这里写自定义目录标题
1.概念
SpringData JPA 是Spring提供的持久层的解决方案
SpringData JPA其实就是Spring对JPA操作的封装(entiyManager)
SpringData JPA 是对JPA操作的封装 ,如果要使用SpringDataJPA有两个条件:
Spring整合JPA
需要有一个JPA的实现框架,例如Hibernate
SpringData JPA 是Spring Data的其中一个子模块 也就是Spring对JPA的操作进行了封装 弱化了Hibernate,我们需要Hibernate只是需要他去实现JPA规范提供的接口和类
2.创建项目
1.导包
4.0.0
cn.itsource
yxb
1.0-SNAPSHOT
2.applicationContext.xml(springDataJPA基本配置)
<context:component-scan base-package=“com.tjc.service”/>
<context:property-placeholder location=“classpath:jdbc.properties”/>
3测试 1.准备domain层 ①抽取一个父类将 BaseDomian (主键) 用@MappedSuperclass注解 让jpa知道这是一个父类 ②子类 也就是要创建的表的类 要继承父类 2.sitory层 定义一个接口,让这个接口去继承 JpaRepository <>中的参数就是要操作的domian层的对象 以及对象的主键类型 public interface EmployeeRepository extends JpaRepository2.Query注解
@Query(“jpql的语句”)
@Query(“select o from Employee o where o.name like ?1”)
//@Query(“select o from Employee o where o.name like :name”)
@Query(nativeQuery = true,value=“select * from employee”)
//通过原生SQL来查询
@Query(nativeQuery = true,value = “SELECT * FROM employee”)
List query04();
3.分页查询
//1.需要先创建一个page对象(注意:页数是从0开始计算【0就是第1页】)
Pageable pageable = new PageRequest(0, 10);
//2.进行查询
Page page = employeeRepository.findAll(pageable);
-
排序
//排序 :第一个参数是排序的规则(DESC/ASC) 后面参数是排序的字符
Sort sort = new Sort(Sort.Direction.DESC,“username”);
List emps = employeeRepository.findAll(sort); -
分页与排序
创建排序对象之后放入分页对象中就OK
Sort sort = new Sort(Sort.Direction.DESC,“username”);
Pageable pageable = new PageRequest(0, 10,sort); -
JpaSpecificationExecutor
作用 :动态生成Query提供了JpaSpecificationExecutor接口
1.要使用这个接口中的方法,就必须用repository中的接口去实现
EmployeeRepository extends JpaRepository<Employee,Long>, JpaSpecificationExecutor
2.实现了之后的运用:采用
List employees = employeeRepostory.findAll(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
// 拿到想要通过某属性查找的字段,直接通过get方法拿到 不要泛型
Path usernamePath = root.get(“username”);
// 再对这个属性添加某种查询规则…比如 where Like
Predicate predicate = criteriaBuilder.like(usernamePath, “%1%”);
// 如果有多种查询条件
Path emailPath = root.get(“email”);
Predicate predicate1 = criteriaBuilder.like(emailPath, “%2%”);
// 将两种和起来
Predicate predicate2 = criteriaBuilder.and(predicate, predicate1);
// 将这个值返回 employees拿到
return predicate2;
}
其中有3个参数 root :根 可以获取对应类的字段
cuiteriaQuery :也就是 select form 等 sql语句
Criteriaquery :过滤的属性
criteriaBuilder: 找到对应的 要求 确定关系条件 username=? / username like ?
用这个方法来使用太麻烦 -
JPA-SPEC插件
动态生成Query的插件,需要导入相应的包
com.github.wenhao
jpa-spec
3.1.1
// 根据规则完成查询
List employees = employeeRepostory.findAll(spec);
employees.forEach(e-> System.out.println(e));
6. 抽取Query
1.作用
抽取前面的公共的代码
- 作用是1.减少代码量
-
2.规范代码
-
3.保持扩展灵活
前端传来的数据查询要求以name email age 为例
// 当前页
private int currentPage=1;
// 每页的条数
private int pageSize=10;
// 排序字段的名字
private String orderName;
// 排序的规则
private String orderType = “ASC”;
// 规范子了获取Specification对象的方法
public abstract Specification createSpec();
// 创建排序对象
public Sort createSort(){
// 如果 排序字段的名字不为空就执行,如果为空就返回null
if(StringUtils.isNotBlank(orderName)){
// 排序规则 获得排序规则
return new Sort(Sort.Direction.valueOf(orderType.toUpperCase()),orderName);
}
return null;
}
2.子类获取 Specification对象
将前端需要查询的3个项目的值用模糊查询写好
@Override
public Specification createSpec() {
Specification<Employee> spec = Specifications.<Employee>and()
// 查询的字段 查询的值
.like(StringUtils.isNotBlank(username), “username”,"%"+username+"%")
.like(StringUtils.isNotBlank(email), “email”, “%”+email+"%")
.gt(age!=null,“age”,age)
.build();
return spec;
}
3.测试类中的要求
模仿前端查询的要求
EmployeeQuery employeeQuery = new EmployeeQuery();
// 查询出来的就是比20要大的数字
employeeQuery.setAge(20);
// 查询出来的是 模糊查询有1的名字
employeeQuery.setUsername(“1”);
// 有2的email
employeeQuery.setEmail(“2”);
// 拿到查询对象
Specification spec = employeeQuery.createSpec();
List employees = employeeRepostory.findAll(spec);
employees.forEach(e-> System.out.println(e));
}