Hibernate出现很久了,的确用起来很省事,只需要处理对象就可以操作数据库。但是凡事都有两面性,它的省事带来的一个问题就是确实不太灵活。有时候一句SQL搞定的事情,用HQL写看后台日志的话会发现它会把简单的事情复杂化,大大降低了效率。
Hibernate支持SQL情况如下:session.createSQLQuery("select * from xxx where .....").addEntity(A.class)。这个A类必须是对应库表映射的,否则数据是无法回填的。如果查询结果集为多表的组合,那么你的SQL要写成select a.*,b.*c.*... from a,b,c,...where ...然后分别对这几个表对应的实体类进行addEntity后来忍无可忍,直接写SQL接收返回的List<Object[]>(query.list()),然后遍历数组,从list中取Object数组,再从数组中取值手动添加到实体类,虽然这个地方写的比较繁琐,但是减少了与数据库的交互,也略去了不需要的数据。
对于用惯原生sql的我来说,更爱这种写原生sql的方法。当然比较简单的查询用HQL是必然的,要灵活运用。为了让自己免去重复遍历list,遍历数组的重复劳动,写了下面帮助方法,如果有跟我一样的兄台,也可以一用。
private static final String method_key = "set"; public static synchronized void fixDataToClz(Object clz,String[] orderArray,Object[] dataArray){ Method[] methods = null; try{ Class<?> c = clz.getClass(); methods = c.getDeclaredMethods(); for(int i=0;i<orderArray.length;i++){ String key = orderArray[i]; for(Method method:methods){ String method_name = method.getName(); if(method_name.startsWith(method_key)&&(method_name.substring(method_key.length()).equalsIgnoreCase(key))){ Field temp_field = c.getDeclaredField(key); Method callMethod = c.getDeclaredMethod(method_name, temp_field.getType()); Object obj = dataArray[i]; callMethod.invoke(clz, obj); break; } } } }catch(Exception e){ System.out.println(e.getMessage()); } }
PS:由于我的方法是写在帮助类中的static方法,因此加了锁,怕并发。也可以单另写在类中就不需要static synchronized 了。
使用方法:
1.创建一个自定义实体类,把自己想要查询的数据都写在类的属性值中,并增加getters&setters(下面例子中是Test类)。
2.写原生sql查询,根据自己写的sql语句来创建一个字符串数组,内容是sql中查询的内容。
例如:
select a.id,b.name from a b where a.id = b.fk_id;
那这个数组String[] order_array = {"id","name"};
注意,这个数组长度一定是跟查询元素的个数是一致的,但是内容要跟我们创建的自定义实体类的属性值一致。表a的id如果对应 自定义实体类的属性是 a_id,那么我们的数组中写的就是a_id而非id
3.List<Object[]> list = query.list();
List<Test> testList = new ArrayList<Test>();
if(!ArrayUtils.isEmpty(list)){
for(Object[] obj_array:list){
//new 一个需要回填值的实体类,不管是否在数据库有否映射表
Test test = new Test();
/**调用帮助方法,参数说明:自定义实体类对象(Test类),根据sql语句创建的数组(order_array注意数组元素顺序与sql查询column顺序一致),数据数组(obj_array由query.list()返回list中取得)。**/
fixDataToClz(test ,order_array,obj_array);
//将已经被填入值的实体类加入到list中去。
testList.add(test);
}
}
相关推荐
hibernate执行原生sql语句
NULL 博文链接:https://ynp.iteye.com/blog/2007053
该方式是原生SQL查询的一种方式,需要个人自己书写SQL语句进行操作,用法比较灵活多变,适合比较复杂的SQL查询.该压缩包是本人对该查询方式的一种总结练习
集成spring,hibernate,并且自写了一个sql的解析器,只有controller和service层,非常方便
Hibernate 函数 ,子查询 和原生SQL查询。Hibernate 函数 ,子查询 和原生SQL查询
Hibernate中的查询:HQL、Criteria、原生SQl的Demo,希望可以帮助大家理解Hibernate查询。
我们能够很方便的创建一个SQLQuery(SQLQuery是一个接口,在Hibernate4.2.2之前,默认返回的是SQLQuery的实现类——SQLQueryImpl对象,在下文中出现的SQLQuery如非注明,都是指该子类)对象来进行原生SQL查询:。...
spring4+hibernate4.3.5,连接sql,使用springMVC框架,完整可运行的程序,看李守宏的视屏,有些做了修改,比如spring版本,用JTDS连接,新手可参考做
NULL 博文链接:https://jeffenchung.iteye.com/blog/1472402
springboot利用jpa连接hibernate,并进行生成表,对表的增加,删除,查询操作用法2
主要介绍了Java的Hibernate框架中的缓存与原生SQL语句的使用,Hibernate是Java的SSH三大web开发框架之一,需要的朋友可以参考下
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...
在多数情况下不及特定数据库支持的物理分页,而hibernate的分页则是直接组装sql,充分利用了特定数据库的分页机制,效率相 对较高。本文讲述的就是如何在不重新编译ibatis源码的前提下,为ibatis引入hibernate式的...
问题描述: 备注:刚开始SQL 没有加任何AS ... WITH query AS (SELECT inner_query.*, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__ FROM 第二页 明显不一样的处理逻辑 select med.* fro
详细的Hibernate3的帮助文档 前言 ...11.4.4. 使用原生SQL的查询 11.5. 修改持久对象 11.6. 修改脱管(Detached)对象 11.7. 自动状态检测 11.8. 删除持久对象 11.9. 在两个不同数据库间复制对象
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...
15.2.3 Java Persistence中的原生SQL 15.3 过滤集合 15.4 高速缓存查询结果 15.4.1 启用查询结果高速缓存 15.4.2 理解查询高速缓存 15.4.3 什么时候使用查询高速缓存 15.4.4 自然标识符...
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...
10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. Session刷出(flush) 10.11. 传播性持久化...