项目中使用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. matplotlib-折线图、散点图

    (一)折线图小结 1.设置图片大小(想要一个高清无码大图) # 图大小 plt.figure(figsize=(20, 8), dpi=80) 2.保存到本地 # 设置图片大小 plt.figure( ...

  2. mysql 数据操作 单表查询 group by 介绍

    group by 是在where 之后运行 在写单表查询语法的时候 应该把group by 写在 where 之后 执行顺序 1.先找到表 from 库.表名 2.按照where 约束条件 过滤你想要 ...

  3. 4.windows如何导入python包

    python链接:https://www.python.org/downloads/release/python-2715/ pip链接:https://pypi.org/project/pip/#f ...

  4. 跟我学Makefile(二)

    命令出错: 每当命令运行完后, make 会检测每个命令的返回码,如果命令返回成功,那么 make 会执行下一条命令. 如果一个规则中的某个命令出错了(命令退出码非零),那么 make 就会终止执行当 ...

  5. Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表,以及同步和异步执行模式)

    系列文章导航 Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表) Adobe AIR中使用Flex连接Sqlite数据库(2)(添加,删除,修改以及语句参数) Adobe ...

  6. [置顶] SNMPv3认证和加密过程

    前面的一些文章详细讲解了SNMPv3的报文内容,下面主要的内容就是SNMPv3的加密和认证过程! USM的定义为实现以下功能: 鉴别 数据加密 密钥管理 时钟同步化 避免延时和重播攻击 1.UsmSe ...

  7. P2831 愤怒的小鸟(状压dp)

    P2831 愤怒的小鸟 我们先预处理出每个猪两两之间(设为$u,v$)和原点三点确定的抛物线(当两只猪横坐标相等时显然无解) 处理出$u,v$确定的抛物线一共可以经过多少点,记为$lines[u][v ...

  8. Ubuntu屏幕录制工具【转】

    本文转载自:https://blog.csdn.net/Draonly/article/details/74898031 原文参考:https://www.sysgeek.cn/simplescree ...

  9. linux开启nscd服务缓存加速

    在我使用的阿里云主机上有观察到开启了一个服务nscd ,后来谷哥了下该服务的作用.了解到nscd会缓存三种服务passwd group hosts,所以它会记录三个库,分别对应源/etc/passwd ...

  10. 查看nginx版本和安装的模块

    查看nginx版本 # nginx -v nginx version: nginx/1.12.2 查看nginx配置了哪些模块 # nginx -V nginx version: nginx/1.12 ...