Hibernate 备忘
1. 概述
HQL查询依赖于Query类,每一个Query实例对应一个查询对象.
使用HQL查询按如下步骤进行:
(1) 获取Hibernate Session对象
(2) 编写HQL语句
(3) 以HQL语句作为参数,调用createQuery方法创建查询对象
(4) 如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值
(5) 调用Query对象的list()或uniqueResult()方法返回查询结果列表.
2. From 子句
From 后面跟的是持久化类名.类名可以 跟一个 as 然后跟 持久化类的实例.
比如 select p from Person as p;
3. Select 子句
(1) select可以跟 持久化实例,或者实例的属性.如
select p,p.name.firstName from Person p; 表示select 出来的list元素是数组
数组结构类似于[Person实例,String类型的first name]
(2) select new list(p.name,p.address) from Person as p,select出来的list的元素还是list.
(3) 可以将select的实例直接封装成对象
select new ClassTest(p.name,p.address) from Person as p
前提是 ClassTest(p.name,p.address) 要存在这个类型的构造器
这个select出来的是ClassTest实例的集合
(4) select 还支持给选中的表达式 命名
select p.name as personName from Person as p.
与map结合
select new map(p.name as personName) from Person as p
select出来的list元素为map,map以personName为key,p.name的实际值为value
public static void main(String[] args)
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select new map(p.name as personName) from Person as p");
java.util.List list = query.list();
for(Iterator iterator=list.iterator();iterator.hasNext(); )
{
Map map = (Map) iterator.next();
System.out.println(map);
}
tx.commit();
HibernateUtil.closeSession();
}
上面代码输出:
{personName=yeeku}
{personName=老朱}
注:Person表里面数据为:
INSERT INTO person_inf VALUES
(1,'yeeku',30),
(2,'老朱',30);
4. 多态查询
from aInterface as n 表示把实现了aInterface接口的所有持久化类的实例全查出来.(P483)
5. where 子句
from Person where name like "tom%" --
与下面的效果相同
from Person person where person.name like "tom%"
6. 命名查询
将HQL配置到映射文件中
<hibernate-mapping>中使用<query>
<!-- 定义命名查询 -->
<query name="myNamedQuery">
<!-- 这里配置命名查询的HQL语句 -->
from Person person where p.age > ?
</query>
在代码中使用session的getNamedQuery("myNamedQuery");来获取Query对象.
7. 使用原生SQL查询
标量查询 和 实体查询 (P497-498)
标量查询:
//执行标量查询
public void scalarQuery()
{
//打开Session和事务
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
String sqlString = "select stu.* from student_inf as stu";
List l = session.createSQLQuery(sqlString)
//指定查询name和student_id两个数据列
.addScalar("name" , StandardBasicTypes.STRING)
.addScalar("student_id" , StandardBasicTypes.INTEGER)
//返回标量值列表
.list();
for (Iterator it = l.iterator(); it.hasNext() ; )
{
//每个集合元素都是一个数组,数组元素是name、student_id两列值
Object[] row = (Object[])it.next();
System.out.println(row[0] + "\t" + row[1]);
}
tx.commit();
HibernateUtil.closeSession();
}
addEntity(String alias,Class entityClass);
setResultTransformer();//将查询结果映射成普通的bean
Hibernate还可以将查询的结构转换成非持久化实体(即普通的JavaBean),只要该JavaBean
为数据列提供了getter和setter方法.
将实体的关联实体(通常是属性)转换成查询结果.
使用addJoin(Strig alias,String path).(P500)
同时将主表和从表数据都查出来
8. 使用定制SQL,改变Hibernate产生底层sql的方式.可以配置成存储过程.
这样Hibernate在增删改时使用存储过程.(P504)
9. 使用命名SQL可实现定制装载(P505)
10. 使用过滤器(P506)
(1) 在映射文件中配置,在<hibernate-mapping>标签中配置<filter-def>
(2) 在<class>标签中配置<filter name="filter-def">以便启用通过
<filter-def>定义的过滤器.也可作为<list>,<set>,<map>的子元素使用
(3) 在session上调用方法enableFilter("filter-def").setParameter("paraName",value);
一旦设置了过滤,则不管数据查询,还是数据加载,该过滤器都将起作用.
启用过滤器后,过滤器在整个session范围内有效,知道调用disableFilter方法.
<!-- 下面定义2个Filter,这里定义过滤器的名称,已经参数情况(几个参数,参数什么类型?) -->
<filter-def name="effectiveDate">
<filter-param name="asOfDate" type="date"/>
</filter-def>
<filter-def name="category">
<filter-param name="catId" type="long"/>
</filter-def>
在一个xml映射文件中定义的过滤器可以在其他映射xml文件中使用(前提是这些xml文件由同一个sessionFactory加载并管理).
<!-- 对Category应用数据过滤,class标签的子标签 这里condition中只有一个参数,类型是data,由上面的 filter-def name="category" 来定义-->
<filter name="effectiveDate" condition=":asOfDate BETWEEN eff_start_date and eff_end_date"/>
11. 上下文相关的session
配置:
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.current_session_context_class">jta</property>