java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot整合Spring Data JPA

SpringBoot4整合Spring Data JPA的实战教程

作者: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 本身不提供实现,需要具体框架:

Spring Data JPA 是什么?

Spring Data JPA 是 Spring 对 JPA 的封装,目的是:

一句话: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 已提供:

基础 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<>();
}

关键点:

级联操作

值说明
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 中的新变化

九、常见坑位总结

坑1:LazyInitializationException

原因:事务外访问懒加载属性

解决:用 JOIN FETCH 或 @EntityGraph

坑2:N+1 查询问题

解决:使用 @EntityGraph 或 JOIN FETCH

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

解决:生产环境用 validate 或 none

坑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的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文