2.4 定义聚合
2.4.1 定义实体
我们使用javax.persistence.Entity注解来定实体类:
@Entity
public class Person {}
一个实体类会映射数据库的一张表,我们启用了spring.jpa.hibernate.ddl-auto: update,Spring Data会自动为我们建一个首字母小写的表person。
我们可以通过@Table(name = "tb_person")来定制的表名。
2.4.2 定义Id
我们使用javax.persistence.Id注解来定义唯一标识,它会和数据库的主键映射;使用javax.persistence.GeneratedValue注解来指定唯一标识的产生策略。
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
}
@GeneratedValue默认使用自动选择唯一标识产生策略,在MySQL下自动使用Hibernate为我们生成的hibernate_sequence表。我们可以使用@GeneratedValue的generator属性配合@SequenceGenerator或@TableGenerator来指定id生成器。
2.4.3 定义值
我们使用javax.persistence.Column来定义一个属性值,它会和数据库的字段映射;当我们不使用它的时候,实体的值会自动映射为表的字段。命名规则是将驼峰式的属性名转换成下划线的字段名(如lastName映射成last_name)。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(name = "name", length = 10)
private String name;
private Integer age;
private Boolean active = true;
}
}
2.4.4 定义单个值对象
值对象要通过javax.persistence.Embeddable注解表明它是实体的一部分。在实体上用javax.persistence.Embedded来组合。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public class Address {
private String city;
private String province;
}
Address的属性会映射到Person表里的字段。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@Column
private String name;
private Integer age;
@Embedded
private Address address;
}
2.4.5 定义列表值对象
同样列表形式的值对象也通过javax.persistence.Embeddable注解表明它是实体的一部分。在实体上通过javax.persistence.ElementCollection来组合。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public class Child {
private String name;
@Enumerated(EnumType.STRING)
private Gender gender;
}
对于多个固定值选择的属性建议使用枚举型来表示:
public enum Gender {
MALE,
FEMALE
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@Column
private String name;
private Integer age;
@Embedded
private Address address;
@ElementCollection(fetch = FetchType.EAGER)
private Collection<Child> children;
}
会生成一个person_children表,字段有:person_id、gender、name。
2.4.6 属性校验
实体的值的校验也支持JSR-303/349/380,我们可以用注解来校验,如 : @NotNull、@Size等
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue
@NotNull //id不能为空
private Long id;
@NotNull
@Size(min = 3, max = 10)
@Column(name = "name", length = 10)
private String name;
private Integer age;
@Embedded
private Address address;
@ElementCollection
private Collection<Child> children;
}
2.5 定义聚合Repository
定义聚合Repository,我们只需要确定三个问题:
- 当前数据访问技术:
JpaRepository - 聚合根实体的类型:
Person - 实体的唯一标识的类型:
Long
public interface PersonRepository extends JpaRepository<Person, Long> {
}
JpaRepository代理实现为SimpleJpaRepository,Spring Data JPA会将PersonRepository注册成一个Bean,我们只需要注入此Bean即可进行数据库操作。
2.5.1 保存
我们直接使用继承自CrudRepository的save*方法即可保存。
保存单个实体:
@SpringBootApplication
@Slf4j
public class LearningSpringDataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(LearningSpringDataJpaApplication.class, args);
}
@Bean
CommandLineRunner saveOne(PersonRepository personRepository){
return args -> {
Address address = new Address("hefei", "Anhui");
Collection<Child> children = Arrays.asList(new Child("wyn", Gender.FEMALE), new Child("wbe", Gender.MALE));
Person person = new Person("wyf", 35, address, children);
Person savedPerson = personRepository.save(person);
log.info(person.toString());
};
}
}
保存多个实体:
@Bean
CommandLineRunner saveAll(PersonRepository personRepository){
return args -> {
Address address1 = new Address("beijing", "Beijing");
Address address2 = new Address("shanghai", "Shanghai");
Collection<Child> children1 = Arrays.asList(new Child("aaa", Gender.FEMALE), new Child("bbb", Gender.MALE));
Collection<Child> children2 = Arrays.asList(new Child("ccc", Gender.FEMALE), new Child("ddd", Gender.MALE));
Person person1 = new Person("foo", 36, address1, children1);
Person person2 = new Person("bar", 34, address2, children1);
List<Person> savedPeople = personRepository.saveAll(Arrays.asList(person1, person2));
savedPeople.forEach(p ->{
log.info(p.toString());
});
};
}

2.5.2 删除
使用继承自CrudRepository的delete*方法来删除数据:
@Bean
CommandLineRunner delete(PersonRepository personRepository){
return args -> {
personRepository.deleteById(1l); //根据id删除
log.info("-----剩余数量为" + personRepository.count() + "------");
personRepository.delete(personRepository.getOne(2l)); //根据实体删除
log.info("-----剩余数量为" + personRepository.count() + "------");
personRepository.deleteAll(); // 删除所有
log.info("-----剩余数量为" + personRepository.count() + "------");
};
}

新书推荐:
我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
主要包含目录有:
第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)

本文介绍了如何在Spring Boot 2.x中使用Spring Data JPA进行领域驱动设计(DDD),详细讲解了如何定义聚合,包括实体、ID、值对象、列表值对象以及属性校验。同时,阐述了如何定义聚合Repository,实现保存和删除操作。此外,还提及了一本涵盖Spring Boot开发相关知识的新书。
&spm=1001.2101.3001.5002&articleId=106327228&d=1&t=3&u=500fd113c43e4e429aaf3411711152e5)
911

被折叠的 条评论
为什么被折叠?



