Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Spring Data’s Guide to Persistence

A Spring Data’s Guide to Persistence

Seconds before coding yet another lookup query, our hero is plucked off his office chair and put into this persistence spaceship where he meets his good friend Spring Data, a library aiming to ease the pain of every day data access, who has been around for more than 10 years.

Together, we’ll begin a journey—aided by a bunch of features like CRUD operations, query derivation, and SQL and NoSQL support—towards developer happiness.

Is this magic? Where is my finder method? When to use named queries? For all the answers, register to this session or stick your thumb up at start.spring.io

Christoph Strobl

September 02, 2021

More Decks by Christoph Strobl

Other Decks in Programming


  1. Safe Harbor Statement The following is intended to outline the

    general direction of VMware's offerings. It is intended for information purposes only and may not be incorporated into any contract. Any information regarding pre-release of VMware offerings, future updates or other planned modifications is subject to ongoing evaluation by VMware and is subject to change. This information is provided without warranty or any kind, express or implied, and is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions regarding VMware's offerings. These purchasing decisions should only be based on features currently available. The development, release, and timing of any features or functionality described for VMware's offerings in this presentation remain at the sole discretion of VMware. VMware has no obligation to update forward looking information in this presentation. 2
  2. 4 SELECT e FROM employee e WHERE e.firstName = :name

    JPA create().select().from(EMPLOYEE) .where(EMPLOYEE.FIRST_NAME).eq(name) .fetch() JOOQ db.employee.find({ first_name : name }) NoSQL SELECT * FROM employee WHERE first_name = %1 SQL everything MATCH (n:Employee) WHERE n.firstName = ’...’ query: { match: { first_name: '...' } }
  3. List<Employee> findByFirstName(String name) Spring Data JPA JDBC Redis Neo4j R2DBC

    MongoDB ArangoDB Couchbase Cosmos DB yugabyteDB Elasticsearch Apache Geode Apache Cassandra ...
  4. 7 A Familiar & Consistent Programming Model That Resprects Store

    Specific Traits no silver bullet no magic not one API to rule them all
  5. Anatomy 9 Entity Manager Database Driver Template API Mapping Conversion

    Resource & Transaction Management native store format <> domain type eg. enum -> string Default Implementation Repository Interface List<Employee> findByFirstName(String name)
  6. Template APIs 10 class MongoTemplate implements MongoOperations { <T> List<T>

    find(Query query, Class<T> entityClass) <T> List<T> findAndRemove(Query query, Class<T> entityClass) <T> T execute(Class<?> entityClass, CollectionCallback<T> callback) query(where(“firstName”).is(...)) template.execute(Employee.class, collection -> { return collection.find(new Document("firstname", "...")) .into(new ArrayList()); }); Access to native driver commands
  7. Repositories 11 interface Repo<Employee, String> extends ...{ Repository CrudRepository findAll();

    findById(...) count(); save(...); delete(...); ... PagingAndSorting Repository findAll(Page); findAll(Sort); Proxy Default Implementation Store Specific List<Employee> findAll(); long count(); Predefined methods List<Employee> findByFirstName(String name); Derived Finder Method
  8. Paging vs Streaming 13 Page<Employee> findByFirstName(String name, Pageable page) Resource

    Allocation Per Invocation Stream<Employee> findByFirstName(String name) Continuous Scrolling
  9. Derived Fetch Queries 14 List<Employee> findEmployeeByFirstNameLikeOrderByAgeAsc(String name) read get query

    search stream Placeholder For Anything You Like matches contains lessThan startsWith greaterThan isEmpty isNull isNotNull before after ... Match Operator Sort Direction Delimiter Employee Page<Employee> Slice<Employee> Stream<Employee>
  10. Derived Delete Queries 16 @Modifying List<Employee> deleteEmployeeByFirstNameLike(String name) remove Some

    Stores Need a Little Help void long Interested in the Operation Result?
  11. 17 I‘d far rather be happy than right any day.

    IDE Support Runtime Support Douglas Adams, The Hitchhiker's Guide to the Galaxy
  12. Data Projections 18 List<View> findByFirstName(String name) Closed Interface Projection interface

    View2 { String getFirstName(); String getLastName(); } class View1 { String firstName; String lastName; } DTO Projection interface View3 { @Value(“#{target....}”) String getName(); } Open Interface Projection Flexible View On Your Data
  13. Query By Example 19 List<Employee> findAll(Example<Employee> probe) a Good Fit

    for Web Form Search Binding Page Stream long count Pageable Sort
  14. Auditing 2 0 class Employee { String firstName; String lastName;

    @CreatedDate Instant created; @LastModifiedDate Instant lastModified; }
  15. Reactive 21 Flux<Employee> findByFirstName(String name) a Reactive Stream of Data

    For a moment, nothing happened. Then, after a second or so, nothing continued to happen. once you forget to subscribe to the stream Douglas Adams, The Hitchhiker's Guide to the Galaxy
  16. 23 class Employee { Long id; String firstName; String lastName;

    Manager manager; } class Manager { Long id; String name; List<Employee> employees } ID Name 1000 Marvin ID FIRST_N LAST_N MANAGER_ID 1 Ford Perfect 1000 table based manager employee linking by default { _id : 1000, name : Marvin, employees : [ { id : 1, firstName : Ford, lastName : Perfect } ... document store embedding by default
  17. 2 4 Would it save you a lot of time

    if I just gave up and went mad now? Actually, it’s not that bad once you got the differences. Decide on what you need. Not what you got or think to be cool. Douglas Adams, The Hitchhiker's Guide to the Galaxy
  18. 25 @Entity class Employee { @Id @GeneratedValue(...) Long id; @Column(name="FIRST_N")

    String firstName; ... } @Document class Employee { @Id Long id; @Field(name=”first_n") String firstName; ... } JPA MongoDB
  19. 26 @Document class Manager { Long id; String name; @DBRef

    List<Employee> employees } { _id : 1000, name : Marvin, employees : [ { $ref : employee, $id : 1 } ... native $dbref format MongoDB – Linking manager { _id : 1, ..., manager : 1000 } @Document class Employee { Long id; //... @DocumentReference Manager manager; } more common simple format employee
  20. 27 @Entity class Employee { Long id; //... @Embedded @AttributeOverrides({...})

    Manager manager; } JPA – Embedding ID FIRST_N LAST_N MANAGER_ID MANAGER_NAME 1 Ford Perfect 1000 Marvin
  21. Richer / Slimmer API 2 9 Read the Documentation for

    store specific features @Procedure(”Employee.increaseSalary”) Integer increaseSalary(Integer raise); JPA Stored Procedure call GeoResults<Employee> findByOfficeLoactionNear(Point p, Distance max) List Stream MongoDB Geospatial Query
  22. Native Queries 3 0 @Query(“SELECT m, COUNT(e) FROM Manager m

    JOIN m.employees e GROUP BY e.name”) List<View> listManagerWithEmployeeCount(); JPA @Aggregation(“{ $project: { id : 1, name: 1, $size : employees } }”) List<View> listManagerWithEmployeeCount(); MongoDB
  23. Repositories 3 2 interface Repo<Employee, String> extends ...{ CrudRepository Repository

    PagingAndSorting Repository List<Employee> findAll(); long count(); findAll(); findById(...) count(); save(...); delete(...); ... findAll(Page); findAll(Sort); Default Implementation Proxy Store Specific
  24. Repository Fragments 3 3 interface Repo<Employee, String> extends ...{ List<Employee>

    findAll(); long count(); Default Implementation Proxy Repository CrudRepository PagingAndSorting Repository Fragment I Fragment II Fragment III Fragment Impl Custom Method Declaration invocation target
  25. Time is an illusion. Lunchtime doubly so. 3 4 Bad

    Performance? Slow Queries? Keep calm and log Douglas Adams, The Hitchhiker's Guide to the Galaxy
  26. #springone @SpringOne So long, and thanks for all the fish.

    Douglas Adams, The Hitchhiker's Guide to the Galaxy Noooo - Wait, there’s more...! Mapping Conversion Auditing Event Listeners Entity Callbacks Transactions Live Coding Spring Data Queries to the End of the Persistence Universe