学习笔记085——Spring Data JPA笔记

发布于:2025-06-05 ⋅ 阅读:(21) ⋅ 点赞:(0)

1、什么是Spring Data JPA?

Spring Data JPA 是 Spring 框架的一个子项目,它简化了基于 JPA (Java Persistence API) 的数据访问层的实现。它通过减少样板代码和提供默认实现,让开发者能够更快速地构建数据访问层。

1.1、主要特点

  1. 减少样板代码:自动生成常见的 CRUD 操作实现
  2. 方法名查询:通过方法命名约定自动生成查询
  3. 自定义查询:支持 JPQL 和原生 SQL 查询
  4. 分页和排序:内置支持分页和排序功能
  5. 审计支持:自动记录创建时间、修改时间等
  6. 与 Spring 生态集成:无缝集成 Spring 事务管理等

1.2、核心接口

  • Repository:标记接口,顶级接口
  • CrudRepository:提供基本的 CRUD 操作
  • PagingAndSortingRepository:扩展 CrudRepository,添加分页和排序功能
  • JpaRepository:JPA 特定扩展,提供 flush、批量删除等功能

2、常用的注解

2.1、实体类相关注解

@Entity

  • 作用:将一个类声明为JPA实体,对应数据库中的表。

  • 属性:指定实体名称,默认为类名

@Table

  • 作用:指定实体对应的数据库表信息。
  • 属性
    • name:表名(默认与实体类名相同)
    • schema:数据库schema
    • catalog:数据库catalog
    • uniqueConstraints:唯一约束

@Id

  • 作用:该注解表明该属性字段是一个主键,该属性必须具备,不可缺少。

@GeneratedValue

  • 作用:指定主键生成策略。

  • 属性

    • strategy:生成策略(GenerationType.AUTO/IDENTITY/SEQUENCE/TABLE)

      1、GenerationType.IDENTITY 该注解由数据库自动生成,主键自增型,在 mysql 数据库中使用最频繁,oracle 不支持。

      2、GenerationType.AUTO 主键由程序控制,默认的主键生成策略,oracle 默认是序列化的方式,mysql 默认是主键自增的方式。

      3、GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列,Oracle支持,Mysql不支持。

      4、GenerationType.TABLE 使用一个特定的数据库表格来保存主键,较少使用。

    • generator:生成器名称

@Column

  • 作用:定义字段与列的映射关系。
  • 属性
    • name:列名
    • nullable:是否允许为null
    • unique:是否唯一
    • length:长度(String类型)
    • precision:精度(BigDecimal)
    • scale:小数位数
    • columnDefinition:列定义SQL片段

@Transient

  • 作用:标记字段不持久化到数据库

  • 示例

    @Transient
    private String tempValue;
    

@Enumerated

  • 作用:定义枚举类型的存储方式

  • 属性

    • value:EnumType.ORDINAL(存储序号)或STRING(存储名称)
  • 示例

    @Enumerated(EnumType.STRING)
    private UserStatus status;
    

@CreatedDate

  • 作用:自动记录创建时间(每次insert的时候,会添加时间进去)

  • 示例

    @CreatedDate
    @Column(name = "create_time")
    private LocalDateTime createTime;
    

@LastModifiedDate

  • 作用:自动记录最后修改时间(每次update的时候,会添加时间进去)

  • 示例

    @LastModifiedDate
    @Column(name = "update_time")
    private LocalDateTime updateTime;
    

@CreatedBy

  • 作用:自动记录创建人

  • 示例

    @CreatedBy
    @Column(name = "created_by")
    private String createdBy;
    

@LastModifiedBy

  • 作用:自动记录最后修改人

  • 示例

    @LastModifiedBy
    @Column(name = "modified_by")
    private String modifiedBy;
    

2.2、关联关系注解

@OneToOne

  • 作用:定义一对一关系
  • 属性
    • mappedBy:指定关系的维护方
    • cascade:级联操作类型
    • fetch:加载策略(FetchType.EAGER/LAZY)

@OneToMany

  • 作用:定义一对多关系
  • 属性
    • mappedBy:指定关系的维护方
    • cascade:级联操作类型
    • fetch:加载策略(FetchType.EAGER/LAZY)

@ManyToOne

  • 作用:定义多对一关系
  • 属性
    • mappedBy:指定关系的维护方
    • cascade:级联操作类型
    • fetch:加载策略(FetchType.EAGER/LAZY)

@ManyToMany

  • 作用:定义多对多关系
  • 属性
    • mappedBy:指定关系的维护方
    • cascade:级联操作类型
    • fetch:加载策略(FetchType.EAGER/LAZY)

2.3、查询方法注解

@Query

  • 作用:定义自定义JPQL或原生SQL查询

  • 属性

    • value:JPQL/SQL查询语句
    • nativeQuery:是否为原生SQL(默认false)
    • countQuery:分页查询时统计总数的查询
  • 示例

    @Query("SELECT u FROM User u WHERE u.email = ?1")
    User findByEmail(String email);
    

@Modifying

  • 作用:标识修改数据的查询(UPDATE/DELETE) 自定义修改数据时,返回值必须为 void 或者 int/Integer!

  • 属性

    • clearAutomatically:执行后是否自动清除持久化上下文
    • flushAutomatically:执行前是否自动flush
  • 示例

    @Modifying
    @Query("UPDATE User u SET u.status = ?2 WHERE u.id = ?1")
    int updateUserStatus(Long id, String status);
    

@EntityGraph

  • 作用:定义实体图的加载策略,解决N+1查询问题
  • 属性
    • attributePaths:要立即加载的属性路径
    • type:加载类型(EntityGraphType.FETCH/LOAD)

3、简单的Demo创建

3.1、引入依赖

<!-- Spring Data JPA 依赖(重要) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- MySQL 驱动(重要) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>

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

<!-- 实体类插件 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

3.2、配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springbootjpa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
   username: root
    password: ys_nj_sst!
  jpa:
    hibernate:
      # 控制是否可以基于程序中Entity的定义自动创建或者修改DB中表结构
      ddl-auto: update
    # 是否打印运行时的sql
    show-sql: true

3.3、实体映射Entity

@Entity
@Data
@Table(name = "user")
public class User implements Serializable {

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

    @Column(nullable = false,unique = true,length = 20)
    private String username;

    @Column(nullable = false,length = 20)
    private String password;

    @Column(nullable = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")//返回格式化
    private Date regdate;

    @Transient
    private String remark;

}

3.4、定义Dao层

public interface UserRepository extends JpaRepository<User,Long> {
    
    @Query(value = "select * from user u where u.id = ?1",nativeQuery = true)
    User findUserById(@Param("id") Long id);

    /*
    *  注意:jpa手写更新语句时,返回值必须为void 或者 int/Integer
    */
    @Transactional
    @Modifying
    @Query(value = "update user set username = ?2,password = ?3 where id = ?1",nativeQuery = true)
    Integer update(Long id,String username,String password);

    /*
    *  不使用本地查询
    */
    @Query(value = "select u from User u where u.username like %:username%")
    List<User> findByNameMatch(@Param("username") String username);
}

网站公告

今日签到

点亮在社区的每一天
去签到