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

/**
* 定义一个查询条件容器
*
* @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. chrome 技巧 记录一些以前不太熟悉的

    chrome已经不知道用了多少年了,但是还是有些技巧不熟悉,记录下有用的和自己不熟悉的 如何查看dom的绑定事件(查看jquery的绑定事件) 新版本的network的类型选项哪去了? 在Source ...

  2. 【mybatis】mybatis中insert 主键自增和不自增的插入情况【mysql】

    主键不自增:返回值是插入的条数 <insert id="add" parameterType="EStudent"> insert into TSt ...

  3. inline-block空隙总结

    如果inline-block,宽度都是50%会留有空隙,解决方法如下 1.标签之间不留空格 (1)直接不留空 <div></div><div></div> ...

  4. MyBatis学习-偏实践(单独MyBatis项目)

    准备先把MyBatis搞熟悉了,然后把SpringMVC搞熟悉了. MyBatis的材料,除了我之前自己实验的 http://www.cnblogs.com/charlesblc/p/5906431. ...

  5. elasticsearch term 查询之一

    1.前言 term级别查询将按照存储在倒排索引中的确切字词进行操作,这些查询通常用于数字,日期和枚举等结构化数据,而不是全文本字段. 或者,它们允许您制作低级查询,并在分析过程之前进行. term级别 ...

  6. jquery.cookie.js操作cookie实现“记住密码”,很简单很强大

    //初始化页面时验证是否记住了密码 $(document).ready(function() { if ($.cookie("rmbUser") == "true&quo ...

  7. arm-linux-gdb+gdbserver环境搭建以及远程调试

    0) gdb源码下载:http://ftp.gnu.org/gnu/gdb/ 1) 编译arm-linux-gdb 指定交叉编译工具链的位置 export PATH=$PATH:/usr/local/ ...

  8. rails手脚架(scaffold)功能

    scaffold是一个高速开发rails应用的代码框架.能够使用一条命令实现CRUD操作. 1: 创建一个应用 rails new scaffoldapp cd scaffoldapp rails s ...

  9. java集合框架小结

    总结例如以下: 1.假设要求线程安全的, 使用Vector.Hashtable 2.假设不要求线程安全,应该使用ArrayList.LinkedList.HashMap 3.假设要求有映射关系,键值对 ...

  10. jQuery-DesktopGrid

    jQueryDesktopGrid jQueryDesktopGrid migrate to https://github.com/jelly-liu/jquery-osx jQuery deskto ...