}
测试代码二:
Session session = HibernateSessionFactory.getSession(); Transaction ta = session.beginTransaction(); Userinfo userinfo = session.createCriteria(Userinfo.class) .add(Expression.eq("userinfoName", name)).add( Expression.eq("userinfoPassword", pwd)).uniqueResult(); ta.commit(); HibernateSessionFactory.closeSession(); return userinfo;}
过滤器在网站xml中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<!-- 过滤器 -->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>cn.happy.filter.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
index.jsp页面的代码:
<body>
<%
HibernateBiz biz=new HibernateBiz();
Emp emp=(Emp)biz.get(Emp.class,1);
%>
<%=emp.getEmpName() %>
</body>
这个代码只是一个例子而已,你可以写别样的代码。这样就算完成了Open
Session In View 模式。
再总结一遍:
关于No Session的这个问题,有了六种的解决方案:
方案一
在biz层 把load 改成get
方案二
/* if (!Hibernate.isInitialized(obj)) {
Hibernate.initialize(obj);
}*/
方案 三 :在 映射文件中 ,类级别 <set> 中加上 lazy =“false”
方案四: 在biz 层 先用一道 需要的UI使用 到的属性 ,然后在biz关闭
方案五:把实体类 改成 用 final 修饰,我们知道,延迟加载的原因是 内存中
有代理对象 (其实是emp 类的子类),所以当我们设为 该类 不能 有子类
方案六:Open Session In View 模式。
在上面都已经用代码做例子了,够清楚了的。
好久没有认真写过博客了,今天就好好的写一篇吧!!!!!!!!! 当
H…
System.out.println(“id:”+category.getId()+”
,name:”+category.getName()+”,
description:”+category.getDescription());
输出的是id,name和description属性值,其他的我们不管,所以Hibernate用了lazy
loading(延迟加载),带来的好处就是我们不关心的
[b]问题补充:[/b]
Caused by: java.sql.SQLException: 关闭的连接
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at
oracle.jdbc.driver.OracleConnection.privatePrepareStatement(OracleConnection.java:895)
at
oracle.jdbc.driver.OracleConnection.prepareStatement(OracleConnection.java:802)
at
org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:396)
at
org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:334)
at
org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:88)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1162)
at org.hibernate.loader.Loader.doQuery(Loader.java:390)
at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.doList(Loader.java:1593)
… 122 more
HibernateUtil代码
private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();
//私有的静态的配置对象
private static Configuration configuration;
//私有的静态的工厂对象
private final static SessionFactory sessionFactory;
//静态代码块,负责给成员变量赋值
static{
configuration=new Configuration().configure();
sessionFactory=configuration.buildSessionFactory();
}
//从SessionFactory 连接池 获取一个和当前thread bind session
public static Session currentSession(){
//2.返回当前的线程其对应的线程内部变量
//sessionTL的get()方法根据当前线程返回其对应的线程内部变量,
//也就是我们需要的Session,多线程情况下共享数据库连接是不安全的。
//ThreadLocal保证了每个线程都有自己的Session.
Session session=sessionTL.get();
//如果当前线程是session 为空=null ,则打开一个新的Session
if(session==null){
//创建一个session对象
session=sessionFactory.openSession();
//保存该Sessioon对象到ThreadLocal中
sessionTL.set(session);
}
return session;
}
//关闭Session
public static void closeSessio(){
Session session=sessionTL.get();
sessionTL.set(null);
session.close();
}
//dept.getEmp()得到子表的记录集合
System.out.println(dept.getEmp());
这是我们不希望看到的结果。
/**
biz层代码:
HibernateDao dao=new HibernateDao();
public Object get(Class clazz,Serializable id){
Object obj= dao.get(clazz, id);return obj;
}
Exception in thread “main” org.hibernate.LazyInitializationException:
failed to lazily initialize a collection of role:
com.javakc.hibernate.onetomany.entity.DeptEntity.emp, could not
initialize proxy – no Session
at
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at
org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:326)
at java.lang.String.valueOf(String.java:2827)
at java.io.PrintStream.println(PrintStream.java:771)
at
com.javakc.hibernate.onetomany.action.TestAction.main(TestAction.java:74)
代码:
dao是
public Userinfo checkUserinfo(String name, String pwd) {
Hibernnate延迟加载策略(这么详细你还看不懂),hibernnate延迟
好久没有认真写过博客了,今天就好好的写一篇吧!!!!!!!!!
当Hibernate
从数据库中加载某个对象(例如:Dept对象)时,如果同时自动加载所有的关联的某个对象(例如:Emp对象),而程序实际上仅仅需要访问Dept对象,那么这些关联的Emp对象就白白浪费了许多内存空间。发生这种情况的原因是:就是立即加载的问题。
1.什么是立即加载呢?
Hibernate 查询 Dept
对象时,立即加载并加载与之关联的Emp对象,这种查询策略称为 立即加载。
立即加载存在两大不足:
1.select 语句的数目太多,需要频繁地访问数据库,会影响查询性能。
2.在应用程序只需要访问Dept对象时,而不需要访问Emp对象的场合,加载Emp对象完全是多余的操作,这些多余的Emp对象就白白的浪费了许多内存空间。
那么我们必须要解决这个问题,所以就要谈到了“延迟加载”的知识了,延迟加载策略能避免加载应用程序不需要访问的关联对象,以优化查询性能。
不过我们要知道有多种查询策略,接下来我们就一起来分析每一种查询策略的加载问题。
第一种:类级别的查询策略
类级别可选的加载策略包括立即加载和延迟加载,默认是延迟加载,如果,<class>元素的lazy的属性为true,表示采用延迟加载;如果lazy
属性 为 false,表示采用立即加载。
我们现在以代码来解释是最好的办法。
1.立即加载策略
我们在Dept.hbm.xml文件中 加 lazy=“false” 属性,即可。
表结构:
测试代码:
Session session = HibernateUtil.currentSession();
session.beginTransaction();
Dept dept = (Dept)session.load(Dept.class, 1);
System.out.println("部门名称"+dept.getdName());
System.out.println("===================");
Dept dept2 = (Dept)session.load(Dept.class, 1);
System.out.println("部门名称"+dept2.getdName());
session.getTransaction().commit();
HibernateUtil.closeSessio();
测试结果:
我们知道使用Load方法加载的是代理对象,只会在属性里保存一个OID,但是如果在Dept映射文件中配置了类级别的lazy为false就代表加载该对象时立即加载,也就是立即检索一次数据库,发出了一条sql语句。
2.延迟加载
类级别的默认加载策略就是延迟加载。在在Dept.hbm.xml文件中
,以下两种方式都表示延迟加载策略。
或是
如果程序加载一个持久化对象的目的是为了访问它的属性,这是我们可以采用立即加载,但是如果程序加载一个持久化对象的目的是为了获得它的引用,这是我们可以采用延迟加载,无须访问Dept对象的属性。
看例子:
Dept dept = (Dept)session.load(Dept.class, 1);
System.out.println("部门名称"+dept.getdName());
Employee emp=new Employee();
emp.setEname("李四");
emp.setDept(dept);
session.save(emp);
这段代码向数据库保存了 一个Employee
对象,它与已经存在的一个Dept持久化对象关联。如果在Dept 类级别
采用延迟加载,则 session.load()方法不会执行访问DEPT 表的select
语句,只返回一个Dept的代理对象,它的deptNo的属性值为1,其余属性都为NULL。session.save()方法执行的sql语句:
所以当,<class>元素的lazy属性为true时,会影响session.load()方法的各种运行时行为。举例说明:
1.如果加载的Dept对象在数据库中不存在时,不会抛出异常,只有运行dept.getxxx()时,才会抛出异常。
测试代码:
Session session = HibernateUtil.currentSession();
session.beginTransaction();
Dept dept = (Dept)session.load(Dept.class, 3);
System.out.println("部门名称"+dept.getdName());
Employee emp=new Employee();
emp.setEname("李四");
emp.setDept(dept);
session.save(emp);
当 deptNo为3不存在时,会抛出以下异常:
2.如果在在整个Session范围内,应用程序没有访问过的Dept对象,那么Dept代理类的实例一直不会被初始化,Hibernater
不会执行任何的select语句。以下代码试图在关闭Session后访问的Dept游离对象:
测试代码:
Session session = HibernateUtil.currentSession();
session.beginTransaction();
Dept dept = (Dept)session.load(Dept.class, 3);
HibernateUtil.closeSessio();
System.out.println("部门名称"+dept.getdName());
session.getTransaction().commit();
HibernateUtil.closeSessio();
从代码中我们可以看出,session被提前关闭,所以dept引用的Dept代理类的实例在Session范围内始终没有被初始化,所以当执行到
System.out.println(“部门名称”+dept.getdName())时,会抛出以下异常:
由此可见,Dept代理类的实例只有在当前的Session范围内才能被初始化。
3.import
org.hibernate.Initialized()静态方法,用于在Session范围内显式初始化代理类实例,isInitialized()方法用于判断代理类实例是否已经被初始化。
代码:
Dept dept = (Dept)session.load(Dept.class, 1);
if(!Hibernate.isInitialized(dept)){
Hibernate.initialize(dept);
HibernateUtil.closeSessio();
System.out.println("部门名称"+dept.getdName());
}
以上代码在Session范围内通过Hibernate
类的Initialized()方法显式初始化了Dept代理类实例,因此关闭Session关闭后,可以正常访问Dept的游离对象。
4.当程序访问代理类实例的getDeptNo()方法时,不会触发Hibernate 初始化
代理类实例的行为。例如:
代码:
Dept dept = (Dept)session.load(Dept.class, 1);
System.out.println("编号:"+ dept.getDeptNo());
HibernateUtil.closeSessio();
System.out.println("部门名称"+dept.getdName());
当程序访问dept.getDeptNo()方法时,该方法直接返回Dept代理类的实例OID值,无须查询数据库。由于变量dept始终引用的是没有初始化的Dept代理类的实例,因此当Session关闭后再执行dept.getdName()方法,会抛出以下异常。
但是值得我们注意的是:不管Dept.hbm.xml文件的<class>元素的属性是true还是false,Session
的get方法及Query对象的list方法在Dept类级别总是使用立即加载策略。举例说明:
1.Session的get方法总是立即到数据库中查询Dept查询对象,如果在数据库中不存在相应的数据,就会返回NULL,例如:
代码:
Session session = HibernateUtil.currentSession();
session.beginTransaction();
Dept dept = (Dept)session.get(Dept.class, 3);
System.out.println(dept);
结果:
由此可知,get方法永远不会执行Dept的代理类实例。
2.Query的list方法总是立即到数据库中查询Dept对象
代码:
List<Dept> query = session.createQuery("from Dept").list();
for (Dept dept : query) {
System.out.println(dept.getdName());
}
结果:
到了这里,算是把第一种类级别的查询策略写的差不多了。
第二种:一对多和多对一关联的查询策略
添加一个小知识点:
01.一对多或者多对多检索策略由lazy和fetch共同确定
02.fetch取值
Join:迫切 Lazy:决定关联对象初始化时机
左外连接
Select:多条简单SQL(默认值)
Subselect:子查询
03.fetch和lazy组合
云顶娱乐平台:Hibernate延迟加载 lazy loading。 解析:fetch=”join” lazy会被忽略,迫切左外连接的立即检索
Fetch=”s Fetch:决定SQL语句构建形式
elect” lazy=”false” 多条简单SQL立即检索
Fetch=”select” lazy=”true” 多条语句延迟检索
Fetch=”select” lazy=”extra” 多条语句及其懒惰检索
Fetch=”subselect” lazy=”false” 子查询立即检索
Fetch=”subselect” lazy=”true” 子查询延迟检索
Fetch=”subselect” lazy=”extra” 子查询及其懒惰检索
Extra:及其懒惰,只有访问集合对象的属性时才会加载,访问集合本身的属性时(例如,集合大小,生成count),不会立即加载。
注意:query的list()会忽略映射文件配置的左外连接查询,fetch,此时lazy属性重新生效。
在映射文件中,用<SET>元素来配置一对多关联及多对一关联关系的加载策略。Dept.hbm.xml文件中的一下代码用于配置Dept和Employee类的一对多关联关系:
<!-- 双向 cascade:级联 inverse:反转 -->
<!--set表明Dept类的emps属性为set集合类型 -->
<!--order-by 对集合排序 order-by="dName asc order-by="dName desc-->
<set name="emps" inverse="true" lazy="true">
<!--employee表的外键 deptNo -->
<key column="deptNo"></key>
<!--一对多 class 属性设定与所关联的持久化类 为employee -->
<one-to-many class="Employee"/>
</set>
这里的<set>元素有lazy属性,主要取决于emps集合被初始化的时机,到底是在加载Dept对象时就被初始化,还是在程序访问emps集合时被初始化。
1.立即加载
Dept.hbm.xml的配置文件:
测试代码:
Dept dept = (Dept)session.get(Dept.class, 1);
System.out.println(dept.getdName());
结果:执行Session的get方法时,对于Dept对象采用类级别的立即加载策略,对于Dept对象的emps集合(Dept关联所有的employee对象),采用一对多关联的立即加载策略。
从这个结果我们可以看到,Hibernate加载了一个Dept对象和Employee对象,但是我们知道很多情况下,不需要访问Employee对象,所以我们就得用了
延迟加载策略。
2.延迟加载
对于<set>元素,应该优先考虑使用的默认延迟加载策略。
测试代码:
Dept dept = (Dept)session.get(Dept.class, 1);
System.out.println(dept.getdName());
结果:
很明显,只执行了一条sql语句,即仅仅加载了Dept对象。
Session的get方法,返回的是Dept对象的emps属性引用一个没有被初始化的集合代理类实例。换句话说,此时的emps集合中没有存放任何Emp对象,只有emps集合代理类实例被初始化时,才回到数据库查询所有与Dept关联的Emp对象。
测试代码:
Dept dept = (Dept)session.get(Dept.class, 1);
System.out.println(dept.getdName());
for (Employee emp : dept.getEmps()) {
System.out.println(emp.getEname());
}
结果:
那么,Dept对象的emps属性引用的集合代理类实例何时被初始化呢?主要包括以下两种情况:
01.当应用程序第一次访问它时,如调用
iterator(),size(),isEmpty(),或是 contains()方法时:
代码:
Dept dept = (Dept)session.get(Dept.class, 1);
Set<Employee> emp=dept.getEmps();
System.out.println(dept.getdName());
Iterator<Employee> itee=emp.iterator();//emps被初始化
02.通过hibernate的静态方法initialize()来初始化它。
Dept dept = (Dept)session.get(Dept.class, 1);
Set<Employee> emp=dept.getEmps();
System.out.println(dept.getdName());
Hibernate.initialize(emp);//emps被初始化
3.增强延迟加载
lazy=”extra”
配置如下:
增强延迟加载策略能进一步延迟Dept对象的emps集合代理类实例初始化时机。当应用程序第一次访问emps属性的iterator()时,会导致emps集合代理类的实例初始化。但是当当应用程序第一次size(),isEmpty(),或是
contains()方法时,emps不会初始化emps集合代理实例。仅仅通过查询select语句必要信息。
测试代码:
Dept dept = (Dept)session.get(Dept.class, 1);
//不会初始化emps集合代理类实例
int size = dept.getEmps().size();
System.out.println(size);
//会初始化emps集合代理类实例
Iterator<Employee> iterator = dept.getEmps().iterator();
System.out.println(iterator);
结果:
现在是第三种:多对一关联的查询策略
lazy=proxy
Employee.hbm.xml中但我配置:
1.延迟加载策略。
测试代码:
Employee em=(Employee) session.get(Employee.class, 21);//仅仅执行em对象的sql语句
Dept dept = em.getDept();
System.out.println(dept.getdName());//执行Dept对象
当Sesson执行get()方法时,仅仅立即执行查询Employee对象的select语句。当Employee
对象引用Dept代理类实例,这个代理类实例的IOD由Employee
表的DeptNo外键值决定。 当执行dept.getdName()时,hibernate
初始化Dept代理类实例,执行以下select语句到数据库中加载Dept对象。
结果:
无代理延迟加载:
lazy=”no-proxy”
测试代码:
Employee em=(Employee) session.get(Employee.class, 21);//仅仅执行em对象的sql语句
Dept dept = em.getDept();
System.out.println(dept.getdName());//执行Dept对象
如果Employee对象的dept属性使用无代理延迟加载,即<many-to-many>元素的lazy属性为no-proxy,当执行
get方法时,加载的Employee的dept属性为NULL,当执行到 em.getDept()时,将触发hibernate执行查询Dept
表的select 语句,从而加载Dept对象。
结果:
由此可见,当lazy为proxy 时,可以延长延迟加载
Dept对象的时间,而当lazy属性为no-proxy时,则可以避免使用由hibernate
提供的Dept代理类实例,使用hibernate 对程序 提供更加透明的持久化服务。
立即加载:
lazy=“false”
测试:
Employee em=(Employee) session.get(Employee.class, 21);
结果:
可以看到,执行了两条sql语句。
Open Session In View 模式9
Open Session In View 模式的作用:
Hibernate
允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个
Hibernate Session 范围之内进行。如果 Service
层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web
层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session
已经关闭,这些导致延迟加载数据的访问异常。
在Java Web 应用中,通常需要调用ibernate API
获取到显示的某个要显示的某个对象并传给相应但的视图JSP,
并在JSP中从这个对象导航到与之关联的对象或集合数据。这些关联对象或集合数据如果是被延迟加载的,hibernate
就会抛出以下异常:
这是因为在调用完hibernate完之后,Session
对象已经关闭了。针对这个问题,hibernate 社区提供了Open Session In View
模式 的解决方案!!
代码示例:
HIbernateTest.java
[b]问题补充:[/b]
package com.shop.hibernate.util;
dao层代码:
public Object get(Class clazz,Serializable id){
Object result= HibernateUtils.currentSession().load(clazz, id);
return result;
}
filter层代码:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.currentSession();
System.out.println("filtert"+session.hashCode());
tx = session.beginTransaction();
// 执行请求处理链 双向过滤
chain.doFilter(request, response);
// 返回响应时,提交事务
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
tx.rollback();
} finally {
// 关闭session
HibernateUtils.closeSession();
}
}
public static void main(String[] args) {
DeptEntity dept = getDept(“402882e762ae888d0162ae888e420000”);
import java.util.Set;
SQL Error: 17008, SQLState: null
每次程序运行一段时间以后,就报此错
08-08-17 09:55:29 WARN JDBCExceptionReporter:71 – SQL Error: 17008,
SQLState: null
08-08-17 09:55:29 ERROR JDBCExceptionReporter:72 – 关闭的连接
08-08-17 09:55:29 WARN JDBCExceptionReporter:71 – SQL Error: 17008,
SQLState: null
08-08-17 09:55:29 ERROR JDBCExceptionReporter:72 – 关闭的连接
org.hibernate.exception.GenericJDBCException: could not execute query
Caused by: java.sql.SQLException: 关闭的连接
集合延迟加载初始化失败,不能初始化一个代理。就是集合在非一对一对象关系中,为了节省资源是默认延迟加载,而get方法又是非延迟加载,所以在执行完一次数据库查询后就执行session.close();关闭了session,而集合是延迟加载,在使用集合时再加载,此时session已经关闭,所以得不到代理。解决方法:可以在主表的hbm配置文件中,在<set>标签里设置lazy=”false”,集合就不延迟加载了,因此在执行get方法时,集合也获取到了,就不会出现延迟加载问题了。
一般情况下,Hibernate会默认给我们设置延迟加载。lazy=”true”
,这样会提升我们的系统性能,所以一般情况下,我们不会去
}
运行结果:
HibernateTest.java
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
private static DeptEntity getDept(String did){
Session session = sessionFactory.openSession();
DeptEntity dept = (DeptEntity)session.get(DeptEntity.class, did);
session.close();
return dept;
}
第二条select语句,对于我们的需求是没有必要的,他只有一个用处就是占用我们的程序执行时间。当然,
这是自动生成的
设置lazy=”false”,当然在特殊的情况下,我们必须要取消延迟加载的时候,我们就把lazy=”false”,就可以了
我的的struts2 +hibernate3
log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name1_0_,
category0_.description as descript3_1_0_
from
users.category category0_
where
category0_.id=?
Hibernate:
select
products0_.category_id as category2_1_,
products0_.id as id1_,
products0_.id as id0_0_,
products0_.category_id as category2_0_0_,
products0_.name as name0_0_,
products0_.price as price0_0_,
products0_.descripton as descripton0_0_
from
users.product products0_
where
products0_.category_id=?
id:1 ,name:java, description:java好啊
和测试代码一的运行结果相互比较,我们会发现,这次运行结果用了两条select语句。但是我们会发现
- Configures and provides access to Hibernate sessions, tied to the
- current thread of execution. Follows the Thread Local Session
-
pattern, see {@link }.
*/
public class HibernateSessionFactory {/**
- Location of hibernate.cfg.xml file.
- Location should be on the classpath as Hibernate uses
- #resourceAsStream style lookup for its configuration file.
- The default classpath location of the hibernate config file is
- in the default package. Use #setConfigFile() to update
- the location of the configuration file for the current
session.
*/private static String CONFIG_FILE_LOCATION =
“/hibernate.cfg.xml”;private static final ThreadLocal
threadLocal = new ThreadLocal();private static Configuration
configuration = new Configuration();private static
org.hibernate.SessionFactory sessionFactory;private static
String configFile = CONFIG_FILE_LOCATION;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println(“%%%% Error Creating SessionFactory %%%%”);
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}/**
- Returns the ThreadLocal Session instance. Lazy initialize
- the
SessionFactory
if needed.* - @return Session
-
@throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();if (session == null || !session.isOpen {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ?
sessionFactory.openSession()
: null;
threadLocal.set;
}return session;
}
/**
- Rebuild hibernate session factory**/public static void
rebuildSessionFactory() {try {
configuration.configure(configFile); sessionFactory =
configuration.buildSessionFactory();} catch (Exception e) {
System.err .println(“%%%% Error Creating SessionFactory %%%%”);
e.printStackTrace();}}
/**
- Close the single hibernate session instance.*
-
@throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = threadLocal.get();
threadLocal.set;if (session != null) {
session.close();
}
}
/**
- return session factory**/public static
org.hibernate.SessionFactory getSessionFactory() {return
sessionFactory;}
/**
- return session factory*
- session factory will be rebuilded in the next call*/public
static void setConfigFile(String configFile)
{HibernateSessionFactory.configFile = configFile;sessionFactory
= null;}
/**
- return hibernate configuration**/public static Configuration
getConfiguration() {return configuration;}
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping
DTD 3.0//EN”
“”>
<!–
Mapping file autogenerated by MyEclipse Persistence Tools
–>
<hibernate-mapping>
<class name=”com.b510.examples.Category” table=”category”
catalog=”users”>
<id name=”id” type=”java.lang.Integer”>
<column name=”id” />
<generator class=”increment” />
</id>
<property name=”name” type=”java.lang.String”>
<column name=”name” length=”500″ />
</property>
<property name=”description” type=”java.lang.String”>
<column name=”description” length=”500″ />
</property>
<set name=”products” inverse=”true” lazy=”false”>
<key>
<column name=”category_id” />
</key>
<one-to-many class=”com.b510.examples.Product” />
</set>
</class>
</hibernate-mapping>
log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name1_0_,
category0_.description as descript3_1_0_
from
users.category category0_
where
category0_.id=?
id:1 ,name:java, description:java好啊
Hibernate:
select
products0_.category_id as
category2_1_,
products0_.id as id1_,
products0_.id as
id0_0_,
products0_.category_id as
category2_0_0_,
products0_.name as
name0_0_,
products0_.price as
price0_0_,
products0_.descripton as
descripton0_0_
from
users.product products0_
/**
*
* @author XHW
*
* @date 2011-7-18
*
*/
public class HibernateTest {
public static void main(String[] args) {
new HibernateTest().update();
}
public void update(){
Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Category
category=(Category)session.get(Category.class, 1);
System.out.println(“id:”+category.getId()+”
,name:”+category.getName()+”,
description:”+category.getDescription());
Set<Product>
products=category.getProducts();
session.getTransaction().commit();
}
}
/**
*
*/
package com.b510.examples;
代码:
/**
*
*/
package com.b510.examples;
import org.hibernate.Session;
/**
*
*/
package com.b510.examples;
Category.hbm.xml
import java.util.Set;
import java.util.Set;
运行结果:
测试代码:
数据,不用现在加载,当我们要用的时候,才去加载
取消延迟加载:
import org.hibernate.Session;
虽然有: Set<Product>
products=category.getProducts();
代码,即:不处理集合对象。但是我们只要的是:
这里我们看到我们关心的是id,name和description属性,
HibernateTest.java
Hibernate就延迟加载
测试代码一:
/**
*
* @author XHW
*
* @date 2011-7-18
*
*/
public class HibernateTest {
public static void main(String[] args) {
new HibernateTest().update();
}
public void update(){
Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Category category=(Category)session.get(Category.class, 1);
System.out.println(“id:”+category.getId()+”
,name:”+category.getName()+”,
description:”+category.getDescription());
Set<Product> products=category.getProducts();
for(Product product:products){
System.out.println(“ID: “+product.getId()+”
name:”+product.getName()+” price: “+product.getPrice());
}
session.getTransaction().commit();
}
}
import org.hibernate.Session;
/**
*
* @author XHW
*
* @date 2011-7-18
*
*/
public class HibernateTest {
public static void main(String[] args) {
new HibernateTest().update();
}
public void update(){
Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Category category=(Category)session.get(Category.class, 1);
System.out.println(“id:”+category.getId()+”
,name:”+category.getName()+”,
description:”+category.getDescription());
Set<Product> products=category.getProducts();
session.getTransaction().commit();
}
}
代码:
log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name1_0_,
category0_.description as descript3_1_0_
from
users.category category0_
where
category0_.id=?
id:1 ,name:java,
description:java好啊
运行效果:
运行效果:
延迟加载在Hibernate中是默认延迟加载;
代码:
where
products0_.category_id=?
ID: 1 name:java SE应用程序设计 price: 78.00
这里可以明确的告诉我们,当我们要加载Set集合的时候,这时候才去加载,而上面的例子,说明的是我们不加载的时候