Hibernate结合JPA编写通用泛型多条件查询

项目中使用Hibernate和JPA对数据库对象进行实例化,但是生成的方法不支持多条件查询。而如果针对每一个数据库对象进行多条件查询编码,则会变得很麻烦,而且一旦以后发生表结构发生变化,这些方法可能还需要进行重新编码。所以考虑编写一个方法可以对数据库对象进行多条件查询,并返回泛型对象,这样就可以方便使用。具体实现思路如下:

第一步:编写数据库查询参数对象,此部分包含两个,一个是查询实体名称(QueryCondition.java),一个是数据库查询条件对象(QueryParameter.java)。

数据库查询条件对象(QueryParameter.java)包含三个参数,分别为参数名、参数值、查询条件表达式

package com.imstudio.jpa;
public class QueryParameter {

	public enum QueryOperateType {
		Equal, CharIn
	}

	public String ParameterName;
	public Object ParameterValue;
	public QueryOperateType ParameterType;

	public QueryParameter() {

	}

	public QueryParameter(String parameterName, Object parameterValue,
			QueryOperateType parameterType) {
		this.ParameterName = parameterName;
		this.ParameterValue = parameterValue;
		this.ParameterType = parameterType;
	}

	public String getParameterName() {
		return ParameterName;
	}

	public QueryOperateType getParameterType() {
		return ParameterType;
	}

	public Object getParameterValue() {
		return ParameterValue;
	}

	public void setParameterName(String parameterName) {
		ParameterName = parameterName;
	}

	public void setParameterType(QueryOperateType parameterType) {
		this.ParameterType = parameterType;
	}

	public void setParameterValue(Object parameterValue) {
		ParameterValue = parameterValue;
	}

}

查询对象实体(QueryCondition.java)包含查询实体名称以及查询参数对象

package com.imstudio.jpa;
import java.util.ArrayList;
import java.util.List;

public class QueryCondition {
	public String ModelName;
	public List<QueryParameter> Parameters = new ArrayList<QueryParameter>();

	public QueryCondition() {

	}

	public QueryCondition(String modelName) {
		this.ModelName = modelName;
	}

	public QueryCondition(String modelName, List<QueryParameter> parameters) {
		this.ModelName = modelName;
		this.Parameters = parameters;
	}

	public void add(QueryParameter queryParameter) {
		this.Parameters.add(queryParameter);
	}

	public String getModelName() {
		return ModelName;
	}

	public List<QueryParameter> getParameters() {
		return Parameters;
	}

	public void setModelName(String modelName) {
		ModelName = modelName;
	}

	public void setParameters(List<QueryParameter> parameters) {
		Parameters = parameters;
	}
}

在完成上述两个实体对象之后就可以具体查询方法的编写了,在查询中使用到一个变量querySymbols,下述编码是从配置文件web.xml中获取,这里主要是为了在使用不同数据库的时候查询关键字标示符的修改。同时为了增加查询方法的通用性,查询返回数据这里定义为泛型。

package com.imstudio.jpa;import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.struts2.ServletActionContext;
import com.imstudio.jpa.QueryParameter.QueryOperateType;

public class QueryDataAction {    
    public String errorCode;
    public QueryDataAction() {
    
    }    
    
    public QueryDataAction(String errorCode) {
            this.errorCode = errorCode;
    } 
       
    public String getErrorCode() {
            return errorCode;
    };

    @SuppressWarnings("unchecked")    
    public <T> List<T> queryByPropertys(QueryCondition queryCondition) {
        String querySymbols = ServletActionContext.getServletContext()
                .getInitParameter("QuerySymbols");
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("select model \n");
        sqlBuffer.append("from " + queryCondition.ModelName + " as model \n");        
        boolean first = true;        
        for (int pi = 0; pi < queryCondition.Parameters.size(); pi++) {
             if (queryCondition.Parameters.get(pi).getParameterName() != null) {                                if (first) {
                    sqlBuffer.append("where ");
                    first = false;
                } else {
                    sqlBuffer.append("and ");
                }                
                if (queryCondition.Parameters.get(pi).getParameterType() == QueryOperateType.Equal) {
                    sqlBuffer.append("model."
                            + queryCondition.Parameters.get(pi)
                                    .getParameterName()                            + " = "
                            + querySymbols                            + queryCondition.Parameters.get(pi)
                                    .getParameterName() + " \n");
                } else if (queryCondition.Parameters.get(pi).getParameterType() == QueryOperateType.CharIn) {
                    sqlBuffer.append("InStr(model."
                            + queryCondition.Parameters.get(pi)
                                    .getParameterName()                            + " , "
                            + querySymbols                            + queryCondition.Parameters.get(pi)
                                    .getParameterName() + " ) > 0 \n");
                }
            }
        }
        List<T> list = new ArrayList<T>();        
        try {
            EntityManagerHelper.log(sqlBuffer.toString(), Level.INFO, null);
            EntityManager emEntityManager = EntityManagerHelper
                    .getEntityManager();
            Query queryObject = emEntityManager.createQuery(sqlBuffer
                    .toString());            
                    for (int li = 0; li < queryCondition.Parameters.size(); li++) {
                queryObject.setParameter(queryCondition.Parameters.get(li)
                        .getParameterName(), queryCondition.Parameters.get(li)
                        .getParameterValue());
            }
            list = queryObject.getResultList();
            emEntityManager.close();

        } catch (RuntimeException re) {
            errorCode += "CM000006";
            EntityManagerHelper.log("queryByPropertys error", Level.SEVERE, re);
            throw re;
        }        return list;
    }    
    
    public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
    }

}

Hibernate结合JPA编写通用泛型多条件查询

时间: 2024-10-12 18:18:13

Hibernate结合JPA编写通用泛型多条件查询的相关文章

必须知道的SQL编写技巧,多条件查询不拼字符串的写法

在做项目中,我们经常遇到复杂的查询方法,要根据用户的输入,判断某个参数是否合法,合法的话才能当作过滤条件,我们通常的做法是把查询SQL赋值给一个字符串变量,然后根据判断条件动态的拼接where条件进行查询.下面来简单说一下写SQL中遇到的问题和解决办法. 一.不确定字段名,而产生的SQL字符串拼接                                                                                                    

必须知道的sql编写技巧。多条件查询不拼接字符串&#183;的写法

在做项目中,我们经常遇到复杂的查询方法,要根据用户的输入,判断某个参数是否合法,合法的话才能当作过滤条件,我们通常的做法是把查询SQL赋值给一个字符串变量,然后根据判断条件动态的拼接where条件进行查询.下面来简单说一下写SQL中遇到的问题和解决办法.  一.不确定字段名,而产生的SQL字符串拼接 比如,有个公司要做一个系统,要支持多语言,这个时候我们就要将语音信息存储在数据库中.然后,根据客户选择查询对应的语言字段,进行显示.下面我们来模拟这个场景,打开SQL Server,新建SysLan

使用泛型编写通用的C#预处理类型转换方法

废话 从.net3.5发布后,就很多前辈利用泛型创造出了很多很有趣的代码,通用的转换方法也被写的烂了,小弟不才,今天又来写一遍,只是为了做个人知识的管理和追赶大牛的步伐,请各位路过的大大多多批评指正. 思路 1.基本类型都实现了IConvertible这个接口 2.基本类型都实现了TryParse方法 实现 public static class Converter { /// <summary> /// 转换为其他继承IConvertible的类型 /// </summary>

【续】使用泛型编写通用的C#预处理类型转换方法(使用委托提高性能)

优化后的代码: public static class Converter { /// <summary> /// 转换为其他继承IConvertible的类型 /// </summary> /// <typeparam name="T">转换的类型</typeparam> /// <param name="value">要转换的值</param> /// <param name=&quo

Hibernate与Jpa的关系,以及使用分页和动态查询

最近由于项目调动,我去了使用JPA的项目组, 因为之前的项目组使用MyBatis,所以一时间关于JPA和Hibernate的知识体系记得不熟,导致出现了混乱:在网上看到了这篇文章,终于解决了我心中的疑惑:JPA是一种规范,Hibernate实现了这种规范 . 这篇短小精悍的文章给了我很多的启发,于是,我把它"复制"到了本文! http://blog.sina.com.cn/s/blog_5f1619e80100yoxz.html 我知道Jpa是一种规范,而Hibernate是它的一种实

Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法

先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 2 的对应的属性赋值:属性即为 Map 的键,值即为 Map 的值. 使用 JDBC 驱动程序处理元数据 Java 通过JDBC获得连接以后,得到一个Connection 对象,可以从这个对象获得有关数据库管理系统的各种信息,包括数据库中的各个表,表中的各个列,数据类型,触发器,存储过程等各方面的信

数据持久层框架iBatis, Hibernate 与 JPA 比较

在本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persistence API(JPA).我们介绍每种解决方案并讨论其所规定的品质,以及在广泛的应用场景中其各自的长处和缺点.然后我们会基于诸如性能.移植性.复杂性以及对数据模型改变的适应性等因素来比较iBATIS.Hibernate和JPA. 如果你是一个刚起步的Java程序员,新接触持久性概念的话,那么就把阅读此文当作是接受一次这一主题以及大部分流行的开源持久性解决方案的启蒙.如果你对这

SpringData Jpa、Hibernate、Jpa 三者之间的关系

JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架--因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现,JBoss应用服务器底层就以Hibernate作为JPA的实现. 既然JPA作为一种规范--也就说JPA规范中提供的只是一些接口,显然接口不能直接拿来使用.虽然应用程序可以面向接口编程,但JPA底层一定需要某种JPA实现,否则JPA依然无法使用. 从笔者的视角来看,Sun之所以提出

jpa多条件查询重写Specification的toPredicate方法(转)

Spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor.Criteria 查询:是一种类型安全和更面向对象的查询 . 这个接口基本是围绕着Specification接口来定义的, Specification接口中只定义了如下一个方法: Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); 要理解这个方