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
Tweet

More Decks by Christoph Strobl

Other Decks in Programming

Transcript

  1. A Spring Data’s Guide
    to Persistence
    September 1–2, 2021
    springone.io
    1

    View full-size slide

  2. 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

    View full-size slide

  3. DON‘T
    PANIC
    Douglas Adams, The Hitchhiker's Guide to the Galaxy

    View full-size slide

  4. 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: '...' } }

    View full-size slide

  5. List findByFirstName(String name)
    Spring
    Data
    JPA
    JDBC
    Redis
    Neo4j
    R2DBC
    MongoDB
    ArangoDB
    Couchbase
    Cosmos DB
    yugabyteDB
    Elasticsearch
    Apache Geode
    Apache Cassandra
    ...

    View full-size slide

  6. 42
    life – data - everything

    View full-size slide

  7. 7
    A
    Familiar & Consistent
    Programming Model
    That Resprects
    Store Specific Traits
    no silver bullet no magic not one API to rule them all

    View full-size slide

  8. 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 findByFirstName(String name)

    View full-size slide

  9. Template APIs
    10
    class MongoTemplate implements MongoOperations {
    List find(Query query, Class entityClass)
    List findAndRemove(Query query, Class entityClass)
    T execute(Class> entityClass, CollectionCallback callback)
    query(where(“firstName”).is(...))
    template.execute(Employee.class, collection -> {
    return collection.find(new Document("firstname", "..."))
    .into(new ArrayList());
    });
    Access to native
    driver commands

    View full-size slide

  10. Repositories
    11
    interface Repo extends ...{ Repository
    CrudRepository
    findAll();
    findById(...)
    count();
    save(...);
    delete(...);
    ...
    PagingAndSorting
    Repository
    findAll(Page);
    findAll(Sort);
    Proxy
    Default Implementation
    Store Specific
    List findAll();
    long count();
    Predefined methods
    List findByFirstName(String name);
    Derived Finder Method

    View full-size slide

  11. Derived Queries
    12
    List findByFirstName(String name)
    Return Type
    Operation Keyword
    Match Against
    Bind Argument

    View full-size slide

  12. Paging vs Streaming
    13
    Page findByFirstName(String name, Pageable page)
    Resource Allocation Per Invocation
    Stream findByFirstName(String name)
    Continuous Scrolling

    View full-size slide

  13. Derived Fetch Queries
    14
    List 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
    Slice
    Stream

    View full-size slide

  14. Derived Count | Exists Queries
    15
    int countEmployeeByFirstNameLike(String name)
    boolean existsEmployeeByFirstNameLike(String name)

    View full-size slide

  15. Derived Delete Queries
    16
    @Modifying
    List deleteEmployeeByFirstNameLike(String name)
    remove
    Some Stores Need a Little Help
    void
    long
    Interested in the
    Operation Result?

    View full-size slide

  16. 17
    I‘d far rather be happy
    than right any day.
    IDE Support Runtime Support
    Douglas Adams, The Hitchhiker's Guide to the Galaxy

    View full-size slide

  17. Data Projections
    18
    List 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

    View full-size slide

  18. Query By Example
    19
    List findAll(Example probe)
    a Good Fit for Web Form Search Binding
    Page
    Stream
    long
    count Pageable
    Sort

    View full-size slide

  19. Auditing
    2
    0
    class Employee {
    String firstName;
    String lastName;
    @CreatedDate
    Instant created;
    @LastModifiedDate
    Instant lastModified;
    }

    View full-size slide

  20. Reactive
    21
    Flux 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

    View full-size slide

  21. Storage
    Engine
    Store Specific

    View full-size slide

  22. 23
    class Employee {
    Long id;
    String firstName;
    String lastName;
    Manager manager;
    }
    class Manager {
    Long id;
    String name;
    List 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

    View full-size slide

  23. 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

    View full-size slide

  24. 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

    View full-size slide

  25. 26
    @Document
    class Manager {
    Long id;
    String name;
    @DBRef
    List 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

    View full-size slide

  26. 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

    View full-size slide

  27. Query
    Language
    Store Specific

    View full-size slide

  28. Richer / Slimmer API
    2
    9
    Read the Documentation
    for store specific features
    @Procedure(”Employee.increaseSalary”)
    Integer increaseSalary(Integer raise);
    JPA
    Stored Procedure call
    GeoResults findByOfficeLoactionNear(Point p, Distance max)
    List
    Stream
    MongoDB
    Geospatial Query

    View full-size slide

  29. Native Queries
    3
    0
    @Query(“SELECT m, COUNT(e) FROM Manager m
    JOIN m.employees e GROUP BY e.name”)
    List listManagerWithEmployeeCount();
    JPA
    @Aggregation(“{ $project: { id : 1, name: 1, $size : employees } }”)
    List listManagerWithEmployeeCount();
    MongoDB

    View full-size slide

  30. Custom
    Implementations
    Store Specific

    View full-size slide

  31. Repositories
    3
    2
    interface Repo extends ...{
    CrudRepository
    Repository
    PagingAndSorting
    Repository
    List findAll();
    long count();
    findAll();
    findById(...)
    count();
    save(...);
    delete(...);
    ...
    findAll(Page);
    findAll(Sort);
    Default Implementation
    Proxy
    Store Specific

    View full-size slide

  32. Repository Fragments
    3
    3
    interface Repo extends ...{
    List findAll();
    long count();
    Default Implementation
    Proxy
    Repository
    CrudRepository
    PagingAndSorting
    Repository
    Fragment I
    Fragment II
    Fragment III
    Fragment Impl
    Custom Method Declaration
    invocation
    target

    View full-size slide

  33. 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

    View full-size slide

  34. Trouble Shooting
    3
    5
    Repository Metrics
    Logfiles
    Network Stats
    Query Planners

    View full-size slide

  35. Guides & Samples
    3
    6
    spring.io/guides spring-projects/spring-data-examples

    View full-size slide

  36. #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

    View full-size slide