我是靠谱客的博主 瘦瘦大地,最近开发中收集的这篇文章主要介绍SpringDataJpa(四):四种特殊的查询方法SpringDataJpa,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

SpringDataJpa

  • SpringDataJpa
    • 使用jpql查询
      • 使用jpql更新
    • 使用原生sql查询
    • 方法命名规则查询(推荐使用)
    • 使用Specification查询

SpringDataJpa

使用jpql查询

使用方法:
1)在dao接口中定义一个方法。使用方法的参数设置jpql的参数,使用方法的返回值接收查询结果。
2)在方法上添加一个@Query注解。
3)在注解中编写jpql。
4)测试

一、使用jpql查询全部

public interface CustomerDao extends JpaRepository<Customer,Long> {
@Query("from Customer")
List<Customer> getAllCustomer();
}
@Test
public void find7() {
List<Customer> allCustomer = customerDao.getAllCustomer();
for (Customer customer : allCustomer) {
System.out.println(customer);
}
}

二、查询分页
在查询方法中添加一个Pageable参数

@Query("from Customer")
List<Customer> getAllCustomerByPage(Pageable pageable);
@Test
public void find8() {
List<Customer> allCustomer = customerDao.getAllCustomerByPage(new PageRequest(0,5));
for (Customer customer : allCustomer) {
System.out.println(customer);
}
}

三、jpql查询带参数

根据id查询

@Query("from Customer where custId = ?")
Customer getCustomerById(long id);
@Test
public void find9() {
Customer customer = customerDao.getCustomerById(100l);
System.out.println(customer);
}

根据客户名称和地址进行模糊查询

  • sql:SELECT * FROM cst_customer WHERE cust_name LIKE '%王%' and cust_address LIKE '%浙江%'
  • jpql:from Customer where custName like ? and custAddress like ?

注意:参数与问号需要进行顺序对应

@Query("from Customer where custName like ? and custAddress like ?")
List<Customer> getCustomerByNameAndAddress(String name,String address);
@Test
public void find10() {
List<Customer> customerList = customerDao.getCustomerByNameAndAddress("%王%", "%浙江%");
for (Customer customer : customerList) {
System.out.println(customer);
}
}

如果就想要反着写,则可以进行参数的顺序标记

@Query("from Customer where custName like ?2 and custAddress like ?1")
List<Customer> getCustomerByNameAndAddress(String address,String name);

使用jpql更新

可以执行更新、删除操作,不支持插入操作。

  • sql:UPDATE cst_customer set cust_source = '互联网' where cust_id = 100
  • jpql: update Customer set custSource = ? where custId = ?

使用方法:
1)在dao接口中定义一个方法。
2)在方法上添加@Query注解,在注解中编写jpql语句
3)在方法上添加@Modifying注解
4)测试

注意:

  • 自定义的jpql方法需要开启事务,且需要提交。
  • dao原本就有的方法里因为有@Transactional注解,所以不用加

方式一:在测试方法中加注解

@Query("update Customer set custSource = ? where custId = ?")
@Modifying
void updateSource(String source, long id);
@Test
@Transactional
@Commit
public void testUpdate() {
customerDao.updateSource("互联网",100l);
}

方式二:在dao接口方法中加注解
注意:在测试方法中默认回滚,在dao方法中默认提交

@Query("update Customer set custSource = ? where custId = ?")
@Modifying
@Transactional
void updateSource(String source, long id);
@Test
public void testUpdate() {
customerDao.updateSource("互联网",100l);
}

使用原生sql查询

不推荐使用原生的sql,但也可以用

使用方法:
1)在dao中定义一个方法
2)在方法上添加@Query注解
3)在注解中添加原生的sql语句,添加一个属性nativeQuery=true

@Query(value = "select * from cst_customer where cust_name like ?" , nativeQuery = true)
List<Customer> getAllCustomerBySQL(String name);
@Test
public void find11() {
List<Customer> customerList = customerDao.getAllCustomerBySQL("%王%");
for (Customer customer : customerList) {
System.out.println(customer);
}
}

方法命名规则查询(推荐使用)

通过一定的规则定义一个方法,框架就可以根据方法名生成一个sql语句进行查询。

规则:

  1. 应该使用findBy开头
  2. 查询某个字段,findBy后跟实体类的属性的名称,默认是等于
  3. 如果有多个条件,就在方法后加And+实体类的属性名。
  4. 方法的参数对应查询定义。
  5. 返回值根据返回的数据类型定义。

一、根据id查询

Customer findByCustId(long id);
@Test
public void find12() {
Customer customer = customerDao.findByCustId(100l);
System.out.println(customer);
}

二、两个条件的模糊查询

List<Customer> findByCustNameLikeAndCustAddressLike(String name, String address);
@Test
public void find13() {
List<Customer> customerList = customerDao.findByCustNameLikeAndCustAddressLike("%王%", "%浙江%");
for (Customer customer : customerList) {
System.out.println(customer);
}
}

三、分页查询
如果需要分页在方法中添加一个参数Pageable即可。

List<Customer> findByCustAddressLike(String address, Pageable pageable);
@Test
public void find14() {
List<Customer> customerList = customerDao.findByCustAddressLike("%浙江%", new PageRequest(0, 5));
for (Customer customer : customerList) {
System.out.println(customer);
}
}

获得page对象:直接返回类型写上Page即可

Page<Customer> findByCustAddressLike(String address, Pageable pageable);
@Test
public void find14() {
Page<Customer> page = customerDao.findByCustAddressLike("%浙江%", new PageRequest(0, 5));
long totalElements = page.getTotalElements();
int totalPages = page.getTotalPages();
List<Customer> content = page.getContent();
for (Customer customer : content) {
System.out.println(customer);
}
}

使用Specification查询

Specification:说明书

除了原生sql,是最强大的查询方式,最复杂的查询方式。

使用方法

  1. 需要dao继承
    JpaSpecificationExecutor接口(接口可以多重继承)
  2. 使用JpaSpecificationExecutor接口中提供方法进行查询。每个方法都需要使用Specification对象作为参数。

JpaSpecificationExecutor接口
其中有三个方法:

  • findOne:查询一条记录
  • findAll:查询多条记录
  • count:统计记录数

Specification接口
只有一个toPredicate方法:
返回一个查询条件。在方法中应该创建一个查询条件并返回。
返回值Predicate:查询条件。
参数

  • Root:代表sql语句的根节点。相当于sql语句中from后的表名。
  • CriteriaQuery
    查询对象。sql语句中的关键字包含在其中。
where
order by
group by
having
  • CriteriaBuilder:工具对象。
    所有的条件的生成都是使用CriteriaBuilder。只要涉及判断都需要使用CriteriaBuilder对象。主要使用CriteriaBuilder创建条件。

一、根据id查询
sql:select * from cst_customer where cust_id = ?

接口上添加继承的接口

public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
}
@Test
public void find15() {
Customer customer = customerDao.findOne(new Specification<Customer>() {
@Override
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//参数1:字段名称
//参数2:字段的值
Predicate predicate = cb.equal(root.get("custId"), 100l);
return predicate;
}
});
System.out.println(customer);
}

也可以使用lambda表达式来写

@Test
public void find15() {
//
Customer customer = customerDao.findOne(new Specification<Customer>() {
//
@Override
//
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//
//参数1:字段名称
//
//参数2:字段的值
//
Predicate predicate = cb.equal(root.get("custId"), 100l);
//
return predicate;
//
}
//
});
Customer customer = customerDao.findOne((root, query, cb) -> cb.equal(root.get("custId"), 100l));
System.out.println(customer);
}

二、根据客户名称和地址模糊查询

@Test
public void find16() {
customerDao.findAll(new Specification<Customer>() {
@Override
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//创建查询条件,根据名称模糊查询
Predicate predicate1 = cb.like(root.get("custName"), "%王%");
//创建查询条件,根据地址模糊查询
Predicate predicate2 = cb.like(root.get("custAddress"), "%北京%");
//组合两个条件
Predicate predicate = cb.and(predicate1, predicate2);
//返回
return predicate;
}
}).forEach(c-> System.out.println(c));
}

三、分页查询

@Test
public void find17() {
Page<Customer> page = customerDao.findAll(new Specification<Customer>() {
@Override
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//创建查询条件,根据名称模糊查询
Predicate predicate1 = cb.like(root.get("custName"), "%王%");
//创建查询条件,根据地址模糊查询
Predicate predicate2 = cb.like(root.get("custAddress"), "%浙江%");
//组合两个条件
Predicate predicate = cb.and(predicate1, predicate2);
//返回
return predicate;
}
}, new PageRequest(0, 5));
List<Customer> content = page.getContent();
for (Customer customer : content) {
System.out.println(customer);
}
}

四、排序
1、在findAll方法中添加Sort参数

@Test
public void find18() {
List<Customer> customerList = customerDao.findAll(new Specification<Customer>() {
@Override
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.like(root.get("custName"), "%王%");
return predicate;
}
}, new Sort(Sort.Direction.DESC, "custId"));
for (Customer customer : customerList) {
System.out.println(customer);
}
}

2、在接口中添加排序,使用CriteriaQuery对象

@Test
public void find19() {
List<Customer> customerList = customerDao.findAll(new Specification<Customer>() {
@Override
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.like(root.get("custName"), "%王%");
//添加排序条件
Predicate result = query.where(predicate)
.orderBy(cb.desc(root.get("custId")))
.getRestriction();
return result;
}
});
for (Customer customer : customerList) {
System.out.println(customer);
}
}

最后

以上就是瘦瘦大地为你收集整理的SpringDataJpa(四):四种特殊的查询方法SpringDataJpa的全部内容,希望文章能够帮你解决SpringDataJpa(四):四种特殊的查询方法SpringDataJpa所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部