jpa使用自定义查询条件
Posted big-cut-cat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jpa使用自定义查询条件相关的知识,希望对你有一定的参考价值。
涛sir:http://www.cnblogs.com/it-taosir/p/9874033.html
意思就是jpa中使用类似like(模糊查询)和 limit (分页)查询结合,通过以下例子解析:
可理解为like,实际效率是比模糊查询like效率高的
建表:sql
create table order_info ( order_id varchar(30) not null, source_id varchar(30), serial_no varchar(30), source_system varchar(20), channel_mark varchar(5), cust_type varchar(4), cust_name varchar(60), goods_sku varchar(64), order_provinc_code varchar(6), order_city_code varchar(6), flow_node_code varchar(255), status int comment ‘0 未锁定 1 锁定 2挂起‘, create_user_id bigint, create_dt datetime, update_dt datetime, visible_status varchar(4) comment ‘0 可见 1 不可见‘, lock_user_id bigint, lock_user_name varchar(64), claim_dt datetime, verify_flag smallint comment ‘null 未审核,0 自动审核未通过 1 自动审核通过‘, create_user_no varchar(64) comment ‘创建人工号‘, create_user_name varchar(64), oper_user_id bigint, oper_user_no varchar(64) comment ‘处理人工号‘, oper_user_name varchar(64), amount bigint, disacount bigint comment ‘优惠金额‘, pay_money bigint, pay_type varchar(10) comment ‘HDFK 货到付款,ZXZF 在线支付‘, payment_type varchar(10) comment ‘XJZF 现金支付,POSC POS机刷卡等‘, pay_status smallint comment ‘0 未支付 1 已支付‘, goods_name varchar(200), exception_type int, lock_user_no varchar(64), flow_code varchar(255), primary key (order_id) );
实体类:
package cn.chinaunicom.srigz.orders.api.database.model; import java.io.Serializable; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import lombok.Data; import lombok.NoArgsConstructor; @Data @Entity @NoArgsConstructor public class OrderInfo implements Serializable { private static final long serialVersionUID = 1063821955023696541L; @Id private String orderId; private String sourceId; private String serialNo; private String sourceSystem; private String channelMark; private String custType; private String custName; private String goodsSku; private String orderProvincCode; private String orderCityCode; private String flowNodeCode; private Integer status; private Long createUserId; @Column(name = "create_dt", columnDefinition = "DATETIME") private Date createDt; @Column(name = "update_dt", columnDefinition = "DATETIME") private Date updateDt; private String visibleStatus; private Long lockUserId; private String lockUserName; @Column(name = "claim_dt", columnDefinition = "DATETIME") private Date claimDt; private Integer verifyFlag; private String createUserNo; private String createUserName; private Long operUserId; private String operUserName; private Long amount; private Long disacount; private Long payMoney; private String payType; private String paymentType; private Integer payStatus; private Integer exceptionType; private String lockUserNo; private String flowCode; @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY) @JoinColumn(name = "orderId") private List<GoodsInfo> goodsInfos; }
Repository:直接拷贝了,其实只要继承两个接口即可
package cn.chinaunicom.srigz.orders.api.database.dao; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.transaction.annotation.Transactional; import cn.chinaunicom.srigz.orders.api.database.model.OrderInfo; public interface OrderRepository extends JpaRepository<OrderInfo,String>, JpaSpecificationExecutor<OrderInfo> { @Query(value="SELECT * from order_info where lock_user_id=?1 AND status=1",nativeQuery=true) List<OrderInfo> selectMyOrders(String lockUserId); @Modifying @Transactional @Query(value="UPDATE order_info SET lock_user_id = NULL AND status = 0 WHERE order_id = ?1",nativeQuery = true) void unlockOrderByOrderId(String orderId); }
service:主要是这块的代码实现
涉及Specification对象的使用,使用匿名内部类重写Predicate toPredicate方法,
在toPredicate方法里按如下例子,设置查询的条件
最终使用findAll的重载方法进行分页查询
/** * 自定义条件查询 * 分页 */ @SuppressWarnings({ "deprecation", "serial" }) public Page<OrderInfo> findByPageAndParams(OrderInfo params, int pageSize, int pageNumber) { Pageable pageable = new PageRequest(pageNumber, pageSize); Specification<OrderInfo> orderInfo=new Specification<OrderInfo>() { //重写查询条件 @Override public Predicate toPredicate(Root<OrderInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) { //查询条件设置为:字段source_system中包含的条件查询 Path<String> sourceSystem = root.get("sourceSystem"); return criteriaBuilder.like(sourceSystem, "%"+params.getSourceSystem()+"%"); } }; return orderRepository.findAll(orderInfo, pageable); }
controller:Page对象封装了很多数据,我们只要取所需的即可
/** * @param orderInfo * @param pageSize * @param pageNum * @return */ @ApiOperation(value="按主题资源匹配查询", notes="SourceSystem") @RequestMapping(value = "/api/v1/orders/findBySourceSystem" ,method = RequestMethod.POST) public Object findBySourceSystem( @ApiParam(required = true, value = "符合SourceSystem的条件") @RequestBody OrderInfo orderInfo, @ApiParam(required = true, value = "每页条数") @RequestParam int pageSize, @ApiParam(required = true, value = "查询第几页") @RequestParam int pageNum ){ Page<OrderInfo> page= orderService.findByPageAndParams(orderInfo,pageSize,pageNum); List<OrderInfo> list=page.getContent(); return ActionHelper.responseOk(list); }
以上是关于jpa使用自定义查询条件的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot 之 使用JPA对数据进行复杂条件的查询
Spring Data 系列学习Spring Data JPA 自定义查询,分页,排序,条件查询
Spring Data 系列学习Spring Data JPA 自定义查询,分页,排序,条件查询