`
vortexchoo
  • 浏览: 64043 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

hibernate使用原生sql帮助类

    博客分类:
  • java
 
阅读更多

      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);

          }

}

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics