SpringBoot4整合Spring Data JPA的实战教程
JPA 是 Java 持久化标准,Spring Data JPA 则让数据库操作变得“几乎不用写 SQL”。本文将系统讲解 JPA 核心概念、实体映射、Repository 用法、方法命名查询和关联关系,帮你快速上手企业级 ORM 开发。
一、什么是 JPA / Spring Data JPA?
JPA 是什么?
JPA(Java Persistence API)是 Java EE 标准,定义了一套 ORM(对象关系映射)规范。
JPA 本身不提供实现,需要具体框架:
- Hibernate(最主流)
- EclipseLink
- OpenJPA
Spring Data JPA 是什么?
Spring Data JPA 是 Spring 对 JPA 的封装,目的是:
- 减少模板代码
- 提供统一的 Repository 抽象
- 通过方法名自动生成查询
一句话:Spring Data JPA = 标准 JPA + Spring 封装 + 自动查询
为什么用 Spring Data JPA?
| 优势 | 说明 |
|---|---|
| 几乎零 SQL | CRUD 不用写一句 SQL |
| 面向对象 | 操作的是 Java 对象,不是表和字段 |
| 数据库无关 | 换数据库只需改配置 |
| 自动分页 / 排序 | 内置支持 |
| 与 Spring 生态无缝整合 | 事务、缓存、审计 |
二、Spring Boot 4 整合 Spring Data JPA
引入依赖
<dependencies>
<!-- JPA Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Druid(可选) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.23</version>
</dependency>
</dependencies>基础配置(application.yml)
spring:
datasource:
url: jdbc:mysql://localhost:3306/jpa_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.MySQLDialectddl-auto 取值说明:
| 值 | 说明 |
|---|---|
create | 每次启动删除表再创建(测试用) |
create-drop | 启动创建,退出删除 |
update | 更新表结构(开发推荐) |
validate | 只校验,不改表结构(生产推荐) |
none | 禁用自动 DDL |
三、实体映射(Entity)
基础实体类
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username", nullable = false, length = 50)
private String username;
@Column(name = "email", length = 100)
private String email;
@Column(name = "age")
private Integer age;
@Column(name = "create_time")
private LocalDateTime createTime;
// 必须有无参构造器
public User() {}
// getter / setter
}核心注解速查
| 注解 | 作用 |
|---|---|
@Entity | 标记为 JPA 实体 |
@Table | 指定表名 |
@Id | 主键 |
@GeneratedValue | 主键生成策略 |
@Column | 字段映射 |
@Transient | 不映射到数据库 |
@Temporal | 日期时间精度(Java 8+ 推荐 java.time) |
主键生成策略
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 private Long id; @Id @GeneratedValue(strategy = GenerationType.UUID) // UUID private String id;
四、Repository:数据访问层(核心)
定义 Repository 接口
public interface UserRepository extends JpaRepository<User, Long> {
}只需继承,无需实现!
JpaRepository 已提供:
save()findById()findAll()deleteById()count()existsById()
基础 CRUD 实战
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User create(User user) {
user.setCreateTime(LocalDateTime.now());
return userRepository.save(user);
}
public User getById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new BusinessException(ResultCode.NOT_FOUND, "用户不存在"));
}
public List<User> listAll() {
return userRepository.findAll();
}
public void delete(Long id) {
userRepository.deleteById(id);
}
}五、方法命名查询(Spring Data JPA 的灵魂)
规则:方法名 = 查询条件
public interface UserRepository extends JpaRepository<User, Long> {
// WHERE username = ?
User findByUsername(String username);
// WHERE email LIKE %?
List<User> findByEmailContaining(String email);
// WHERE age >= ? AND username = ?
List<User> findByAgeGreaterThanEqualAndUsername(int age, String username);
// WHERE create_time BETWEEN ? AND ?
List<User> findByCreateTimeBetween(LocalDateTime start, LocalDateTime end);
// ORDER BY create_time DESC
List<User> findByOrderByCreateTimeDesc();
// 分页 + 排序
Page<User> findByAge(int age, Pageable pageable);
}方法命名关键字对照表
| 关键字 | 示例 | SQL |
|---|---|---|
And | findByUsernameAndAge | WHERE username = ? AND age = ? |
Or | findByUsernameOrEmail | WHERE username = ? OR email = ? |
Between | findByAgeBetween | WHERE age BETWEEN ? AND ? |
LessThan | findByAgeLessThan | WHERE age < ? |
GreaterThan | findByAgeGreaterThan | WHERE age > ? |
Like | findByUsernameLike | WHERE username LIKE ? |
Containing | findByEmailContaining | WHERE email LIKE %?% |
OrderBy | findByOrderByAgeDesc | ORDER BY age DESC |
In | findByIdIn(List<Long> ids) | WHERE id IN (?) |
分页与排序
// 分页
Pageable pageable = PageRequest.of(0, 10, Sort.by("createTime").descending());
Page<User> page = userRepository.findByAge(18, pageable);
// 结果
page.getContent(); // 数据列表
page.getTotalPages(); // 总页数
page.getTotalElements(); // 总记录数
page.getNumber(); // 当前页码六、关联关系映射(入门级)
一对多(@OneToMany)
@Entity
@Table(name = "t_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderNo;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Order> orders = new ArrayList<>();
}关键点:
@ManyToOne默认立即加载,@OneToMany默认懒加载mappedBy指向对方的主表字段cascade控制级联操作
级联操作
| 值 | 说明 |
|---|---|
CascadeType.PERSIST | 保存时级联 |
CascadeType.MERGE | 更新时级联 |
CascadeType.REMOVE | 删除时级联 |
CascadeType.ALL | 所有操作级联 |
七、审计功能(自动填充)
开启审计
@Configuration
@EnableJpaAuditing
public class JpaConfig {
}实体中使用
@Entity
@Table(name = "t_user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@CreatedDate
@Column(name = "create_time")
private LocalDateTime createTime;
@LastModifiedDate
@Column(name = "update_time")
private LocalDateTime updateTime;
@CreatedBy
@Column(name = "created_by")
private String createdBy;
@LastModifiedBy
@Column(name = "updated_by")
private String updatedBy;
}创建时间、更新时间、创建人、更新人自动填充
八、Spring Boot 4 中的新变化
- 对
java.time支持更完善 - Hibernate 6 作为默认实现
- 查询性能优化
- 对虚拟线程(Virtual Threads)支持
九、常见坑位总结
坑1:LazyInitializationException
原因:事务外访问懒加载属性
解决:用 JOIN FETCH 或 @EntityGraph
坑2:N+1 查询问题
解决:使用 @EntityGraph 或 JOIN FETCH
坑3:ddl-auto=update 生产环境误用
解决:生产环境用 validate 或 none
坑4:方法命名查询太复杂
解决:用 @Query 写 JPQL 或原生 SQL
十、本篇总结
- Spring Data JPA = 标准 JPA + Spring 封装
- 实体映射用 @Entity / @Table / @Column
- Repository 继承 JpaRepository 即可获得 CRUD
- 方法命名查询是 JPA 的灵魂
- 关联关系要注意懒加载和 N+1 问题
以上就是SpringBoot4整合Spring Data JPA的实战教程的详细内容,更多关于SpringBoot整合Spring Data JPA的资料请关注脚本之家其它相关文章!
相关文章
解决shiro 定时监听器不生效的问题 onExpiration不调用问题
这篇文章主要介绍了解决shiro 定时监听器不生效的问题 onExpiration不调用问题。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-07-07
Java的Hibernate框架中的双向主键关联与双向外键关联
Hibernate想要实现双向的关联就必须在映射文件的两端同时配置<one-to-one>,另外还要在主映射的一端采用foreign外键关联属性,下面我们就一起来看一下Java的Hibernate框架中的双向主键关联与双向外键关联方法:2016-06-06
JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别
这篇文章主要介绍了JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习下吧2019-07-07


最新评论