SpringBoot4整合Spring Data JPA的实战教程

 更新时间:2026年08月31日 15:33:58   作者:gis开发之家  
JPA 是 Java 持久化标准,本文将系统讲解 JPA 核心概念、实体映射、Repository 用法、方法命名查询和关联关系,帮你快速上手企业级 ORM 开发,希望对大家有所帮助

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?

优势说明
几乎零 SQLCRUD 不用写一句 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.MySQLDialect

ddl-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
AndfindByUsernameAndAgeWHERE username = ? AND age = ?
OrfindByUsernameOrEmailWHERE username = ? OR email = ?
BetweenfindByAgeBetweenWHERE age BETWEEN ? AND ?
LessThanfindByAgeLessThanWHERE age < ?
GreaterThanfindByAgeGreaterThanWHERE age > ?
LikefindByUsernameLikeWHERE username LIKE ?
ContainingfindByEmailContainingWHERE email LIKE %?%
OrderByfindByOrderByAgeDescORDER BY age DESC
InfindByIdIn(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 查询问题

解决:使用 @EntityGraphJOIN FETCH

坑3:ddl-auto=update 生产环境误用

解决:生产环境用 validatenone

坑4:方法命名查询太复杂

解决:用 @Query 写 JPQL 或原生 SQL

十、本篇总结

  1. Spring Data JPA = 标准 JPA + Spring 封装
  2. 实体映射用 @Entity / @Table / @Column
  3. Repository 继承 JpaRepository 即可获得 CRUD
  4. 方法命名查询是 JPA 的灵魂
  5. 关联关系要注意懒加载和 N+1 问题

以上就是SpringBoot4整合Spring Data JPA的实战教程的详细内容,更多关于SpringBoot整合Spring Data JPA的资料请关注脚本之家其它相关文章!

相关文章

  • Java多线程:生产者与消费者案例

    Java多线程:生产者与消费者案例

    这篇文章主要介绍了Java并发编程中的生产者与消费者模型简述,多线程并发是Java编程中最终要的部分之一,需要的朋友可以参考下,希望能给你带来帮助
    2021-07-07
  • Java通过SMS短信平台实现发短信功能 含多语言

    Java通过SMS短信平台实现发短信功能 含多语言

    这篇文章主要为大家详细介绍了Java通过SMS短信平台实现发短信功能的相关资料,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java实现限制文件上传类型功能

    Java实现限制文件上传类型功能

    这篇文章主要为大家详细介绍了在Java中如何实现限制文件上传类型功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-07-07
  • 解决shiro 定时监听器不生效的问题 onExpiration不调用问题

    解决shiro 定时监听器不生效的问题 onExpiration不调用问题

    这篇文章主要介绍了解决shiro 定时监听器不生效的问题 onExpiration不调用问题。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java枚举通过Code获取相应的Value值实现方式

    Java枚举通过Code获取相应的Value值实现方式

    本文介绍了枚举定义、如何通过code获取value的方法,并提供了一个完整的代码示例,通过实际测试,证明了该方法的有效性,希望本文能够为读者提供参考,并鼓励大家支持脚本之家
    2026-03-03
  • java获取到heapdump文件后快速分析技巧

    java获取到heapdump文件后快速分析技巧

    大家都知道HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件,今天通过本文给大家介绍java获取到heapdump文件后,如何快速分析,需要的朋友可以参考下
    2023-04-04
  • Java的Hibernate框架中的双向主键关联与双向外键关联

    Java的Hibernate框架中的双向主键关联与双向外键关联

    Hibernate想要实现双向的关联就必须在映射文件的两端同时配置<one-to-one>,另外还要在主映射的一端采用foreign外键关联属性,下面我们就一起来看一下Java的Hibernate框架中的双向主键关联与双向外键关联方法:
    2016-06-06
  • springboot 启动如何排除某些bean的注入

    springboot 启动如何排除某些bean的注入

    这篇文章主要介绍了springboot 启动如何排除某些bean的注入方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别

    JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别

    这篇文章主要介绍了JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习下吧
    2019-07-07
  • 从Java到Kotlin语法平滑迁移实践指南(含详细代码)

    从Java到Kotlin语法平滑迁移实践指南(含详细代码)

    Kotlin作为一门现代编程语言,凭借其简洁的语法、强大的功能和与Java的无缝互操作性,已成为Android开发的首选语言,这篇文章主要介绍了从Java到Kotlin语法平滑迁移的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-05-05

最新评论