Pour les futurs étudiants du cours "Java Developer. Professional", nous avons préparé une traduction de matériel utile.
Nous vous invitons également à participer à la leçon ouverte sur le thème "Introduction à Spring Data jdbc"
Spring Data JDBC a été annoncé en 2018. L'objectif était de fournir aux développeurs une alternative plus simple à JPA tout en continuant à suivre les principes de Spring Data. Vous pouvez en savoir plus sur les motivations du projet dans la documentation .
Dans cet article, je vais montrer quelques exemples d'utilisation de Spring Data JDBC. Il n'y aura pas de tutoriel détaillé ici, mais j'espère que les informations fournies seront suffisantes pour vous donner un essai vous-même. Très bien si vous connaissez déjà Spring Data JPA. Vous pouvez trouver le code source sur github .
Pour un démarrage rapide, j'ai utilisé ce modèle .
Préparation préliminaire
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());
}
};
}
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 . , . , . - (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"