Introdução ao Spring Data JDBC Baeldung

Para os futuros alunos do curso "Java Developer. Professional" preparamos uma tradução de material útil.



Também o convidamos a participar da aula aberta sobre o tópico
"Introdução ao Spring Data jdbc"










Spring Data JDBC foi anunciado em 2018. O objetivo era fornecer aos desenvolvedores uma alternativa mais simples para JPA enquanto continuava a seguir os princípios do Spring Data. Você pode aprender mais sobre os motivos por trás do projeto na documentação





Neste artigo, mostrarei alguns exemplos de uso do Spring Data JDBC. Não haverá um tutorial detalhado aqui, mas esperamos que as informações fornecidas sejam suficientes para você mesmo experimentar. Muito bom se você já estiver familiarizado com Spring Data JPA. Você pode encontrar o código-fonte no github .





Para um início rápido, usei este modelo .





Preparação preliminar

data-jdbc



— , flyway



postgres



.





// build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'

    implementation 'org.flywaydb:flyway-core'

    runtimeOnly 'org.postgresql:postgresql'
}
      
      



:





# application.yml
spring:
  application:
    name: template-app
  datasource:
    url: jdbc:postgresql://localhost:5432/demo_app?currentSchema=app
    username: app_user
    password: change_me
    driver-class-name: org.postgresql.Driver
      
      



:





create table book (
    id varchar(32) not null,
    title varchar(255) not null,
    author varchar(255),
    isbn varchar(15),
    published_date date,
    page_count integer,
    primary key (id)
);
      
      



java- ( , @Id



org.springframework.data.annotation.Id



):





// Book.java
public class Book {
    @Id
    private String id;
    private String title;
    private String author;
    private String isbn;
    private Instant publishedDate;
    private Integer pageCount;
}
      
      



, :





// BookRepositoryTest.java
@Test
void canSaveBook() {
    var book = Book.builder().author("Steven Erikson").title("Gardens of the Moon").build();
    var savedBook = bookRepository.save(book);

    assertThat(savedBook.getId()).isNotBlank();
    assertThat(savedBook.getAuthor()).isEqualTo(book.getAuthor());
    assertThat(savedBook.getTitle()).isEqualTo(book.getTitle());

    assertThat(savedBook).isEqualTo(bookRepository.findById(savedBook.getId()).get());
}
      
      



— ERROR: null value in column "id" violates not-null constraint. , id . Spring Data JDBC Spring Data JPA. ApplicationListener



BeforeSaveEvent



:





// PersistenceConfig.java
@Bean
public ApplicationListener<BeforeSaveEvent> idGenerator() {
    return event -> {
        var entity = event.getEntity();
        if (entity instanceof Book) {
            ((Book) entity).setId(UUID.randomUUID().toString());
        }
    };
}
      
      



, Id . .





 

Spring Data . Spring Data JDBC . BookRepository



:





Optional<Book> findByTitle(String title);
      
      



:





@Test
void canFindBookByTitle() {
    var title = "Gardens of the Moon";
    var book = Book.builder().author("Steven Erikson").title(title).build();
    var savedBook = bookRepository.save(book);
    assertThat(bookRepository.findByTitle(title).get()).isEqualTo(savedBook);
}
      
      



Caused by: java.lang.IllegalStateException: No query specified on findByTitle



. Spring Data JDBC , @Query. sql- :





@Query("select * from Book b where b.title = :title")
Optional<Book> findByTitle(@Param("title") String title);
      
      



! .





: Spring Data JDBC 2.0





Spring Data JDBC . , . , . - (Domain Driven Design), , , , , .





--

"--" "--" @MappedCollection



. "--".  UserAccount



Address



. sql:





create table address
(
    id      varchar(36) not null,
    city    varchar(255),
    state   varchar(255),
    street  varchar(255),
    zipcode varchar(255),
    primary key (id)
);

create table user_account
(
    id         varchar(36)  not null,
    name       varchar(255) not null,
    email      varchar(255) not null,
    address_id varchar(36),
    primary key (id),
    constraint fk_user_account_address_id foreign key (address_id) references address (id)
);
      
      



UserAccount



:





// UserAccount.java
public class UserAccount implements GeneratedId {
    // ...other fields
    @MappedCollection(idColumn = "id")
    private Address address;
}
      
      



, address



. idColumn



Address



. , Address



UserAccount



, UserAccount



. :





//UserAccountRepositoryTest.java
@Test
void canSaveUserWithAddress() {
    var address = stubAddress();
    var newUser = stubUser(address);

    var savedUser = userAccountRepository.save(newUser);

    assertThat(savedUser.getId()).isNotBlank();
    assertThat(savedUser.getAddress().getId()).isNotBlank();

    var foundUser = userAccountRepository.findById(savedUser.getId()).orElseThrow(IllegalStateException::new);
    var foundAddress = addressRepository.findById(foundUser.getAddress().getId()).orElseThrow(IllegalStateException::new);

    assertThat(foundUser).isEqualTo(savedUser);
    assertThat(foundAddress).isEqualTo(savedUser.getAddress());
}
      
      



--

sql, "--":





create table warehouse
(
    id       varchar(36) not null,
    location varchar(255),
    primary key (id)
);

create table inventory_item
(
    id        varchar(36) not null,
    name      varchar(255),
    count     integer,
    warehouse varchar(36),
    primary key (id),
    constraint fk_inventory_item_warehouse_id foreign key (warehouse) references warehouse (id)
);
      
      



(warehouse) / (inventoryitems). Warehouse



@MappedCollection



InventoryItem



:





public class Warehouse {
    // ...other fields
    @MappedCollection
    Set<InventoryItem> inventoryItems = new HashSet<>();

    public void addInventoryItem(InventoryItem inventoryItem) {
        var itemWithId = inventoryItem.toBuilder().id(UUID.randomUUID().toString()).build();
        this.inventoryItems.add(itemWithId);
    }
}

public class InventoryItem {
    @Id
    private String id;
    private String name;
    private int count;
}
      
      



id



addInventoryItem



. ApplicationListener



Warehouse



BeforeSaveEvent



, id



InventoryItem



. , . "--". , Warehouse



InventoryItem



.





InventoryItem



Warehouse



. , , . JPA , , . Spring Data JDBC , "--" .





-- --

"--" " ". "--" . . Spring Data JDBC Id



. , . 





Spring Data JPA, , , . , Spring Data JDBC , . , , "" (dirty tracking) (session). Spring Data JDBC , ( ) , . , , JPA, , Spring Data JPA Spring Data JDBC.





Spring Data JDBC. , , . , dirty tracking, . , , .





, ! , Spring Data JDBC.






"Java Developer. Professional"







" Spring Data jdbc"












All Articles