概述
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语句进行查询。
规则:
- 应该使用
findBy
开头 - 查询某个字段,findBy后跟实体类的属性的名称,默认是等于
- 如果有多个条件,就在方法后加And+实体类的属性名。
- 方法的参数对应查询定义。
- 返回值根据返回的数据类型定义。
一、根据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,是最强大的查询方式,最复杂的查询方式。
使用方法:
- 需要dao继承
JpaSpecificationExecutor
接口(接口可以多重继承) - 使用
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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复