数据访问(二):Spring Data JPA

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

该 starter 聚合 Spring Data JPA 与默认实现 Hibernate,并自带事务支持;再加数据库驱动即可(同 14 章)。实体注解使用 jakarta.persistence.* 包。

实体

import jakarta.persistence.*;

@Entity
@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private Integer age;

    // 无参构造、getter/setter 省略
}

要点:需要无参构造;@GeneratedValue(strategy = IDENTITY) 表示自增主键;字段名与列名的映射规则(含下划线命名)以官方文档为准。

Repository:接口即实现

public interface UserRepository extends JpaRepository<User, Long> {
    // 方法名派生查询
    List<User> findByName(String name);
    boolean existsByAge(Integer age);
    long countByName(String name);
    List<User> findByAgeGreaterThanEqualOrderByIdDesc(int age);
}

Spring Data 在启动时为接口生成代理实现,无需写实现类。规则是「动词 + By + 条件属性」,支持 And/Or/GreaterThan/Containing/OrderBy 等连接词;方法名中属性拼写错误会在启动阶段报错。

JpaRepository 自带常用方法:savefindById(返回 Optional)、findAlldeleteByIdexistsByIdcount

分页与排序

Page<User> page = repo.findByAge(18, PageRequest.of(0, 10, Sort.by("id").descending()));
List<User> content = page.getContent();
long total = page.getTotalElements();

分页查询返回 Page<T>,内含数据与总数等信息;PageRequest.of(页码, 每页条数, Sort) 构造分页条件(页码从 0 开始)。

@Query 自定义查询

方法名搞不定时用 @Query 写 JPQL(面向实体):

public interface UserRepository extends JpaRepository<User, Long> {

    @Query("select u from User u where u.name like concat('%', :kw, '%')")
    List<User> search(@Param("kw") String kw);

    @Query(value = "select * from t_user where age > :minAge", nativeQuery = true)
    List<User> findByAgeGreaterThan(@Param("minAge") int minAge);
}
  • nativeQuery = true 表示原生 SQL;
  • 更新/删除类语句还要加 @Modifying,并让调用在事务中执行:
@Modifying
@Query("update User u set u.age = u.age + 1 where u.id = :id")
int increaseAge(@Param("id") Long id);

常用配置

spring.jpa.hibernate.ddl-auto=update   # none / validate / update / create
spring.jpa.show-sql=true               # 开发期打印 SQL

ddl-auto 由 Hibernate 按实体自动维护表结构:开发期常用 update,生产建议 validatenone(由 DBA 管理表结构)。完整属性清单以官方文档为准。

小结

Spring Data JPA 的核心是「实体 + Repository 接口」:简单 CRUD 零实现代码,复杂查询用方法名派生或 @Query。相比 14 章的 JdbcTemplate 它更「对象化」,代价是 SQL 由框架生成、复杂查询调优需要额外手段——这正是 16 章 MyBatis 的用武之地。

笔记加载中…