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 JPA实现简单条件查询

Spring Data 系列学习Spring Data JPA 自定义查询,分页,排序,条件查询

jpa的JpaSpecificationExecutor使用对象自定义sql条件

Spring Data JPA 之 原生SQL使用