相对于JDBC来说,hibernate有一定的好处,它封装了数据库的连接、查询,修改等,为我们提供了方便的数据访问的。但是于此同时,作为一个封装性强的框架,hibernate不免就暴露出了它的缺点,那就是数据库查询的不灵活性。
hibernate本身对复杂的sql本身支持的就不是太好,只可以处理一些固定的、简单的查询,幸好,hibernate还支持一种HQL查询,这才没有彻底的把它自己封死。
hibernate的HQL查询作为hibernate的扩展功能,它在支持像类似于以往普通sql查询的基础上,又对语句结构进行了一些封装和优化,其中的HQL动态输入就是一个很好的例子。
话不多说,直接上例子:
public static void testTwo(){
String HQL = "select a.usrName ,a.password from User a where a.id not in (:data0) and (a.usrName not in (:data20))";
List<String> list = new ArrayList<String>();
list.add("Boss");
list.add("admin");
List<String> list1 = new ArrayList<String>();
list1.add("Boss");
List<String> list3 = new ArrayList<String>();
list3.add("Boss");
list3.add("admin");
Session session = HibernateUtil.getSession();
Query queryObject = session.createQuery(HQL);
queryObject.setParameterList("data0", list);
queryObject.setParameterList("data20", list3);
List<Object []> objects = queryObject.list();
for(Object [] objects2 :objects){
for(Object object : objects2){
System.out.print(object+"\t");
}
System.out.println();
}
}
上述代码中执行效果就是,针对一个可以任意嵌套的HQL语句,通过外界数据的动态输入来达到类似于sql的动态输入的效果。
需要注意的是,这种HQL语句本身有一个特点,就是HQL语句中的占位符的写法,通常有两种写法:
一种写法不带括号,比如 :data0
另一种写法带括号,比如 (:data0)
这两种写法有什么特点呢?
通常来说当HQL语句没有嵌套时,可以使用第一种写法;
当HQL语句里面需要有很多复杂性的嵌套时,大伙儿请注意,千万不要使用不带括号的那种,如果你写了,不好意思,控制台给你报的错误会让你上火的,你都不知道错哪里了。
HQL中的占位符可以使用那些类型的数据来填充呢?
通常来说,可以是list集合,可以是数组,可以是map集合。前提是使用上面的占位符的形式。如果你使用的占位符是 “?”,那么你就不可以使用本博客中的,因为如果使用"?"作为占位符的话,注入的方式是不同的,还请大家注意。
其实hibernate不提倡我们用“?”这样的方式的占位符,而是建议用JPA或者命名参数的占位符,即本博客中使用的占位符方式。