spring data jpa 简化了数据库操作,在国外比较受欢迎,国内用的比较多的是 mybatis-plus。
引入依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
配置
properties
spring.datasource.url=jdbc:mysql://localhost:3306/helloword
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
上面 4 个属性就不多讲了,讲一下下面三个配置属性。
- spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
Hibernate 为不同的数据库类型提供了翻译器,如果你使用的是 mysql 8.x,则声明为 MySQL8Dialect,不写的话可能会导致兼容性问题。
- spring.jpa.hibernate.ddl-auto=update
自动更新表结构,但不会删除表数据。
具体表现如下:
场景 | Hibernate 会做什么 |
---|---|
表不存在 | 自动创建表 |
表存在但字段不匹配 | 自动添加缺失的列 |
字段类型变化 | 尝试修改类型(可能失败,取决于数据库) |
删除实体类里的字段 | 不会删除数据库中的列(安全) |
还有其他取值:
取值 | 作用(启动时 Hibernate 对数据库表结构的处理) | 常用场景 |
---|---|---|
none | 什么都不做,不检查也不修改表结构。 | ✅生产环境默认推荐 |
validate | 只校验实体类字段和表是否匹配,不匹配就抛异常。 | ✅生产/测试,防止意外改表 |
update | 自动更新表结构 | ✅开发/调试 |
create | 先删所有表,再重新创建(数据全丢)。 | ❌单元测试或快速原型 |
create-drop | 启动时 create,应用退出时再全部删表。 | ❌一次性演示/集成测试 |
- spring.jpa.show-sql=true
控制台会打印sql,生产环境建议关闭。
定义表结构
定义如下的对象,当程序启动后,会自动创建 tbl_user 表,不需要自己手动写sql语句。
java
@Data
@Entity
@Table(name = "tbl_user")
public class UserDo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
}
主键策略 GenerationType.IDENTITY 的意思是: 把主键的生成完全交给数据库的自增机制(MySQL 的 AUTO_INCREMENT),JPA/Hibernate 执行 INSERT 时 ,而是等数据库成功插入后,再把数据库生成的主键值 取出来回填到实体对象的 id 字段。
唯一约束 和 非null 约束
可以给字段添加唯一约束 和 非null 约束。
java
@Column(unique = true, nullable = false)
private String name;
注意,如果表和字段已经存在,再重新设置唯一约束和非null约束,是不会生效的,所以最好创建的时候就确定好,生产环境一般会使用 flyway 固化sql
字符长度设置
默认 String 类型的长度是 varchar(255),可以自定义它的长度。
java
@Column(length = 512)
private String email;
实际生产中还是会结合 flyway 手写sql定义表结构,所以定义表结构的很多用法,了解即可。
定义Repository
java
public interface UserRepository extends JpaRepository<UserDo, Long> {
}
JpaRepository 内部已经自带了常用的sql操作,比如根据id查询,查询所有数据;也可以自己添加一些操作,不用手写sql,jpa有一套规则,会自动生成sql。
java
public interface UserRepository extends JpaRepository<UserDo, Long> {
UserDo findByName(String name);
}
规则有如下:
关键字 | 示例方法名 | 生成的 SQL 片段 |
---|---|---|
And | findByNameAndAge | where name = ? and age = ? |
Or | findByNameOrAge | where name = ? or age = ? |
Is / Equals | findByNameIs | where name = ? |
IsNot | findByNameIsNot | where name <> ? |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like 'xxx%' |
EndingWith | findByNameEndingWith | where name like '%xxx' |
Containing | findByNameContaining | where name like '%xxx%' |
LessThan | findByAgeLessThan | where age < ? |
LessThanEqual | findByAgeLessThanEqual | where age <= ? |
GreaterThan/GreaterThanEqual | findByAgeGreaterThan | where age > ? |
Between | findByAgeBetween | where age between ? and ? |
使用 Repository
java
@RestController
@RequestMapping("/api/hello")
@Validated
@RequiredArgsConstructor
public class HelloController {
private final UserRepository userRepository;
@GetMapping
public List<UserDo> hello() {
return userRepository.findAll();
}
}

审计功能
审计就是什么人再什么时间点删除/修改了记录。
spring data jpa 支持 创建时间,修改时间,创建人,修改人 这几个审计字段。
开启审计
再主类上添加注解 @EnableJpaAuditing 即可。
审计父类
实际使用的时候可以将审计字段抽离出来:
java
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String updatedBy;
}
实际使用可以继承这个类:
java
@Entity
@Getter
@Setter
@Table(name = "tbl_user")
public class UserDo extends AuditableEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String passwordHash;
private String email;
}
其中创建者和修改者,需要定义填充规则:
java
@Component
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
// 示例:从 SecurityContext 拿登录人
return Optional.of("system");
}
}
软删除
软删除就是数据库中有个字段专门标记是否被删除,而不是直接删除记录。
首先表中先定义一个字段表示是否删除,比如 is_deleted,然后可以在审计类中,添加下面这行即可:
java
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@SoftDelete(columnName = "is_deleted")
public abstract class AuditableEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String updatedBy;
}
对于 is_deleted 为 true 的字段,正常查询是查不到的,除非自己自定义sql查询。
分页
自带分页功能,直接用就行:
java
@GetMapping
public Page<UserDo> hello() {
Pageable pageable = PageRequest.of(0, 1, Sort.by("id").descending());
Page<UserDo> all1 = userRepository.findAll(pageable);
return all1;
}
page = 0 是第1页,如果想和前端保持统一,数字1才是第1也,则传进后端的page参数减去1再调用api即可。

特殊场景,需要结合其他条件进行分页,只要参数带上 pageable 就好了。
java
public interface UserRepository extends JpaRepository<User, Long> {
// 1) 自带分页
Page<User> findAll(Pageable pageable);
// 2) 带条件的分页
Page<User> findByUsernameContaining(String keyword, Pageable pageable);
}
主类上可以添加 @EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO),否则Controller直接返回Page的实现类会出现告警
多表查询
待补充