Hibernate 检索策略
1. 类级别检索策略
1.1 立即检索
1.2 延迟检索
2. 一对多和多对多关联的检索策略
2.1 批量延迟和批量立即检索
2.1 迫切左外连接检索
3.多对一和一对多关联的检索策略。
3.1 迫切左外连接检索
3.2延迟检索
3.3立即检索
3.4批量延迟检索和批量立即检索
类级别检索策略
类级别可选的检索策略包括立即检索和延迟检索,默认为立即检索 . 如果<class>元素的 lazy 属性为 true ,标识采用延迟检索; 如果lazy 属性为 false ,表示采用立即检索. Lazy 属性的默认值为 false.
以下示例演示了 lazy = true 和 lazy = false 的区别
<class name="com.test.pojo.Person" table="person" schema="dbo" catalog="studyHibernate" lazy="false">
Person person = (Person)session.load(Person.class, new Integer(47));
以上代码立即检索. 执行 select 查询语句.
更改: lazy="true"
当执行: person.getPersonName(); 时才执行 select 语句.
不管 Session 的get() 方法和 createQuery() 方法在类级别中总是使用立即检索.
一对多和多对多关联的检索策略.
在映射文件中,用<set>元素来配置一对多关联以及多对多关联关系.
<set> 元素有 lazy 和 outer-join 属性
一对多关联默认的检索策略为立即检索.
对于 <set> 元素应该优先考虑使用延迟检索策略.
<set name = “adds” inverse=”true” lazy=”true”>
以下代码演示了<set>元素中的 lazy 属性的用法.
Person person = (Person)session.load(Person.class, new Integer(47));
person.getPersonName();
// Iterator ite = person.getAdds().iterator();
<set name="adds" cascade="all" lazy="true" >
<key column="personId"/>
<one-to-many class="com.test.pojo.Adds"/>
</set>
如果把 lazy = “true” 时表示延时检索 只执行一条 SQL语句
如果把 lazy = “false” 时表示立即检索 ,执行两条 SQL语句
批量延迟检索和批量立即检索
<set> 元素有一个 batch-size 属性,用于为延迟检索或立即检索策略设定批量检索的数据.批量检索能减少 select 语句的数目,提高延迟检索或者立即检索的性能.
以下代码检索所有的 person 对象(以下代码属于批量立即检索.):
<set name="adds" cascade="all" lazy="false" batch-size="6" >
List list = session.createQuery
("from Person as person").list();
Iterator ite = list.iterator();
以下代码实现批量延迟检索:
<set name="adds" cascade="all" lazy="true" batch-size="6" >
List list = session.createQuery
("from Person as person").list();
Iterator ite = list.iterator();
while(ite.hasNext()){
Person person = (Person)ite.next();
Iterator ite1 = person.getAdds().iterator();
while(ite1.hasNext()){
Adds adds = (Adds)ite1.next();
System.out.println(adds.getAddName());
}
}
多对一和一对多关联的检索策略
在映射文件中,<many-to-one>及<one-to-one> 元素分别用来设置多对以和一对一关联关系.
<many-to-one name=”” column=”” class=””/>
<many-to-one> 元素的 outer-join属性有三个可选值得:
1. auto:默认值,如果 person.hbm.xml 的<class>元素的 lazy 属性为 true,那么对与 Adds 关联的 Person 对象采用延迟检索策略;否则采用迫切左外连接检索策略.
2.
以下代码演示立即检索
<class name="com.test.pojo.Person" table="person" schema="dbo" catalog="studyHibernate" lazy="false">
<many-to-one name="person" column="personId" class="com.test.pojo.Person" outer-join="false"/>
Adds adds = (Adds)session.get(Adds.class, new Integer(43));
Person person = adds.getPerson();
如果把 class 的 lazy 属性值改为:lazy = “true” 为延迟检索.
<class name="com.test.pojo.Person" table="person" schema="dbo" catalog="studyHibernate" lazy="false">
以下代码批量延迟检索:
<class name="com.test.pojo.Person" table="person" schema="dbo" catalog="studyHibernate" lazy="true" batch-size="3">
// lazy="false" 批量立即检索
<many-to-one name="person" column="personId" class="com.test.pojo.Person" outer-join="false"/>
List list = session.createQuery("from Adds a").list();
for(int i=0;i<list.size();i++){
Adds adds = (Adds)list.get(i);
Person person = adds.getPerson();
person.getPersonName();
}
Hql查询方式:
以下代码通过查询条件显示数据:
List list = session.createQuery(
"from Person p where p.personName = :personName")
.setString("personName", "scott").list();
Hql 的 like 查询
List list = session.createQuery(
"from Person p where p.personName like :personName ")
.setString("personName", "%a%").list();
查询指定范围值:
List list = session.createQuery("from Person p where p.id > :pid and p.id < :nid")
.setInteger("pid", new Integer(60))
.setInteger("nid",new Integer(70))
.list();
for(int i=0;i<list.size();i++){
Person person = (Person)list.get(i);
System.out.println("--- id ="+person.getPersonid());
System.out.println("--- name="+person.getPersonName());
}
在映射文件中定义命名查询语句
Person.hbm.xml 定义如下:
<query name="findPersonByname">
<![CDATA[ from Person p where p.personName like :name]]>
</query>
程序代码如下:
List list = session.getNamedQuery("findPersonByname")
.setString("name","%a%").list();
Hql 翻页查询:
setFirstResult(int firsResult):设定从哪个对象开始检索,参数表示这个对象在查询结果中的索引位置,索引起始值为 0.
setmaxResult(int maxResult):设定一次最多检索出的对象数目.
以下示例演示了翻页操作 :
List list = session.createQuery("from Person p").setFirstResult(5)
.setMaxResults(5).list();
HQL 投影查询:
投影查询是指查询结果仅包括部分实体或者实体的部分属性. 投影是通过 select 关键字来实现的.
Hql 投影查询中使用 聚合函数:
Query query = session
.createQuery(
"select max(id) as max,min(id) as min ,sum(id) as sum ,personName from Person group by personName order by personName desc");
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Object[] object = (Object[]) list.get(i);
Integer maxid = (Integer) object[0];
Integer minid = (Integer) object[1];
Integer sumid = (Integer) object[2];
String personName = (String)object[3];
System.out.println("----- maxid =" + maxid);
System.out.println("----- minid =" + minid);
System.out.println("----- sumid=" + sumid);
System.out.println("----- personName ="+personName);
}
也可以返回类实例:
Query query = session.createQuery("select new com.test.pojo.MyPerson(p.personid,p.personName,p.email) from Person p where p.personName like :personName")
.setString("personName", "%a%");
List list = query.list();
Iterator ite = list.iterator();
while(ite.hasNext()){
MyPerson myperson = (MyPerson)ite.next();
}
在运行 session.load()方法时,Hibernate 不会执行任何select 语句,仅仅返回 Customer 类的代理类实例,它的OID 为:100 ,由 load() 方法的第二个参数决定,当程序调用 customer.getName() 方法时,Hibernate 会初始化 Customer 代理类实例。
Session session = HibernateSessionFactory.getSession();
Transaction transaction = session.beginTransaction();
Employee employee =
(Employee) session.load(Employee.class, new Integer(100));
System.out.println("--- employee id ="+employee.getId());
Employee.getName();
transaction.commit();
session.close();
以下代码试图在关闭session 后访问 Customer 游离对象。
Session session = HibernateSessionFactory.getSession();
Transaction transaction = session.beginTransaction();
Employee employee =
(Employee) session.load(Employee.class, new Integer(40));
transaction.commit();
session.close();
System.out.println("---- employee name ="+employee.getName());
以上代码在Session 范围内始终没有被初始化,在执行employee.getName() 时会抛出异常。必须在 session 范围内要初始化对象。
Transaction transaction = session.beginTransaction();
Employee employee =
(Employee) session.load(Employee.class, new Integer(40));
if(!Hibernate.isInitialized(employee)){
Hibernate.initialize(employee);
}
transaction.commit();
session.close();
当应用程序访问代理类实例的 getId() 方法时,不会触发 Hibernate 初始化代理类实例的行为。
Transaction transaction = session.beginTransaction();
Employee employee =
(Employee) session.load(Employee.class, new Integer(40));
Employee.getId();
transaction.commit();
session.close();
不管 xml文件中的<class>元素的 lazy 属性是 true 还是 false, session 的get()方法总是使用立即检索策略.
批量延迟检索:
例如:
<set name=” ” inverse=”true” lazy = “true” bach-size=5>
批量立即检索:
例如:
<set name=” ” inverse=”true” bach-size=5>