版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cheidou123/article/details/84447384
一 分页功能
在JPA中提供了很方便的分页功能,那就是Pageable(org.springframework.data.domain.Pageable)以及它的实现类PageRequest(org.springframework.data.domain.PageRequest),详细的可以见示例代码:
/**
* 一个参数,匹配两个字段
* @param name2
* @Param pageable 分页参数
* @return
* 这里Param的值和=:后面的参数匹配,但不需要和方法名对应的参数值对应
* 这里增加了@QueryHints注解,是给查询添加一些额外的提示
* 比如当前的name值为HINT_COMMENT是在查询的时候带上一些备注信息
*/
@Query("select c from Customer c where c.firstName=:name or c.lastName=:name")
Page<Customer> findByName(@Param("name") String name2,Pageable pageable);
/**
* 分页
* 应用查询提示@QueryHints,这里是在查询的适合增加了一个comment
* 查询结果是lastName和firstName都是bauer这个值的数据
*/
@RequestMapping("/pageable")
public void pageable(){
//Pageable是接口,PageRequest是接口实现
//PageRequest的对象构造函数有多个,page是页数,初始值是0,size是查询结果的条数,后两个参数参考Sort对象的构造方法
Pageable pageable = new PageRequest(0,3, Sort.Direction.DESC,"id");
Page<Customer> page = repository.findByName("bauer",pageable);
//查询结果总行数
System.out.println(page.getTotalElements());
//按照当前分页大小,总页数
System.out.println(page.getTotalPages());
//按照当前页数、分页大小,查出的分页结果集合
for (Customer customer: page.getContent()) {
System.out.println(customer.toString());
}
System.out.println("-------------------------------------------");
}
二 投影(Projection)的用法
三 数据更新的另外一种方式
除了使用modify注解来更新数据以外,我们还可以直接通过ave或者saveAndFlush来更新字段
save具有一定的延迟性,我们建议采用saveAndFlush来更新
更新的时候我们需要先把这个数据查出来,否则没有的字段会变成null或者默认值。
四 查询条件Specification
查询条件是最重要,在这里我们需要继承JpaSpecificationExecutor这个接口
public interface CustomerSpecificationRepository extends JpaRepository<Customer,Long>;,
JpaSpecificationExecutor<Customer> {
}
这个接口目前有如下几个方法
T findOne(Specification<T> var1);
List<T> findAll(Specification<T> var1);
Page<T> findAll(Specification<T> var1, Pageable var2);
List<T> findAll(Specification<T> var1, Sort var2);
long count(Specification<T> var1);
在spring的jpa中,主要是围绕着Specification接口来定义的。 Specification接口中只定义了如下一个方法
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
我们在实际的使用中主要就是重写这个方法
/**
* 条件查询补换卡订单列表时的动态组装条件
*
* @param orderId 订单编号
* @param orderType 补换卡类型:0-补换170卡,1-补换澳洲卡
* @param phone 补换的号码:当orderType为0时为170号码,当orderType为1时为澳洲号码
* @param orderStatus 订单状态:0-未付款,1-已付款,2-退款中,3-已退款 4-已撤单
* @param applyStatus 申请状态:0-未提交申请(未完成支付),1-申请已提交待处理(已完成支付),2-补换卡处理中,3-已完成,4-申请已取消
* @param payStatus 支付状态:0-未支付;1-已支付;2-支付失败
* @param openId 补换卡用户
* @return
*/
private Specification<ReplaceCardOrder> where(String orderId, Integer orderType, String phone, List<Integer> orderStatus, List<Integer> applyStatus, List<Integer> payStatus, String openId) {
return new Specification<ReplaceCardOrder>() {
@Override
public Predicate toPredicate(Root<ReplaceCardOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
// 订单编号
if (!StringUtils.isEmpty(orderId)) {
predicates.add(cb.equal(root.<String> get("orderId"), orderId));
}
// 订单状态
if (null != orderStatus && orderStatus.size() > 0) {
predicates.add(root.<Integer> get("orderStatus").in(orderStatus));
}
// 申请状态
if (null != applyStatus && applyStatus.size() > 0) {
predicates.add(root.<Integer> get("applyStatus").in(applyStatus));
}
// 支付状态
if (null != payStatus && payStatus.size() > 0) {
predicates.add(root.<Integer> get("payStatus").in(payStatus));
}
// 补换卡类型
if (null != orderType) {
predicates.add(cb.equal(root.<Integer> get("orderType"), orderType));
// 补换的号码
if (!StringUtils.isEmpty(phone)) {
if(orderType == ReplaceCardConstant.ORDER_TYPE_CN){
//补换170卡号码
predicates.add(cb.equal(root.<String> get("phoneCN"), phone));
} else if (orderType == ReplaceCardConstant.ORDER_TYPE_AU) {
//补换澳洲卡号码
predicates.add(cb.equal(root.<String> get("phoneAU"), phone));
}
}
}
// 补换卡用户
if (!StringUtils.isEmpty(openId)) {
predicates.add(cb.equal(root.<String> get("openId"), openId));
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
}