项目中使用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的生成代码就可以进行多条件查询了。欢迎和大家多多沟通学习,如有任何改进意见和建议,我的QQ是1243672,欢迎联系哦。

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

  1. Spring Data JPA,一种动态条件查询的写法

    我们在使用SpringData JPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实现. 如果是查询条件是动态的,框架也提供了查询接口. Jpa ...

  2. jpa中使用Query判断条件查询

    jpa中使用Query判断条件查询 @Query(value = " select m.* from mining_area as m " + " where 1 = 1 ...

  3. SpringMVC整合Hibernate实现增删改查之按条件查询

    首先我贴出我项目的结构,只完成了条件查询的相关代码,增删改没有写. 1.新建一个动态Web工程,导入相应jar包,编写web.xml配置文件 <context-param> <par ...

  4. orm 通用方法——GetOneModel 条件查询一个对象

    数据连接层的方法封装成通用方法是很有必要,节省不必要的重复写代码. Golang的orm.xorm框架没有封装这些操作. 这里是一个查询单个对象的方法. 此处抛砖引玉,大家继续完善. 通用方法定义代码 ...

  5. orm 通用方法——QueryModelCount条件查询记录数

    定义代码: /** * 描述:根据条件查询对象数 * 作者:Tianqi * 日期:2014-09-17 * param:model 对象实例 * param:cond 查询条件 * return:i ...

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

    在做项目中,我们经常遇到复杂的查询方法,要根据用户的输入,判断某个参数是否合法,合法的话才能当作过滤条件,我们通常的做法是把查询SQL赋值给一个字符串变量,然后根据判断条件动态的拼接where条件进行 ...

  7. 为什么放弃Hibernate、JPA、Mybatis,最终选择JDBCTemplate

    一.前言 因为项目需要选择数据持久化框架,看了一下主要几个流行的和不流行的框架,对于复杂业务系统,最终的结论是,JOOQ是总体上最好的,可惜不是完全免费,最终选择JDBC Template. Hibe ...

  8. 泛型理解及应用(二):使用泛型编写通用型Dao层

    相信目前所有的IT公司网站在设计WEB项目的时候都含有持久层,同样地使用过Hibernate的程序员都应该看过或者了解过Hibernate根据数据库反向生成持久层代码的模板.对于Hibernate生成 ...

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

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

随机推荐

  1. namenode 问题小记

    问题1:namenode进程故障 Namenode挂掉,Namenode gc日志里面YGC报错promotion failed 现象描述 NameNode进程挂掉,Namenode gc日志里面YG ...

  2. 使用scikit-learn 估计器分类

    本章的几个概念: 估计器(estimator) 用于分类.聚类和回归分析          转换器(transformer):用于数据预处理回来数据转换          流水线(pipeline): ...

  3. java多线程(六)

    使用Runnable接口创建线程 Runnable接口 只有一个run()方法 Thread类实现了Runable接口 便于多个线程共享资源 Java不支持多继承,如果已经继承了某个基类,便要实现Ru ...

  4. Django组件拾忆

    知识预览 一 Django的form组件 二 Django的model form组件 三 Django的缓存机制 四 Django的信号 五 Django的序列化 回到顶部 一 Django的form ...

  5. 3.1 Templates -- Handlerbars Basics(Handlerbars基础知识)

    一.简介 Ember.js使用Handlerbars模板库来强化应用程序的用户界面.它就像普通的HTML,但也给你嵌入表达式去改变现实的内容. Ember使用Handlerbars并且用许多新特性去扩 ...

  6. SpringData关键字查询练习

    我们在上一节知道SpringData关键字有很多,我就拿几个例子练练手 1.需求我们查询lastName like sun and id < ?的查询 package com.fxr.sprin ...

  7. Java基础知识陷阱(九)

    本文发表于本人博客. 今天我来说说关于JAVA多线程知识,有错误请指出.大家都知道JAVA在服务端上处理也有很大优势,很多公司也有在服务器跑JAVA进程,这说明JAVA在处理这个多线程以及并发下也有一 ...

  8. 基于SSH RSA的信任关系

    RSA 非对称加密算法 client  --->  server 私钥 公钥 1. 客户端生成密钥对 ssh-keygen -t rsa 执行后产生的密钥对会分别追加写到当前用户家目录下的以下文 ...

  9. 解决[Xcodeproj] Unknown object version错误

    错误描述: RuntimeError - [Xcodeproj] Unknown object version. /Library/Ruby/Gems/2.0.0/gems/xcodeproj-0.2 ...

  10. iview使用vue-i18n实现国际化

    iview官网中和网上的例子中使用的都是webpack方式,需要import js文件,但是由于项目架构比较简单,没有使用webpack,纯html和js进行交互.所以这里就直接使用js文件引用方式. ...