spring jpa 数据库操作流程

spring JPA实践

1 什么是spring JPA
java persistence api:基于JPA接口规范实现的ORM框架,通过继承jpaRepository,spring data jpa运行时会自动将java对象映射为spl数据库中得实体表,将运行得实体对象持久化得数据库
2 怎么做
1) 引入相关依赖,配置resuorce目录下得yml

<dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true # 连接网址
    username: root # 用户名
    password: root # 密码
    driver-class-name: com.mysql.cj.jdbc.Driver  # 驱动
    hikari:#引入依赖
      maximum-pool-size: 20       # 对应 max-active
      minimum-idle: 10            # 对应 min-idle (建议设为与 max 相同或略小)
      connection-timeout: 30000   # 连接超时时间 (毫秒)
      idle-timeout: 600000        # 空闲连接存活时间 (毫秒)
      max-lifetime: 1800000       # 连接最大生命周期 (毫秒)

2)配置好之后,创建mysql实体表以及java中对应的实体对象属性(要对应的上)

@Data // lombok注解,避免手动创建构造函数和getter setter方法
@Entity //表明其为实体,spring 扫描后就可以将其进行持久化
@Table(name = "t_user")
public class UserDO implements Serializable {

    @Id //表明其为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true) //列明,不要求非空,但要求值唯一
    private String username;

    @Column(nullable = false)
    private String phone;

    @Column(name = "create_time", nullable = false)
    private Date createTime;

    @Column(nullable = false)
    private Integer status;

}

3)创建好实体类之后要创建jap repository类进行持久化

public interface UserRepository extends CrudRepository<UserDO, Long> {
  //CrudRepository内部已经实现了简单的根据列名进行增删改查操作,用户可以直接使用
//CrudRepository,PagingAndSortingRepository,SimpleJpaRepository,QueryDslJpaRepository 等接口提供了额外的功能
  //如果要使用复杂得查询,比如多对一查询,可以自定义sql语句,然后传入相应的实体类参数
  @Query(value = "SELECT u.* FROM t_user u JOIN t_order o ON u.id = o.user_id WHERE o.amount > :minAmount", 
             nativeQuery = true)
      List<UserDO> findUsersWithLargeOrders(@Param("minAmount") BigDecimal minAmount);
}

4) 实际应用:业务实现层进行实际应用

@Service
public class UserController {
    @Resource
    private final UserRepository userRepository;

    public UserDO getUserInfo(@PathVariable long id){
        UserDO userDO = userRepository.findById(id).orElse(null);
        return userDO;
    }

}

进阶:spring jpa框架如何实现操作内存中的对象一样操作数据库
ORM框架:对象关系映射的本质(反向代理)
具体执行流程:
启动阶段
├── Spring 扫描 @Entity,构建元数据(PersistentClass)
├── 构建 SessionFactory,对需懒加载的实体做字节码增强(生成子类)
└── 扫描 Repository 接口 → 生成 JDK/CGLIB 代理 → 注入 SimpleJpaRepository

运行时
├── 业务调用 repo.findById(1)
├── TransactionManager 开启事务(ThreadLocal 绑定 EntityManager/Connection)
├── 检查 Persistence Context(一级缓存)→ 命中则直接返回
├── 未命中 → 生成 SQL → JDBC 执行 → ResultSet 组装对象
│ └── 对象放入缓存 + 保存快照 + 标记 MANAGED
├── 返回:实体实例(字节码增强后的子类,关联字段可能是 HibernateProxy)

├── 修改对象:user.setName("New")(只改内存,不发 SQL)

└── 事务提交
├── flush():遍历缓存,对比快照 → 发现变更
├── 生成并执行 UPDATE SQL
├── commit() 到数据库
└── 关闭 Session,归还连接

图片

导航