|
| 1 | += Spring Data JDBC - Ahead of Time Repository Optimization Example |
| 2 | + |
| 3 | +The project shows the usage of AOT Repositories. |
| 4 | +Ahead of Time Repositories implement query methods through code contribution and allow for debugging queries during runtime. |
| 5 | +Additionally, AOT repositories improve startup time and reduce memory consumption because AOT optimized query methods do not require reflective introspection. |
| 6 | +Each AOT repository is documented with a JSON file that describes the queries implemented by the repository. |
| 7 | + |
| 8 | +== Using AOT Repositories |
| 9 | + |
| 10 | +Repository AOT processing is enabled by default when using Spring Boot's AOT processing (see `pom.xml` for `spring-boot-maven-plugin` usage). |
| 11 | +AOT processing generates AOT artifacts to `target/spring-aot` and through the regular build. |
| 12 | +When using the JVM mode (not Graal Native Images), then you need to enable AOT mode on the JVM when running your application through `-Dspring.aot.enabled=true`. |
| 13 | + |
| 14 | +[source,bash] |
| 15 | +---- |
| 16 | +$ mvn clean package |
| 17 | +$ java -Dspring.aot.enabled=true -jar target/spring-data-jdbc-aot-optimization-4.0.0-SNAPSHOT.jar |
| 18 | +---- |
| 19 | + |
| 20 | +You can find more details about AOT processing in the https://docs.spring.io/spring-data/relational/reference/4.0/jdbc/aot.html[Spring Data JDBC Reference Documentation]. |
| 21 | + |
| 22 | +== AOT Repository |
| 23 | + |
| 24 | +**`CategoryRepositoryImpl__AotRepository`** |
| 25 | + |
| 26 | +Excerpt from: `target/spring-aot/main/sources/example/springdata/aot/CategoryRepositoryImpl__AotRepository.java` |
| 27 | + |
| 28 | +[source,java] |
| 29 | +---- |
| 30 | +@Generated |
| 31 | +public class CategoryRepositoryImpl__AotRepository extends AotRepositoryFragmentSupport { |
| 32 | + public CategoryRepositoryImpl__AotRepository(JdbcAggregateOperations operations, |
| 33 | + RowMapperFactory rowMapperFactory, |
| 34 | + RepositoryFactoryBeanSupport.FragmentCreationContext context) { |
| 35 | + super(operations, rowMapperFactory, context); |
| 36 | + } |
| 37 | +
|
| 38 | + public List<Category> findAllByNameContaining(String name) { |
| 39 | + Criteria criteria = Criteria.where("name").like("%" + escape(name) + "%"); |
| 40 | + StatementFactory.SelectionBuilder builder = getStatementFactory().select(Category.class).filter(criteria); |
| 41 | +
|
| 42 | + RowMapper rowMapper = getRowMapperFactory().create(Category.class); |
| 43 | + List result = (List) builder.executeWith((sql, paramSource) -> getJdbcOperations().query(sql, paramSource, new RowMapperResultSetExtractor<>(rowMapper))); |
| 44 | + return (List<Category>) convertMany(result, Category.class); |
| 45 | + } |
| 46 | +
|
| 47 | + public List<Category> findWithDeclaredQuery(String name) { |
| 48 | + class ExpressionMarker{}; |
| 49 | + String query = "SELECT * FROM category WHERE name = :name"; |
| 50 | + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); |
| 51 | + getBindableValue(ExpressionMarker.class.getEnclosingMethod(), name, 0).bind("name", parameterSource); |
| 52 | +
|
| 53 | + RowMapper rowMapper = getRowMapperFactory().create(Category.class); |
| 54 | + List result = (List) getJdbcOperations().query(query, parameterSource, new RowMapperResultSetExtractor<>(rowMapper)); |
| 55 | + return (List<Category>) convertMany(result, Category.class); |
| 56 | + } |
| 57 | +} |
| 58 | +---- |
| 59 | + |
| 60 | +== Metadata |
| 61 | + |
| 62 | +**`CategoryRepository.json`** |
| 63 | + |
| 64 | +Excerpt from: `target/spring-aot/main/resources/example/springdata/aot/CategoryRepository.json` |
| 65 | + |
| 66 | +[source,json] |
| 67 | +---- |
| 68 | +{ |
| 69 | + "name": "example.springdata.aot.CategoryRepository", |
| 70 | + "module": "JDBC", |
| 71 | + "type": "IMPERATIVE", |
| 72 | + "methods": [ |
| 73 | + { |
| 74 | + "name": "findProjectedByNameContaining", |
| 75 | + "signature": "public abstract java.util.List<example.springdata.aot.CategoryProjection> example.springdata.aot.CategoryRepository.findProjectedByNameContaining(java.lang.String)", |
| 76 | + "query": { |
| 77 | + "query": "SELECT \"CATEGORY\".\"NAME\" AS \"NAME\", \"CATEGORY\".\"DESCRIPTION\" AS \"DESCRIPTION\" FROM \"CATEGORY\" WHERE \"CATEGORY\".\"NAME\" LIKE :name" |
| 78 | + } |
| 79 | + }, |
| 80 | + { |
| 81 | + "name": "findWithDeclaredQuery", |
| 82 | + "signature": "public abstract java.util.List<example.springdata.aot.Category> example.springdata.aot.CategoryRepository.findWithDeclaredQuery(java.lang.String)", |
| 83 | + "query": { |
| 84 | + "query": "SELECT * FROM category WHERE name = :name" |
| 85 | + } |
| 86 | + }, |
| 87 | + { |
| 88 | + "name": "save", |
| 89 | + "signature": "org.springframework.data.jdbc.repository.support.SimpleJdbcRepository", |
| 90 | + "fragment": { |
| 91 | + "interface": "org.springframework.data.jdbc.repository.support.SimpleJdbcRepository", |
| 92 | + "fragment": "org.springframework.data.jdbc.repository.support.SimpleJdbcRepository" |
| 93 | + } |
| 94 | + } |
| 95 | + ] |
| 96 | +} |
| 97 | +---- |
0 commit comments