Spring DataJPA的Specifications动态查询
程序员文章站
2022-04-25 19:33:11
...
Spring DataJPA的Specifications动态查询
JpaSpecificationExecutor接口的方法
T findOne(Specification<T> var1); //查询单个对象
List<T> findAll(Specification<T> var1); //查询列表
//查询全部 分页 Pageable:分页参数
//返回值:分页PageBean(springdatajpa提供的)
Page<T> findAll(Specification<T> var1, Pageable var2);
//查询列表,
//Sort:排序参数
List<T> findAll(Specification<T> var1, Sort var2);
//统计查询
long count(Specification<T> var1);
Specification对象:查询条件(进行查询时,需要自定义我们自己的Specification实现类)
实现的方法:
/*
* Root:代表查询的跟对象(查询的任何属性都可以从跟对象中获取)
* CriteriaQuery:顶层查询对象,自定义查询方式(了解)
* CriteriaBuilder:查询的构造器,封装了很多查询条件
*/
Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);//封装查询条件
dao层接口
public interface CustomerDao extends JpaRepository<Customer,Integer>, JpaSpecificationExecutor<Customer> {
}
根据客户名查询客户
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {
@Resource
CustomerDao customerDao;
/*
* 根据条件,查询单个对象
* */
@Test
public void testSpec(){
//匿名内部类
/*
* 定义一查询条件,
* 1.实现Specification接口(提供泛型,就是查询的对象类型)
* 2.实现toPredicate方法(构造查询条件)
* 3.需要借助方法参数中的两个参数(root:获取需要查询的对象属性;CriteriaBuilder:构造查询条件的,内部封装了很多查询条件(模糊匹配,精准匹配))
*
* 案例:根据客户名查询
* 查询条件:
* 1.查询方式,在CriteriaBuilder对象中
* 2.比较的属性名称:在Root对象中
* */
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取比较的属性
Path<Object> name = root.get("name");
//构造查询条件,select * from customer where name = "heima"
//参数1:需要比较的属性Path对象 参数2;当前需要比较的取值
Predicate predicate = cb.equal(name, "heima");//进行精准匹配,比较属性的取值
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
}
多个条件进行查询(接口内容不需要写)
/*
* 多条件查询:根据客户名和客户所属行业进行查询
* */
@Test
public void testSepc2(){
/*
* root:获取属性:客户名称,所属行业
* cb:构造查询
* 1.构造客户名的精准匹配查询
* 2.构造所属行业的精准匹配查询
* 3.将以上两个查询联系起来
* */
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取客户名称,所属行业
Path<Object> name = root.get("name");
Path<Object> industry = root.get("industry");
//.构造客户名的精准匹配查询
Predicate predicate1 = cb.equal(name, "heima");
Predicate predicate2 = cb.equal(industry, "教育");
//将以上两个查询联系起来(组合:满足条件1并且满足条件2,满足条件1或者满足条件2)
Predicate predicate = cb.and(predicate1, predicate2); //以与的形式拼接条件
//cb.or() 以或的方式拼接条件
return predicate;
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
根据用户名进行模糊查询
/*
* 案例:根据客户名进行迷糊查询
* equal:直接得到path对象(属性),然后进行比较即可
* gt lt le like:得到path对象,根据path指定比较的参数类型,再去进行比较 path.as(参数类型的字节码)
* */
@Test
public void testSpec3(){
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
Path<Object> name = root.get("name");
Predicate predicate = cb.like(name.as(String.class), "%马%");
return predicate;
}
};
List<Customer> customerList = customerDao.findAll(spec);
System.out.println(customerList);
}
根据客户名进行迷糊查询并按照id排序
/*
* 案例:根据客户名进行模糊查询并按照id排序
* */
@Test
public void testSpec4(){
Specification<Customer> spec = new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
Path<Object> name = root.get("name");
Predicate predicate = cb.like(name.as(String.class), "%马%");
return predicate;
}
};
//创建排序对象,需要调用构造方法实例化对象
//参数1:排序的顺序(Sort.Direction.DESC:倒序 Sort.Direction.ASC:升序);参数2:排序的属性名
Sort sort = new Sort(Sort.Direction.DESC,"id");
List<Customer> customerList = customerDao.findAll(spec,sort);
System.out.println(customerList);
}
分页查询
/*
* 分页查询
* findAll(Specification,Pageable):带有条件的分页
* findAll(Pageable):没有条件的分页
* 参数1:Specification
* 参数2:Pageable
* 查询的页码,每页查询的条数
*
* 返回:Page对象:SpringDataJpa为我们封装好的pageBean对象
* */
@Test
public void testSpec5(){
/*
* PageRequest树Pageable接口的实现类
* 创建PageRequest时需要调用构造方法传入两个参数
* 参数1:当前查询的页数(从0开始)
* 参数2:当前查询的总数
* */
Pageable pageable = new PageRequest(0,3);
//分页查询
Page<Customer> page = customerDao.findAll(pageable);
System.out.println(page.getTotalElements()); //表中的总条数
System.out.println(page.getTotalPages()); //得到总页数
System.out.println(page.getContent()); //得到结果列表,list集合
}
推荐阅读
-
flask/django 动态查询表结构相同表名不同数据的Model实现方法
-
JSP使用JDBC完成动态验证及采用MVC完成数据查询的方法
-
JDK动态代理给Spring事务埋下的坑!
-
JAVAEE——宜立方商城09:Activemq整合spring的应用场景、添加商品同步索引库、商品详情页面动态展示与使用缓存
-
[C#]利用 DynamicLinq 实现简单的动态表达式构建查询
-
Excel里两种方法实现动态查询与查询符合条件的多个结果
-
Spring系列第十五讲 Spring中的Java动态代理技术(上)
-
Spring data jpa的使用与详解(复杂动态查询及分页,排序)
-
基于jpa的specification实现动态查询
-
spring data jpa的动态查询封装