利用反射机制完成所有hibernate的模糊、非模糊查询。可以按条件查询
有的时候我们会遇到这样的情况,比如图书馆有很多本书,这时候我们要按照书名查询,按照类别查询,按照作者查询,或者按照ISBN查询,并且有可能一次按照多个条件查询,这时候通常会需要如下的hql或者sql语句。
① from Book b
where b.bookName=”红楼梦“ and b.bookAuthor=”施耐庵” ……
② Select * from tb_book b where
b.bookName=”红楼梦“ and b.bookAuthor=”施耐庵” ……
并且在写servlet或者使用struts写action的时候需要针对不同的查询调用不同的DAO层,因此往往servlet或者dao需要写多个类似处理代码,他们几乎相同。
其实针对查询这些信息的时候我们完全可以利用反射机制来自动生成一条hql或者sql语句执行,不需要每次都写出新的语句,这样既不利于维护,也不利于开发。
我的设想就是,不管是否使用ORM框架,都需要有实体类对应数据库的表,而这些实体类的属性就对应了表的字段。
我们如果能利用一个实体类来进行针对自身不为null的属性生成hql或者sql语句,那么就可以利用一个查询的dao完成所有类型的查询了。
下面给出我写的hqlModel,这个类是一个用来生成查询语句的。
此类的中心思想就是自动生成查询语句,只要给定一个Object类型,就可以“自动”根据类的属性调用getter方法来获取值。如果值不为空,就按照该值来进行条件查询,如果没有任何属性被赋值,那么他将认为要生成form Book 这样的查询语句。
这样不管是查询所有数据,查询指定数据,多条件查询指定数据,都可以用同一个方法来执行。
至于模糊或者非模糊,只要给定一个boolean,然后判断就可以了。这样用setter作为其是否开启模糊查询的开关。
package com.leaves.daoUtil;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 此类用来创建hql查询语句,能自动生成如下格式hql语句。<br>
* from BookInfo where bookNameId='null' and bookName='《三国演义》' and
* bookAuthor='施耐庵' ;<br>
* 使用getHql()方法来创建hql语句,此方法调用会抛出异常。<br>
* 此类需要你为其提供一个带有get和set方法的bean,类会根据其get的方法获得其值,如果get属性不为null则添加where条件。<br>
* 如果没有设置任何方法,则默认生成from BookInfo形式HQL语句。
*
* @version 1.0.0.0
* @author leaves叶知泉,<a href="http://www.c5ms.com">官方网站www.c5ms.com</a>
*
*/
public class HqlModel {
private Object object;
/**
* 是否开启模糊查询
*/
private boolean likeSel;
public boolean isLikeSel() {
return likeSel;
}
/**
* 设置属性是否开启模糊查询
*
* @param likeSel
*/
public void setLikeSel(boolean likeSel) {
this.likeSel = likeSel;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
/**
* 允许不带参数实例化
*/
private HqlModel() {
}
/**
* 使用指定的对象来获取一个HqlModel实例
*
* @param object
* 实例化时所需要的DTO对象
*/
public static HqlModel newInstanceByObj(Object object) {
HqlModel hqlModel = new HqlModel();
hqlModel.setObject(object);
return hqlModel;
}
/**
* 用来进行创建hql语句的方法, 此方法可能抛出异常
*
* @return 根据传入对象的get方法构建的hql语句
*/
public String getHql() throws Exception {
// 预准备好的hql语句。
StringBuffer sbf = new StringBuffer("from Object where ");
// 得道给定实例的类型。
Class<?> theClass = this.getObject().getClass();
// 使用类名替换Object字符串。
sbf.replace(5, 11, theClass.getSimpleName());
// 活的该类所有属性。
Field[] fields = object.getClass().getDeclaredFields();
// 遍历所有属性
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(),
theClass);
// 获得所有属性的读取方法
Method getMethod = pd.getReadMethod();
// 执行读取方法,获得属性值
Object objTemp = getMethod.invoke(object);
// 如果属性值为null,就略过
if (objTemp == null) {
continue;
}
// 如果不为空。
// 判断是否开启模糊查询,添加查询条件,并且加上%%符号。
if (isLikeSel()) {
sbf.append(field.getName() + " like '%" + objTemp + "%'");
sbf.append(" and ");
}//同理添加查询条件,不添加%%符号。
else {
sbf.append(field.getName() + "='" + objTemp + "'");
sbf.append(" and ");
}
}
//最后一个属性设置完成之后取出残余的and和尾部的空格。
if (sbf.toString().endsWith("and ")) {
sbf.delete(sbf.length() - "and".length() - 1, sbf.length());
}
//如果没有设置任何属性,则取出尾部的where字符串和后面的空格。
if (sbf.toString().endsWith("where ")) {
sbf.delete(sbf.length() - "where".length() - 1, sbf.length());
}
//返回生成好的语句。
return sbf.toString();
}
}
目前属于1.0版本,还不支持sql语句生成,其实都是一个道理,只要在类中修改 StringBuffer sbf = new StringBuffer(“from Object where ”);这一句就能完成。
希望朋友们修改出更好的生成器之后能跟小弟一起分享,多多指教。
此类不足之处:
·没有sql、hql切换的开关
·理论上还可以生成update和save这样的语句,只是小弟还没有想到设计。
分享到:
相关推荐
对于单表查询,可以通过编写简单的Lambda表达式或者使用预定义的查询构造器来完成。 **示例**: ```java List<User> users = userMapper.selectList(new QueryWrapper().eq("status", "active")); ``` #### 3. 多...
Dao 接口的工作原理是通过 MyBatis 的反射机制来实现的,MyBatis 将 Dao 接口的方法转换为数据库操作。 10. MyBatis 是如何进行分页的?分页插件的原理是什么? MyBatis 提供了一个分页插件,用于实现数据库分页。...
11. **传递多个参数**:可以使用`@Param`注解,或者创建一个包含所有参数的Java Bean作为参数。 12. **动态SQL**:MyBatis的动态SQL用于构建灵活的SQL,包括`if`, `choose`, `when`, `otherwise`, `where`, `trim`,...
Spring框架利用反射机制读取和解析注解,从而实现特定的功能。 #### MyBatis面试高频问题 **问题一:什么是Mybatis?** - **MyBatis**是一个优秀的持久层框架,它支持定制SQL、存储过程以及高级映射。 **问题二...
Java基础语法 面向对象编程(OOP) 常用数据结构(如数组、链表、栈、队列等) 2、高级特性 多线程与并发编程 JVM原理与性能优化 反射与动态代理 3、框架与工具 Spring、Spring Boot MyBatis、Hibernate Maven、...
DAO层的实现可以通过Hibernate、EJB等ORM框架,或者手工编写,利用Java反射机制。 7. **错误处理**:在错误处理方面,应谨慎使用异常的打印输出,而是定义错误页面进行统一处理。例如,使用JSP的errorPage属性将...
Mybatis动态SQL非常有用,可以通过多种动态SQL标签如if、choose、when、otherwise等来实现SQL条件逻辑,使SQL更加灵活。MyBatis的XML映射文件中,除了常见的标签外,还包含、、等高级配置标签。 MyBatis的XML映射...
很抱歉,由于您提供的标题和描述中包含了"xxxxxx"的模糊信息,我无法明确具体的IT知识点。然而,从标题可以推断这可能是一个关于某个特定系统的用户手册,而"docx.zip"表明这是一个被压缩的Microsoft Word文档。通常...