- 浏览: 49698 次
文章分类
最新评论
最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下
首先定义一个所有条件的容器,继承Specification
/**
* 定义一个查询条件容器
* @author lee
*
* @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
* @Create In 2012-2-8 By lee
* @param expression0 void
*/
public void add(Criterion criterion){
if(criterion!=null){
criterions.add(criterion);
}
}
}
然后是各种条件组装类,我首先做了一个接口来包装各种条件
Java代码 收藏代码
/**
* 条件接口
* 用户提供条件表达式接口
* @Class Name Criterion
* @Author lee
* @Create In 2012-2-8
*/
public interface Criterion {
public enum Operator {
EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR
}
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder);
}
然后是针对不同类型条件处理的实现
一个是简单比较类型的处理
Java代码 收藏代码
/**
* 简单条件表达式
* @author lee
*
*/
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;
}
}
}
一个逻辑条件计算实现
Java代码 收藏代码
/**
* 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等
* @author lee
*
*/
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()]));
default:
return null;
}
}
}
添加一个组装工厂类
Java代码 收藏代码
/**
* 条件构造器
* 用于创建条件表达式
* @Class Name Restrictions
* @Author lee
*/
public class Restrictions {
/**
* 等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.EQ);
}
/**
* 不等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.NE);
}
/**
* 模糊匹配
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LIKE);
}
/**
*
* @param fieldName
* @param value
* @param matchMode
* @param ignoreNull
* @return
*/
public static SimpleExpression like(String fieldName, String value,
MatchMode matchMode, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return null;
}
/**
* 大于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.GT);
}
/**
* 小于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LT);
}
/**
* 大于等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.GTE);
}
/**
* 小于等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LTE);
}
/**
* 并且
* @param criterions
* @return
*/
public static LogicalExpression and(Criterion... criterions){
return new LogicalExpression(criterions, Operator.AND);
}
/**
* 或者
* @param criterions
* @return
*/
public static LogicalExpression or(Criterion... criterions){
return new LogicalExpression(criterions, 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,Operator.EQ);
i++;
}
return new LogicalExpression(ses,Operator.OR);
}
}
使用方法如下
Java代码 收藏代码
Criteria<Event> c = new Criteria<Event>();
c.add(Restrictions.like("code", searchParam.getCode(), true));
c.add(Restrictions.eq("level", searchParam.getLevel(), false));
c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true));
c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true));
c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true));
c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true));
c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true));
c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true));
c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true));
c.add(Restrictions.in("solveTeam.code",teamCodes, true));
eventDao.findAll(c);
其中eventDao为继承JpaSpecificationExecutor的接口类
首先定义一个所有条件的容器,继承Specification
/**
* 定义一个查询条件容器
* @author lee
*
* @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
* @Create In 2012-2-8 By lee
* @param expression0 void
*/
public void add(Criterion criterion){
if(criterion!=null){
criterions.add(criterion);
}
}
}
然后是各种条件组装类,我首先做了一个接口来包装各种条件
Java代码 收藏代码
/**
* 条件接口
* 用户提供条件表达式接口
* @Class Name Criterion
* @Author lee
* @Create In 2012-2-8
*/
public interface Criterion {
public enum Operator {
EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR
}
public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,
CriteriaBuilder builder);
}
然后是针对不同类型条件处理的实现
一个是简单比较类型的处理
Java代码 收藏代码
/**
* 简单条件表达式
* @author lee
*
*/
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;
}
}
}
一个逻辑条件计算实现
Java代码 收藏代码
/**
* 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等
* @author lee
*
*/
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()]));
default:
return null;
}
}
}
添加一个组装工厂类
Java代码 收藏代码
/**
* 条件构造器
* 用于创建条件表达式
* @Class Name Restrictions
* @Author lee
*/
public class Restrictions {
/**
* 等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.EQ);
}
/**
* 不等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.NE);
}
/**
* 模糊匹配
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LIKE);
}
/**
*
* @param fieldName
* @param value
* @param matchMode
* @param ignoreNull
* @return
*/
public static SimpleExpression like(String fieldName, String value,
MatchMode matchMode, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return null;
}
/**
* 大于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.GT);
}
/**
* 小于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LT);
}
/**
* 大于等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.GTE);
}
/**
* 小于等于
* @param fieldName
* @param value
* @param ignoreNull
* @return
*/
public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) {
if(StringUtils.isEmpty(value))return null;
return new SimpleExpression (fieldName, value, Operator.LTE);
}
/**
* 并且
* @param criterions
* @return
*/
public static LogicalExpression and(Criterion... criterions){
return new LogicalExpression(criterions, Operator.AND);
}
/**
* 或者
* @param criterions
* @return
*/
public static LogicalExpression or(Criterion... criterions){
return new LogicalExpression(criterions, 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,Operator.EQ);
i++;
}
return new LogicalExpression(ses,Operator.OR);
}
}
使用方法如下
Java代码 收藏代码
Criteria<Event> c = new Criteria<Event>();
c.add(Restrictions.like("code", searchParam.getCode(), true));
c.add(Restrictions.eq("level", searchParam.getLevel(), false));
c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true));
c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true));
c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true));
c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true));
c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true));
c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true));
c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true));
c.add(Restrictions.in("solveTeam.code",teamCodes, true));
eventDao.findAll(c);
其中eventDao为继承JpaSpecificationExecutor的接口类
发表评论
-
ObjectMapper对json结构字符串和Java对象的转换
2016-10-18 15:54 8197package com.gtstar.cbos.web.ccs ... -
JpaSpecificationExecutor.class
2016-10-14 16:57 651Java代码 收藏代码 public interf ... -
hibernate的Criteria Query(转)
2016-09-02 12:08 452当查询数据时,人们往往需要设置查询条件。在SQL或HQL语句中 ... -
Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解
2016-08-18 13:45 1914引言: 接上一篇文章,对@RequestMapping进行地址 ... -
dbcTemplate详解
2016-08-12 09:16 5791、JdbcTemplate操作数据库 Spring对数据库的 ... -
Spring JdbcTemplate方法详解
2016-08-03 08:58 2381JdbcTemplate主要提供以下五类方法: •execut ... -
Spring Data 系列之JPA(二)
2016-07-15 10:40 481来一起看一下复杂查询 ... -
Spring Data 系列之JPA(一)
2016-07-15 10:36 500引入: Spring Data是SpringSource基 ... -
springMVC+spring+Hibernate的配置
2016-07-07 12:30 2531本实例采用springMvc冬眠 与 春天进行整合,用spri ... -
JdbcTemplate详解
2016-07-05 16:28 4721、JdbcTemplate操作数据库 Spring对数据库的 ... -
SpringMVC+Hibernate+Spring整合实例(一)
2016-07-05 09:17 528SpringMVC又一个漂亮的web框架,他与Struts2并 ... -
spring关于“transactionAttributes”的相关配置
2016-07-05 09:15 486spring关于“transactionAttri ... -
springMVC 参数传递
2016-07-01 09:39 526SpringMVC的各种参数绑定方式 1. 基本数据类 ...
相关推荐
总结来说,Spring Data JPA的`Specifications`接口为开发者提供了强大的动态查询能力,能够灵活地应对各种复杂的查询场景,同时保持代码的整洁和可维护性。通过熟练掌握`Specifications`,可以极大地提升开发效率,...
如果默认的CRUD方法不能满足需求,可以通过在Repository 接口中定义查询方法,Spring Data JPA 会根据方法名自动构建SQL。例如,`findByEmail` 方法会生成一个查找指定邮箱用户的查询。 6. **Service 层** 在业务...
**SpringBoot整合SpringData JPA** 是一个现代Java开发中的常见技术栈,它结合了Spring Boot的便捷性和Spring Data JPA的数据访问效率。Spring Boot简化了应用的初始搭建以及配置,而Spring Data JPA则是Spring ...
3. **Service/Repository层**:使用Spring Data JPA来处理数据库操作,Repository接口定义了对数据的CRUD操作,而Service层封装了业务逻辑。 4. **Model**:包含应用程序的数据模型,可能由实体类(Entity)和数据...
spring data jpa 实例源码 spring data jpa 实例源码 spring data jpa 实例源码
Spring MVC 是一个用于构建 Web 应用的模型-视图-控制器(MVC)框架,Spring 提供了依赖注入、AOP(面向切面编程)等核心功能,而 Spring Data JPA 则是简化数据库操作的利器,它封装了对 Java Persistence API(JPA...
在实际应用中,你可能会遇到更多复杂的查询需求,例如嵌套的分页查询、联接查询、聚合函数等,JPA和Spring Data JPA都提供了丰富的API来支持这些操作。例如,你可以使用`@Query`注解自定义SQL或HQL查询,或者利用`...
Spring Data JPA是在Hibernate基础之上的封装实现。当我们使用Spring Data JPA时,你会发现有时候没有SQL语句,其实框架的底层已经帮我们实现了,我们只需要遵守规范使用就可以了。 Spring Data JPA的配置 在...
3. **Repository 自动化查询**:Spring Data JPA 的一大亮点是能自动生成 SQL 查询。通过在 Repository 接口中定义方法名,系统可以自动识别并执行对应的数据库操作,如查找、添加、更新和删除。 4. **Thymeleaf ...
在 Spring Data JPA 中,DAO(Data Access Object)是一种常用的设计模式,用于封装数据访问逻辑。DAO 提供了一个抽象层,允许开发者使用 Java 语言来访问数据库,而不需要编写 SQL 语句。 Spring Data JPA 提供了...
Spring Data JPA 可以看作是对 JPA 的进一步封装和简化,它能够帮助开发者更快地实现对数据的增删改查操作。 在使用Spring Data JPA时,首先需要理解项目依赖,它通常会依赖于Spring框架的核心模块以及JPA规范实现...
Specifications是JPA的一部分,它允许构建动态查询条件。开发者可以构建查询的规格,然后利用这些规格来创建查询。 ### 事务 - **事务性查询方法**:Spring Data JPA提供了使用注解配置事务的方法,以保证数据的...
此外,Spring Data JPA 还支持自定义查询,通过在 Repository 接口中添加注解方法,可以执行更复杂的 SQL 或 HQL 查询。同时,它还提供了事务管理功能,确保数据的一致性和完整性。 总的来说,Spring MVC + Spring ...
Spring Data JPA 提供了诸如自动建表、查询方法自动生成、动态查询等功能,极大地提高了开发效率。通过使用 Spring Data JPA,我们可以定义 Repository 接口,只需要编写简单的查询方法,就能自动实现数据库的 CRUD...
3. **Spring Data JPA**: Spring Data JPA是Spring框架的一部分,它简化了持久层的开发,提供了对JPA(Java Persistence API)的封装。通过简单的注解,我们可以轻松实现CRUD操作,同时支持复杂的查询功能。它还支持...
Spring Data JPA 封装了 JPA,提供了更简单的方法来实现数据访问。通过定义 Repository 接口,Spring Data JPA 可以自动生成实现,包括CRUD操作,甚至复杂的查询方法。 在 "springMvc-jpa-blank-master" 这个项目中...
项目通过Spring Data JPA与数据库进行交互,支持事务管理、自定义查询和实体管理等功能。 项目的主要特性和功能 1. 事务管理 支持类级别和方法级别的事务注解。 提供只读事务和不同隔离级别的事务配置。 支持...
Spring Data JPA是Spring框架的一部分,它提供了对Java Persistence API (JPA) 的简化封装,允许开发者通过面向接口的方式进行数据库操作,包括进行复杂的查询和分页。 首先,要启用Spring Data JPA功能,我们需要...
3. **JPA 查询**:除了 Spring Data Commons 的自动查询推导,Spring Data JPA 还支持基于 JPA 的注解(如 `@Query`)自定义查询,甚至支持动态查询。 4. **Auditing**:提供了审计功能,可以追踪实体的创建时间和...
Spring Data 是 Spring 的一个子...2:详解Spring Data JPA封装的各种查询方式 3:详解Spring Data JPA常用接口 4:详解Spring Data JPA各种查询方式 5:详解Spring Data JPA在web方面的用法 具体内容,可以参考大纲: