🎉🎉《Spring Boot实战案例合集》目前已更新111个案例,我们将持续不断的更新。文末有电子书目录。
💪💪永久更新承诺
我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务。
💌💌如何获取
订阅我们的合集《点我订阅》,并通过私信联系我们,我们将第一时间将电子书发送给您。
环境:SpringBoot3.4.2
1. 简介
2.1 实体类与继承
使用@Entity注解来标记您的实体类,以表明它们是JPA实体
如果表名与类名不同,请使用@Table注解来指定表名
对于应由多个实体继承的公共属性,可以考虑使用@MappedSuperclass
实体类基类设计
public abstract class BaseEntity implements Serializable {private Long id;// 其它公共属性private Date createTime ;//getters, setters}
BaseEntity类被注解为@MappedSuperclass。它包含了你希望在多个实体类之间共享的公共字段。Employee类继承自BaseEntity,也就从超类继承了id, createTime字段。通过基类的设计实现了代码的复用性,并保持了实体层次的清晰和结构化。
具体实体类
(name = "t_employees")public class Employee extends BaseEntity {private String name ;private String address ;// getters, setters}
主键说明
主键字段使用@Id注解
主键生成策略使用@GeneratedValue注解(该注解有多种生成策略,如:GenerationType.IDENTITY、GenerationType.SEQUENCE等)
关联关系
使用@OneToOne、@OneToMany、@ManyToOne和@ManyToMany来定义实体之间的关系
使用fetch属性来控制加载行为(例如,LAZY(延迟加载)或EAGER(急切加载))
利用mappedBy来定义双向关联中的拥有方
public class Department extends BaseEntity {private String name;private String code ;private List<Employee> employees = new ArrayList<>() ;// getters, setters}public class Employee extends BaseEntity {// ...private Department department;// getters, setters}
级联操作
使用cascade属性来指定级联操作(例如,CascadeType.ALL、CascadeType.PERSIST)
在使用级联删除(CascadeType.DELETE)时要特别小心,以避免意外丢失数据
public class Department extends BaseEntity {// ...(mappedBy = "department",cascade = {CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.REMOVE},orphanRemoval = true)private List<Employee> employees = new ArrayList<>() ;}
说明:
如果你将级联操作设置为CascadeType.ALL,所有操作(例如,持久化、合并、删除)都应该从父实体(Department)级联到子实体(Employee)
orphanRemoval = true:此选项指定当从Department集合中移除对某个Employee实体的引用时,这个孤立的Employee实体也应该从数据库中删除
如下示例,保存Department时会级联保存所有的Employee。
private DepartmentRepository departmentRepository ;public void testSave() {Department department = new Department() ;department.setCode("S0001") ;department.setName("研发部") ;Employee e1 = new Employee("张三", "SC") ;e1.setDepartment(department) ;Employee e2 = new Employee("Pack", "XJ") ;e2.setDepartment(department) ;department.setEmployees(List.of(e1, e2)) ;this.departmentRepository.saveAndFlush(department) ;}
控制台输出
同样也适用于其它的级联操作。
2.2 有效性验证
使用验证注解(如@NotNull、@Size等)直接在实体类中强制实施数据完整性约束。
将JPA验证与Spring的@Valid注解结合使用,以自动验证传入的数据。
public class Department extends BaseEntity {private String name;private String code ;}
当我们执行如下代码时程序将抛出异常
public void testSave() {Department department = new Department() ;department.setCode("S0001") ;// 没有设置name属性this.departmentRepository.saveAndFlush(department) ;}
注意,你需要开启如下配置:
spring:jpa:properties:hibernate:'[javax.persistence.validation.mode]': auto
2.3 审计
通过添加如@CreatedBy、@CreatedDate、@LastModifiedBy和@LastModifiedDate等字段来实现实体审计,以跟踪是哪个用户何时创建或修改了实体
利用Spring的@EntityListeners来管理审计行为
如下比较完善的一个实体基类
public abstract class AuditableEntity implements Serializable {private static final long serialVersionUID = 1L;private Long id ;private Date createTime = new Date() ;protected String createdBy;protected LocalDateTime createdDate;protected String lastModifiedBy;protected LocalDateTime lastModifiedDate;}
如上我们又定义了一个可以审计的实体基类;如果哪个实体需要被审计那么就继承该类即可。
public class Product extends AuditableEntity {private String name;private Double price;// getters, setters}
注意,要使得审计功能生效,我们还需要做如下配置:
开启审计功能
@Configuration@EnableJpaAuditingpublic class JpaConfig {}
当前审计人Bean
我们需要提供一个你当前操作的人是谁的bean
public class SystemAuditorAware implements AuditorAware<String> {public Optional<String> getCurrentAuditor() {return Optional.of("Pack") ;}}
这里你需要根据自己的实际情况来编写。
2.4 DTO映射
当查询数据时,考虑使用DTO投影来仅查询需要的字段,从而提高性能
使用Spring Data JPA的@Query注解或查询方法来创建自定义投影
如下实体类
(name = "t_author")public class Author extends BaseEntity {private String name ;private Integer age ;private String address ;private String sex ;private String email ;}
该实体字段表多,我们可能只需要部分字段,如:name,sex,那么我们可以定义如下的投影:
public interface AuthorProjection {String getName();String getSex();}
使用@Query查询
public interface AuthorRepository extends JpaRepository<Author, Long> {@Query("select e.name as name, e.sex as sex from Author e")List<AuthorProjection> queryAuthors() ;}
注意,你需要在sql中使用 as 别名。
2.5 索引
在实体类上我们可以通过@Table注解的indexes属性指定列来创建索引。
@Index(columnList = "name, sex")})public class Author extends BaseEntity {}
当服务启动时,会自动创建基于 "name", "sex" 2个字段的联合索引。
索引对于提高查询性能至关重要,尤其是在处理大型数据集时。根据你应用程序的查询模式,仔细选择哪些列要创建索引是非常关键的。
推荐文章
优雅!基于Spring Boot字段加密后的模糊查询,支持MyBatis, JPA
高级版@ResponseBody,接口响应数据格式完全自定义
优雅重构Spring Boot代码,我用这6种策略消灭if else
性能排名第一的模板引擎 JTE 在 Spring Boot 中的应用


