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的资料请关注代码网其它相关文章!
发表评论