Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part C JPA)

2022-08-24 14:40:19 浏览数 (1)

一、Spring Boot 整合 Spring Data JPA

Spring Data

Spring Data 项目是为了简化构建基于 Spring 框架的数据访问技术,包括非关系型数据库Map-Reduce框架、关系型数据库以及云数据服务的访问支持。

Spring Data 中又包含了多个子项目

Spring Data 的特点: Spring Data提供了统一的API来对数据访问层进行操作;这个规范主要是Spring Data Commons子模块来实现的,Spring Data Commons提供了针对关系型数据库和非关系型数据库访问数据时都基于Spring 提供的统一标准,这个标准包含了增删改查、条件查询、排序以及分页操作。

Spring Data 统一的Repository接口

  • Repository<T,ID extends Serializable>:统一接口
  • RevisionRepository<T,ID extends Serializable, N extends Number & Comparable<N>>:基于乐观锁机制
  • CrudRepository<T,ID extends Serializable>:基本CRUD
  • PagingAndSortingRepository<T,ID extends Serializable>:基本CRUD及分页排序

Spring Data 提供了数据访问类的模板 XxxTemplate,如RedisTemplate、MongoTemplate等

JPA 与 Spring Data

  • JpaRespository的基本功能
    • 编写接口继承JpaRepository,拥有CRUD以及分页功能
  • 定义符合规范的方法名,接口中只要生命符合规范的方法,既拥有对应的功能
    • 如方法名 findByLastnameAndFirstname,关键字是And,对应的JPQL条件部分既为”WHERE x.lastname = ? AND x.firstname = ?“
    • 方法名 findByLastnameOrFirstname,关键字Or,对应的JPQL
  • @Query自定义查询,定制查询SQL
  • Specifications查询(Spring Data JPA 支持 JPA 2.0 的Criteria查询)

二、Spring Data JPA 实现 CRUD

创建新工程spring-boot-jpa,引入Spring Data JPA

查看jpa的依赖图

配置默认的数据源

代码语言:javascript复制
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/test

创建一个实体类Telsa,并配置好映射关系

代码语言:javascript复制
@Data
@Entity // 标注为一个实体类
@Table(name = "jpa_tesla") // 设置实体类对应的表名
public class Tesla {

    @Id // 设置主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 设置主键为自增主键
    private Integer id;
    @Column // 列名默认与属性名一致
    private String name;
    @Column(name = "vehicle_type") // 设置列名
    private String vehicleType;
    @Column
    private String factory;
}

创建repository包,创建TeslaRepository接口继承JpaRepository,这里泛型中的第一个是实体类的类型,第二个是主键的类型

代码语言:javascript复制
public interface TeslaRepository extends JpaRepository<Tesla,Integer> {

    
}

JpaRepository接口中包含了基本的增删改查方法

在yml中配置jpa

代码语言:javascript复制
jpa:
  hibernate:
    # 更新或者创建数据表
    ddl-auto: create
  # 控制台显示执行的SQL
  show-sql: true

如果是第一次启动应用,并且数据库没有表,建议使用ddl-auto: create,应用启动可以根据实体类创建响应的表,如果不是第一次启动,建议改为ddl-auto: update。

JpaRepositoriesAutoConfiguration会在HibernateJpaAutoConfiguration自动配置之后才会启动自动配置

HibernateJpaAutoConfiguration启用类JpaProperties中的配置

jpa自动配置项都在JpaProperties类中

启动主程序,会自动创建表,根据实体类的属性及注解中声明的表名、字段名以及主键增长方式创建。

根据启动日志,可以确定Spring Boot自动执行了建表语句

测试TeslaRepository的CRUD方法

创建TeslaRepositoryTest测试类,注入TeslaRepository并新增save方法

代码语言:javascript复制
@SpringBootTest
public class TeslaRepositoryTest {

    @Resource
    private TeslaRepository repository;

    @Test
    public void testSave(){
        Tesla tesla = new Tesla();
        tesla.setName("Model 3");
        tesla.setVehicleType("Compact Car");
        tesla.setFactory("Shanghai Gigafactory");
        repository.save(tesla);
    }
}

执行testSave方法

新增getById方法

代码语言:javascript复制
@Test
public void testGetById(){
    Tesla tesla = repository.getById(1);
    System.out.println("查询到的数据为:"   tesla);
}

执行getById方法

此时需要在Tesla实体类上增加@Proxy(laxy=false)注解,重新执行

控制台成功显示查询到的数据。

出现这个报错基于JPA的实现来分析,就是在进行数据库访问之时,当前针对数据库的访问与操作session已经关闭且释放了,故提示no Session可用。

在测试类中新增update方法

代码语言:javascript复制
@Test
public void update(){
    Tesla tesla = new Tesla();
    tesla.setId(1);
    tesla.setName("Model 3P");
    tesla.setFactory("弗拉蒙特超级工厂");
    tesla.setVehicleType("四门轿车");
    repository.save(tesla);
}

执行update方法

根据控制台执行的SQL语句,JPA先执行了查询方法,查看是否存在,如果存在就更新,如果不存在就创建

在测试类中新增delete方法

代码语言:javascript复制
@Test
public void delete(){
    Tesla tesla = new Tesla();
    tesla.setId(2);
    repository.delete(tesla);
}

执行delete方法

根据控制台输出的SQL可以确定已经将id为1的记录删除

0 人点赞