在业务中查询是一件非常头疼的事,毕竟不可能只是对一张表的查询是吧?其实在业务中往往会涉及到多张表的查询,以及查询时需要的各种条件。当然这不用担心,毕竟这是对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);
}