spring boot jpa复杂条件拼接查询语句

在业务中查询是一件非常头疼的事,毕竟不可能只是对一张表的查询是吧?其实在业务中往往会涉及到多张表的查询,以及查询时需要的各种条件。当然这不用担心,毕竟这是对JPA的支持,而我们在用JPA原生态API的时候往往可能会把一些个方法写得很凌乱,没得一个具体的规范来写自己的方法在后期维护上肯定会很困难。当然你自己也可以封装一些方法来使用,而当我们使用到Spring Data JPA时,它已经帮助我们完成了这个方法的规范了

Repository 在这里 继承 JpaSpecificationExecutor<T> ,可以写成这样

public interface ISampleColRepository extends JpaRepository<SampleCol, Integer>,JpaSpecificationExecutor<SampleCol>{

    @Override
    Page<SampleCol> findAll(Specification<SampleCol> specification, Pageable pageable);


}
//或者不用继承JpaSpecificationExecutor

public interface ISampleColRepository extends JpaRepository<SampleCol, Integer>{
  //直接这样写,没有了重写而已
Page<SampleCol> findAll(Specification<SampleCol> specification, Pageable pageable);

}

//servcie使用specification拼接查询语句

从上边的图可以看出,repository里的一些方法支持,  specification<T>这个参数,这个参数里就可以拼接查询条件,该参数里(接口)有一个方法toPredicate(),而其中的参数大家并不陌生,都是JPA规范中的,ROOT查询中的条件表达式,CriteriaQuery中条件查询设计器,CriteriaBuilder条件查询构造器---使用他们就能完成复杂点的查询语句拼接,而我们在使用复杂对象查询时,实现该方法用JPA去构造对象查询便可。  

例子1:

例1,在service层,
Page<User> page = useRepository.findAll(new Specification<User>() {  
            @Override  
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {  
                root = query.from(User.class);  
                Path<String> nameExp = root.get("name");  
                return cb.like(nameExp, "%Sam%");  //模糊查询
            }  
  
        }, new PageRequest(1, 5, new Sort(Direction.DESC, new String[] { "birth" })));  

 例子2

useRepository.findAll(new Specification<StockLog>() {
			@Override
			public Predicate toPredicate(Root<StockLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<>();
				list.add(cb.equal(root.get("del").as(Boolean.class), false));
                                //条件1 用户
				if(!StringUtils.isEmpty(username)){
					list.add(cb.equal(root.get("username").as(String.class),username));
				}
                                //条件2 类型
				if(type!=null){
					list.add(cb.equal(root.get("type").as(Integer.class),type));
				}
				query.where(cb.and(list.toArray(new Predicate[list.size()])));
				return query.getRestriction();
			}
		},pageable);

 结合再多字段排序,拼接的条件基本就够用了

//spring boot jpa分页从0页开始的  这里的1其实就是前台的第二页
Sort sort = new Sort(Sort.Direction.DESC, "createdate")
 .and(new Sort(Sort.Direction.AES, "id"));
Pageable pageable = new PageRequest(1, 10, sort)

 案例

service层

package com.jxwy.tagmanagement.service.samplecol.impl;

import com.jxwy.tagmanagement.model.samplecol.SampleCol;
import com.jxwy.tagmanagement.repository.sampleCol.ISampleColRepository;
import com.jxwy.tagmanagement.service.samplecol.ISampleColservice;
import com.jxwy.tagmanagement.utils.EntityToVoUtils;
import com.jxwy.tagmanagement.vo.samplecol.SampleColVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class ISampleColserviceImpl implements ISampleColservice {
    @Autowired
    private ISampleColRepository iSampleColRepository;
    @Autowired
    private EntityToVoUtils entityToVoUtils;

    @Override
    public SampleColVo save(SampleCol sampleCol) {
        //更新
        if (sampleCol != null && sampleCol.getId() != null) {
            Integer aL = iSampleColRepository.updateSampleById(sampleCol.getId(), sampleCol.getName(), sampleCol.getSqlStr(), sampleCol.getExceuteState(), sampleCol.getType(), new Date());
            if (aL > 0) {
                return entityToVoUtils.toSampleColVo(sampleCol);
            }
            return null;
        }
        // 新建
        SampleCol sampleColSave = iSampleColRepository.save(sampleCol);
        return entityToVoUtils.toSampleColVo(sampleColSave);
    }

    @Override
    public SampleColVo findById(Integer id) {
        return entityToVoUtils.toSampleColVo(iSampleColRepository.findOne(id));
    }

    @Override
    public void delById(Integer id) {
        iSampleColRepository.delete(id);
    }

    @Override
    public void delByIds(String ids) {
        String[] split = ids.split(",");
        List objects = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            SampleCol one = iSampleColRepository.findOne(Integer.parseInt(split[i]));
            if(one!=null){
                iSampleColRepository.delete(Integer.parseInt(split[i]));
            }
        }

    }

    @Override
    public List<SampleColVo> search(String content, Integer type, Integer executeState, Integer useRateFlag, Integer pageSize, Integer pageNo) {
        Sort sort = null;
        //排序 都是实体的属性名字
        if (useRateFlag == 0) {
            sort = new Sort(Sort.Direction.DESC, "creationDate")
                    .and(new Sort(Sort.Direction.DESC, "exceuteState"));
        } else {
            sort = new Sort(Sort.Direction.DESC, "useRate");
        }
    //分页从0开始
        Pageable pageable = new PageRequest(pageNo-1, pageSize, sort);
        //查询条件
        Page<SampleCol> sampleColPage = iSampleColRepository.findAll(new Specification<SampleCol>() {
            @Override
            public Predicate toPredicate(Root<SampleCol> root, CriteriaQuery<?> query, CriteriaBuilder cb) {//下边都是实体里的属性名字
                List<Predicate> list = new ArrayList<>();
                if (type!= null) {
                    list.add(cb.equal(root.get("type").as(Integer.class), type));//type为最上边方法的参数
                }
                // Expression<String> nameEx = root.get("name").as(String.class);

                if (content != null) {
                    list.add(cb.like(root.get("name").as(String.class), "%" + content + "%"));
                }
                Predicate predicate1 = cb.and(list.toArray(new Predicate[list.size()]));
                query.where(predicate1);
                System.out.print(query.toString());
                return query.getRestriction();

               /* if(content!=null){ //这里是or关系
                    Predicate predicate2 = cb.and();//参数可以是p1,p1  也可以是和上边的数组一样
                    Predicate predicate3 = cb.or(predicate1, predicate2);
                    //复杂的逻辑关系 and or
                    public Predicate toPredicate(Root<UserModel> root,  
                    CriteriaQuery<?> query, CriteriaBuilder cb) {  
                    Predicate p1 = cb.like(root.get("name").as(String.class), "%"+um.getName()+"%");  
                    Predicate p2 = cb.equal(root.get("uuid").as(Integer.class), um.getUuid());  
                    Predicate p3 = cb.gt(root.get("age").as(Integer.class), um.getAge());  
                    //把Predicate应用到CriteriaQuery中去,因为还可以给CriteriaQuery添加其他的功能,比如排序、分组啥的  
                    query.where(cb.and(p3,cb.or(p1,p2)));  
                    //添加排序的功能  
                    query.orderBy(cb.desc(root.get("uuid").as(Integer.class)));  
                    return query.getRestriction();  
    }  
                }*/
            }
        }, pageable);
        return entityToVoUtils.toSampleColVoList(sampleColPage.getContent());
    }
}

repository层

package com.jxwy.tagmanagement.repository.sampleCol;

import com.jxwy.tagmanagement.model.samplecol.SampleCol;
import com.jxwy.tagmanagement.vo.samplecol.SampleColVo;
import org.hibernate.sql.Update;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
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.data.repository.query.Param;

import java.util.Date;
import java.util.List;

public interface ISampleColRepository extends JpaRepository<SampleCol, Integer>,JpaSpecificationExecutor<SampleCol> {
    //保存
    @Override
    <S extends SampleCol> S save(S s);

    //更新
    @Query(value = "update sample_col S set S.name= :name,S.type = :type,S.sql_str=:sqlStr,S.exceute_state=:exceuteState ,S.creation_date = :createDate where S.id = :id", nativeQuery = true)
    @Modifying
    Integer updateSampleById(@Param(value = "id") Integer id,
                             @Param(value = "name") String name,
                             @Param(value = "sqlStr") String sqlStr,
                             @Param(value = "exceuteState") Integer exceuteState,
                             @Param(value = "type") String type,
                             @Param(value = "createDate") Date createDate);

    /**
     * 根据id删除
     */
    @Override
    void delete(Integer integer);

    /**
     * 根据ids删除
     */
    @Modifying
    @Query(value = "delete from SampleCol S where S.id in :ids ")
    void delByIds(@Param(value = "ids") List ids);

    /**
     * 根据id查询样
     */
    @Override
    SampleCol findOne(Integer integer);

    /**
     * search
     * 按照创建时间排序
     */
    /*@Query(value = "select * from sample_col S where  1=1 and if(:type is  null,1=1,S.type=:type) and if(:executeState is  null,1=1,S.exceute_state=:executeState)  order  by creation_date desc ,use_rate desc  limit :star ,:end ", nativeQuery = true)
    List<SampleCol> search(@Param(value = "type") Integer type, @Param(value = "executeState") Integer executeState, @Param(value = "createTimeFlag") Integer createTimeFlag, @Param(value = "useRateFlag") Integer useRateFlag, @Param(value = "star") Integer star, @Param(value = "end") Integer end);
*/

    /**
     *搜索
     * @param specification
     * @param pageable
     * @return
     */
    @Override
    Page<SampleCol> findAll(Specification<SampleCol> specification, Pageable pageable);
}

猜你喜欢

转载自blog.csdn.net/qq_27886997/article/details/85238414