一、定义一个查询条件容器

/**
* 定义一个查询条件容器
*
* @param <T>
*/
public class Criteria<T> implements Specification<T> {
private List<Criterion> criterions = new ArrayList<Criterion>(); public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
if (!criterions.isEmpty()) {
List<Predicate> predicates = new ArrayList<Predicate>();
for(Criterion c : criterions){
predicates.add(c.toPredicate(root, query,builder));
}
// 将所有条件用 and 联合起来
if (predicates.size() > 0) {
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}
}
return builder.conjunction();
}
/**
* 增加简单条件表达式
* @Methods Name add
* @param
*/
public Criteria<T> add(Criterion criterion){ if(criterion!=null){
criterions.add(criterion);
} return this;
}
}

二、条件接口

public interface Criterion {  

    public enum Operator {
EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR
} public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder);
}

三、逻辑条件表达式,用于复杂条件时使用,如or或and

public class LogicalExpression implements Criterion {
private Criterion[] criterion; // 逻辑表达式中包含的表达式
private Operator operator; //计算符 public LogicalExpression(Criterion[] criterions, Operator operator) {
this.criterion = criterions;
this.operator = operator;
} public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<Predicate>();
for(int i=0;i<this.criterion.length;i++){
predicates.add(this.criterion[i].toPredicate(root, query, builder));
}
switch (operator) {
case OR:
return builder.or(predicates.toArray(new Predicate[predicates.size()]));
case AND:
return builder.and(predicates.toArray(new Predicate[predicates.size()])); default:
return null;
}
} }

四、简单条件表达式

public class SimpleExpression implements Criterion{  

    private String fieldName;       //属性名
private Object value; //对应值
private Operator operator; //计算符 protected SimpleExpression(String fieldName, Object value, Operator operator) {
this.fieldName = fieldName;
this.value = value;
this.operator = operator;
} public String getFieldName() {
return fieldName;
}
public Object getValue() {
return value;
}
public Operator getOperator() {
return operator;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
Path expression = null;
if(fieldName.contains(".")){
String[] names = StringUtils.split(fieldName, ".");
expression = root.get(names[0]);
for (int i = 1; i < names.length; i++) {
expression = expression.get(names[i]);
}
}else{
expression = root.get(fieldName);
}
switch (operator) {
case EQ:
return builder.equal(expression, value);
case NE:
return builder.notEqual(expression, value);
case LIKE:
return builder.like((Expression<String>) expression, "%" + value + "%");
case LT:
return builder.lessThan(expression, (Comparable) value);
case GT:
return builder.greaterThan(expression, (Comparable) value);
case LTE:
return builder.lessThanOrEqualTo(expression, (Comparable) value);
case GTE:
return builder.greaterThanOrEqualTo(expression, (Comparable) value);
default:
return null;
}
} }

五、条件构造器,用于创建条件表达式

public class Restrictions {  

    /**
* 等于
* @param fieldName
* @param value
* @return
*/
public static SimpleExpression eq(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.EQ);
} /**
* 不等于
* @param fieldName
* @param value
* @return
*/
public static SimpleExpression ne(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.NE);
} /**
* 模糊匹配
* @param fieldName
* @param value
* @param
* @return
*/
public static SimpleExpression like(String fieldName, String value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.LIKE);
} /**
* 大于
* @param fieldName
* @param value
* @return
*/
public static SimpleExpression gt(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.GT);
} /**
* 小于
* @param fieldName
* @param value
* @return
*/
public static SimpleExpression lt(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.LT);
} /**
* 大于等于
* @param fieldName
* @param value
* @return
*/
public static SimpleExpression lte(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.LTE);
} /**
* 小于等于
* @param fieldName
* @param value
* @param
* @return
*/
public static SimpleExpression gte(String fieldName, Object value) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Criterion.Operator.GTE);
} /**
* 并且
* @param criterions
* @return
*/
public static LogicalExpression and(Criterion... criterions){
return new LogicalExpression(criterions, Criterion.Operator.AND);
}
/**
* 或者
* @param criterions
* @return
*/
public static LogicalExpression or(Criterion... criterions){
return new LogicalExpression(criterions, Criterion.Operator.OR);
}
/**
* 包含于
* @param fieldName
* @param value
* @return
*/
@SuppressWarnings("rawtypes")
public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) {
if(ignoreNull&&(value==null||value.isEmpty())){
return null;
}
SimpleExpression[] ses = new SimpleExpression[value.size()];
int i=0;
for(Object obj : value){
ses[i]=new SimpleExpression(fieldName,obj, Criterion.Operator.EQ);
i++;
}
return new LogicalExpression(ses, Criterion.Operator.OR);
} /**
* 不包含于
* @param fieldName
* @param value
* @return
*/
@SuppressWarnings("rawtypes")
public static LogicalExpression notin(String fieldName, Collection value, boolean ignoreNull) {
if(ignoreNull&&(value==null||value.isEmpty())){
return null;
}
SimpleExpression[] ses = new SimpleExpression[value.size()];
int i=0;
for(Object obj : value){
ses[i]=new SimpleExpression(fieldName,obj, Criterion.Operator.NE);
i++;
}
return new LogicalExpression(ses, Criterion.Operator.AND);
} /**
* between
* @param fieldName
* @param object1
* @param object2
* @return
*/
public static LogicalExpression between(String fieldName, Object object1, Object object2)
{
if(object1 == null || object2 == null)
{
return null;
}
SimpleExpression[]ses=new SimpleExpression[2];
ses[0]=new SimpleExpression(fieldName,object1, Criterion.Operator.GTE);
ses[1]=new SimpleExpression(fieldName,object2, Criterion.Operator.LTE);
return new LogicalExpression(ses, Criterion.Operator.AND);
}

六、构造动态查询仓库接口

@NoRepositoryBean
public interface BaseRepository<T,ID extends Serializable> extends PagingAndSortingRepository<T,ID> { int count(Specification<T> specification);
Page<T> findAll(Specification<T> specification, Pageable pageable);
List<T> findAll(Specification<T> specification);
}

使用实例:

POJO对象为

public class UserInfo
{
private Integer id;
private String name;
...
}

dao接口为

public interface UserInfoService extends BaseRepository<UserInfo,Integer>
{
}

使用:

@RunWith(SpringRunner.class)
@SpringBootTest
public class test
{
@Autowired
private UserInfoService userInfoService;
@Test
public void test()
{
Criteria<UserInfo> criteria = new Criteria<>();
criteria.add(Restrictions.eq("id",10)).add(Restrictions.like("name","abc"));
List<UserInfo> users = userInfoService.findAll(criteria);
}
}

JPA动态查询封装的更多相关文章

  1. SSH动态查询封装接口介绍

    SSH动态查询封装接口介绍 1.查询记录总条数 public int count(Class c,Object[][] eq,Object[][] like,String[] group,String ...

  2. spring data jpa 动态查询(工具类封装)

    利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...

  3. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  4. spring jpa 动态查询(Specification)

    //dao层 继承 扩展仓库接口JpaSpecificationExecutor (JPA 2引入了一个标准的API)public interface CreditsEventDao extends ...

  5. Spring Data JPA动态查询(多条件and)

    entity: @Entity @Table(name = "data_illustration") public class Test { @Id @GenericGenerat ...

  6. spring JPA 动态查询

    没什么好说的,记住就行. 下面是在Service中的方法 Page<TStaff> staffs=dao.findAll(new Specification<TStaff>() ...

  7. Hibernate JPA 动态criteria语句针对null查询条件的特殊处理

    最近原Hibernate项目需要添加一个条件,结构有点类似下面的格式,学生和房间是多对一的关系,现在要查询所有没有房间的学生. Class Student{ @ManyToOne Room room; ...

  8. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  9. SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

    软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...

随机推荐

  1. Oracle常见故障问题

    1. ORA-27102: out of memory 创建pfile文件: create pfile from spfile: 修改pfile文件 修改文件/home/oracle/app/orac ...

  2. ACM--素数距离问题

    题目描述:现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离.如果输入的整数本身就是素数,则输出该素数本身,距离输出 ...

  3. javascript函数,构造函数。js对象和json的区别。js中this指向问题

    函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.好处:在出现大量程序相同的时候,可以封装为一个function,这样只用调用一次,就能执行很多语句.(1)语法:函数就是包裹在花括号中的代码 ...

  4. c++之list学习

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <list> using namespace std; ...

  5. flume分布式日志收集系统操作

    1.flume是分布式的日志收集系统,把收集来的数据传送到目的地去. 2.flume里面有个核心概念,叫做agent.agent是一个java进程,运行在日志收集节点. 3.agent里面包含3个核心 ...

  6. 【LeetCode】Find Minimum in Rotated Sorted Array 解题报告

    今天看到LeetCode OJ题目下方多了"Show Tags"功能.我觉着挺好,方便刚開始学习的人分类练习.同一时候也是解题时的思路提示. [题目] Suppose a sort ...

  7. git学习——分支

    分支 创建分支:git branch 如:git branch testing Git通过HEAD指针知道用户是在哪一个分支上工作. 切换分支用git checkout命令,注意:可以用git sta ...

  8. Win7如何改变用户文件夹位置

    现在装WIN7后第一件就是改变用户账户文件夹位置..因为里面存着一些软件的设定和信息等..不必要每次装后都手动改一次.. 已前用优化大师改.太麻烦.也不稳定有时有些目录不能完全改过来.. 通过命令mk ...

  9. 如何将微信小程序页面内容充满整个屏幕

    修改该页面的wxss文件 /* pages/weather/weather.wxss */ .weather{ position: fixed; height: 100%; width: 100%; ...

  10. tcp/ip--百度百科

    Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议.Inter ...