生活日记
Hibernate 与延迟加载:
Hibernate 对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的(如果不是成千的话) select 语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整个数据库都在初始化的阶段被读出来了。当然,你可以不厌其烦地检查每一个对象与其他对象的关系,并把那些最昂贵的删除,但是到最后,我们可能会因此失去了本想在 ORM 工具中获得的便利。
一个明显的解决方法是使用 Hibernate 提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个 Hibernate 会话要在对象使用的时候一直开着。这会成为通过使用 DAO 模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的数据库逻辑,包括打开或关闭会话,都不能在应用层出现。最常见的是,一些实现了简单接口的 DAO 实现类将数据库逻辑完全封装起来了。一种快速但是笨拙的解决方法是放弃 DAO 模式,将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的可扩展性。
在 Web 层进行延迟加载
幸运的是, Spring 框架为 Hibernate 延迟加载与 DAO 模式的整合提供了一种方便的解决方法。对那些不熟悉 Spring 与 Hibernate 集成使用的人,我不会在这里讨论过多的细节,但是我建议你去了解 Hibernate 与 Spring 集成的数据访问。以一个 Web 应用为例, Spring 提供了 OpenSessionInViewFilter 和 OpenSessionInViewInterceptor 。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于 interceptor 在 Spring 容器中运行并被配置在 web 应用的上下文中,而 Filter 在 Spring 之前运行并被配置在 web.xml 中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开 Hibernate 会话。一旦已绑定到线程,这个打开了的 Hibernate 会话可以在 DAO 实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成了, Hibernate 会话会在 Filter 的 doFilter 方法或者 Interceptor 的 postHandle 方法中被关闭。下面是每个组件的配置示例:
Interceptor的配置:
< beans >
< bean id ="urlMapping"
class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
< property name ="interceptors" >
< list >
< ref bean ="openSessionInViewInterceptor" />
</ list >
</ property >
< property name ="mappings" >
</ bean >
< bean name ="openSessionInViewInterceptor"
class ="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor" >
< property name ="sessionFactory" >< ref bean ="sessionFactory" /></ property >
</ bean >
</ beans >
Filter的配置
< web-app >
< filter >
< filter-name > hibernateFilter </ filter-name >
< filter-class >
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</ filter-class >
</ filter >
< filter-mapping >
< filter-name > hibernateFilter </ filter-name >
< url-pattern > *. spring </ url-pattern >
</ filter-mapping >
</ web-app >
实现 Hibernate 的 Dao 接口来使用打开的会话是很容易的。事实上,如果你已经使用了 Spring 框架来实现你的 Hibernate Dao, 很可能你不需要改变任何东西。方便的 HibernateTemplate 公用组件使访问数据库变成小菜一碟,而 DAO 接口只有通过这个组件才可以访问到数据库。下面是一个示例的 DAO :
public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO {
public Product getProduct(Integer productId) {
return (Product)getHibernateTemplate().load(Product. class , productId);
}
public Integer saveProduct(Product product) {
return (Integer) getHibernateTemplate().save(product);
}
public void updateProduct(Product product) {
getHibernateTemplate().update(product);
}
}
在业务逻辑层中使用延迟加载
即使在视图外面, Spring 框架也通过使用 AOP 拦截器 HibernateInterceptor 来使得延迟加载变得很容易实现。这个 Hibernate 拦截器 透明地将调用配置在 Spring 应用程序上下文中的业务对象中方法的请求拦截下来,在调用方法之前打开一个 Hibernate 会话,然后在方法执行完之后将会话关闭。让我们来看一个简单的例子,假设我们有一个接口 BussinessObject :
public interface BusinessObject {
public void doSomethingThatInvolvesDaos();
}
类BusinessObjectImpl实现了BusinessObject接口:
public class BusinessObjectImpl implements BusinessObject {
public void doSomethingThatInvolvesDaos() {
// lots of logic that calls
// DAO classes Which access
// data objects lazily
}
}
通过在Spring应用程序上下文中的一些配置,我们可以让将调用BusinessObject的方法拦截下来,再令它的方法支持延迟加载。看看下面的一个程序片段:
< beans >
< bean id ="hibernateInterceptor" class ="org.springframework.orm.hibernate.HibernateInterceptor" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
< bean id ="businessObjectTarget" class ="com.acompany.BusinessObjectImpl" >
< property name ="someDAO" >< ref bean ="someDAO" /></ property >
</ bean >
< bean id ="businessObject" class ="org.springframework.aop.framework.ProxyFactoryBean" >
< property name ="target" >< ref bean ="businessObjectTarget" /></ property >
< property name ="proxyInterfaces" >
< value > com.acompany.BusinessObject </ value >
</ property >
< property name ="interceptorNames" >
< list >
< value > hibernateInterceptor </ value >
</ list >
</ property >
</ bean >
</ beans >
当 businessObject 被调用的时候, HibernateInterceptor 打开一个 Hibernate 会话,并将调用请求传递给 BusinessObjectImpl 对象。当 BusinessObjectImpl 执行完成后, HibernateInterceptor 透明地关闭了会话。应用层的代码不用了解任何持久层逻辑,还是实现了延迟加载。
在单元测试中测试延迟加载
最后,我们需要用 J-Unit 来测试我们的延迟加载程序。我们可以轻易地通过重写 TestCase 类中的 setUp 和 tearDown 方法来实现这个要求。我比较喜欢用这个方便的抽象类作为我所有测试类的基类。
public abstract class MyLazyTestCase extends TestCase {
private SessionFactory sessionFactory;
private Session session;
public void setUp() throws Exception {
super .setUp();
SessionFactory sessionFactory = (SessionFactory) getBean( " sessionFactory " );
session = SessionFactoryUtils.getSession(sessionFactory, true );
Session s = sessionFactory.openSession();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));
}
protected Object getBean(String beanName) {
// Code to get objects from Spring application context
}
public void tearDown() throws Exception {
super .tearDown();
SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
Session s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
}
}
haohao
2006-11-28 11:05:52
阅读:797
评论:2
引用:0
以前对数据的展示都是直接拿jsp来写的。
来了公司后,是自己提出来要用webwork,原来以为在webwork比较简单
而且好用,但是用起来才知道,hibernate还麻烦,最讨厌的是就是是可恶的
标签。
自己是做web开发的,却对html,对js,对标签和ajax之类,感觉舒服,
而且弄的时候带有很大情绪,但是web开发这些作为数据的录入和展示是肯定
少不了的。
真不知道什么时候才能离开这些可恶的东西,感觉非常的令你不舒服,
特别是js。
来了公司后,是自己提出来要用webwork,原来以为在webwork比较简单
而且好用,但是用起来才知道,hibernate还麻烦,最讨厌的是就是是可恶的
标签。
自己是做web开发的,却对html,对js,对标签和ajax之类,感觉舒服,
而且弄的时候带有很大情绪,但是web开发这些作为数据的录入和展示是肯定
少不了的。
真不知道什么时候才能离开这些可恶的东西,感觉非常的令你不舒服,
特别是js。
haohao
2006-11-26 18:12:10
阅读:69
评论:0
引用:0
最近工作遇到两个比较麻烦的问题
一个是讨厌已久的js,一个是webwork的个标签.
其他的对我来说没有什么多难的,hibernate的应用,spring的应用
都比较容易,ajax对我来说,估计是逃不了的.因为做web开发,这两个东
西是肯定要用的.
估计突袭这个项目对我而言意义很大,第一是自己提出的办法来解决
的,第一个涉及到的ajax和webwork开发.
前几天对问题心里比较不愿意去解决,现在看来不行了,别人是帮助
不了自己了,
只有自己了
一个是讨厌已久的js,一个是webwork的个标签.
其他的对我来说没有什么多难的,hibernate的应用,spring的应用
都比较容易,ajax对我来说,估计是逃不了的.因为做web开发,这两个东
西是肯定要用的.
估计突袭这个项目对我而言意义很大,第一是自己提出的办法来解决
的,第一个涉及到的ajax和webwork开发.
前几天对问题心里比较不愿意去解决,现在看来不行了,别人是帮助
不了自己了,
只有自己了
haohao
2006-11-21 20:45:17
阅读:84
评论:0
引用:0
今天突然精神发作就要去买本书jdo的书.
结果又买回来了,看了看,本来感觉这个
东西和hibernate等一样是o/r.结果发现自己又
错了,完全不一样的东西,值得去学习.
可以解决困惑好长时间的一个问题,就是
java的对象分布式的同步,根据介绍实现的非常
好
不过jdo和hibernate有一个共同的特点就是
要求oop的思想立即也应用的非常牛才行了.
看来oop是java的核心基础了
结果又买回来了,看了看,本来感觉这个
东西和hibernate等一样是o/r.结果发现自己又
错了,完全不一样的东西,值得去学习.
可以解决困惑好长时间的一个问题,就是
java的对象分布式的同步,根据介绍实现的非常
好
不过jdo和hibernate有一个共同的特点就是
要求oop的思想立即也应用的非常牛才行了.
看来oop是java的核心基础了
haohao
2006-11-19 22:25:24
阅读:74
评论:0
引用:0
今天本来要去王政井书店.路过地坛顺便就看看
书市,进去一个看那是什么书市简直就是一菜市场,
感觉差死了.想找本书看,结果要买的书,根本不知
道去哪儿找.找了两个小时一本也没有找到,还是去了
王政井.
顺便看看了有没有什么可以买的衣服,结果一看,
发现衣服也贵不行,能看上眼,就是要400多.突然
感觉自己又没有钱了,就没有买,上个月没有工作,花了
我近4000多块钱,好在我又工作了,马上就可以发工
资了.
书市,进去一个看那是什么书市简直就是一菜市场,
感觉差死了.想找本书看,结果要买的书,根本不知
道去哪儿找.找了两个小时一本也没有找到,还是去了
王政井.
顺便看看了有没有什么可以买的衣服,结果一看,
发现衣服也贵不行,能看上眼,就是要400多.突然
感觉自己又没有钱了,就没有买,上个月没有工作,花了
我近4000多块钱,好在我又工作了,马上就可以发工
资了.
haohao
2006-11-19 22:22:12
阅读:88
评论:1
引用:0
本来有机会进去一家,不要天天开会的公司。
但是我却想跟上鬼一样的进了一家,非常喜欢开会的公司。
每个星期最少3次思想教育会,真不知道国人是怎么搞的,把
人的思想都教坏了,让我们公司花这么多时间来教育。
公司是一家国有企业,有点文化大革命的时期的样子,白天抓
生产晚上抓思想。
不过还好,公司董事长开会比较有意思,最起码让你感觉不是
那么无聊,但是部门会议除了技术讨论以外,其他的会议,我一律
当时比赛的时候中场休息。
我最近感觉来这样的公司,对我来说是一件大大的好事,让我
明白了,我们社会主义国有企业的优越性在哪儿,毛病在哪儿,也同
时让我明白了杨老板的说,要看领导的脸色,知道自己的角色,什么叫
做屁股指挥脑袋,我也也特别能领会领导意思,知道他说话的意思,
就是开玩笑也在暗示着什么!
不过今天部门开会的时候,经理说问我们大家想好了,2007年做
什么吗?一下给我傻了。
我的确没有想过,只知道自己的目标是什么,自己要做什么样的事,
知道自己做执行力不够,很难将高端的愿望解码成具体的工作派遣单,
知道在各种资源没有来临的时候,结累和等待说不定,等到那天就等的
没有了,我知道我想做的事业现在是肯定不能做,因为社会资源不够,
大的形势发展不到位,市场需求短时间不会出现。
其实这无疑是对自己的考验,要知道想做点事情的人都要耐的住寂寞
和冷落,耐的住考验,这点我是从杨总身上体会到的。
但是我却想跟上鬼一样的进了一家,非常喜欢开会的公司。
每个星期最少3次思想教育会,真不知道国人是怎么搞的,把
人的思想都教坏了,让我们公司花这么多时间来教育。
公司是一家国有企业,有点文化大革命的时期的样子,白天抓
生产晚上抓思想。
不过还好,公司董事长开会比较有意思,最起码让你感觉不是
那么无聊,但是部门会议除了技术讨论以外,其他的会议,我一律
当时比赛的时候中场休息。
我最近感觉来这样的公司,对我来说是一件大大的好事,让我
明白了,我们社会主义国有企业的优越性在哪儿,毛病在哪儿,也同
时让我明白了杨老板的说,要看领导的脸色,知道自己的角色,什么叫
做屁股指挥脑袋,我也也特别能领会领导意思,知道他说话的意思,
就是开玩笑也在暗示着什么!
不过今天部门开会的时候,经理说问我们大家想好了,2007年做
什么吗?一下给我傻了。
我的确没有想过,只知道自己的目标是什么,自己要做什么样的事,
知道自己做执行力不够,很难将高端的愿望解码成具体的工作派遣单,
知道在各种资源没有来临的时候,结累和等待说不定,等到那天就等的
没有了,我知道我想做的事业现在是肯定不能做,因为社会资源不够,
大的形势发展不到位,市场需求短时间不会出现。
其实这无疑是对自己的考验,要知道想做点事情的人都要耐的住寂寞
和冷落,耐的住考验,这点我是从杨总身上体会到的。
haohao
2006-11-17 23:35:38
阅读:168
评论:0
引用:0
由于在大量招人,我这个二把刀,
作为面试官来面试别人,
来应聘的人有做两年的经验,有和我一样民办大学,也国家重点大学
北京科技大学,北航,在我面前出现的大概有10来个人.
但是感觉都不行,基本都连下一次面试都进不去,
不行的原因有:
刚刚毕业的学生,大多数经过培训,但是培训的情况不行,差的很远
对基本的东西理解特别差.
还有就是,我们感觉这些人都脑子有问题,我和经理明明和他们说
我们要招一些视图层的人,但是每一个都说自己在数据库方面比较强,
说懂什么hibernate,spring struts了,但是问问,什么是IoC什么是MVC
什么是orm,hibernate这些东西能给我给我们做什么,却回答的模棱两可
还有就是有一个家伙说自己工作两年了用hibernate有一段时间了,但是
我问load,get的区别,却不知道,这个是最基本的, 还就是我问hibernate
中lazy是怎么回事的时候,却说不上了.
有一个家伙说自己,非常聪明,我问多对多的关系,怎么处理,却说不上了,
我问抽象类和接口的区别在哪儿,也不知道.
可以说今天下午面试的同志们,集体不行,而且我估计也没有什么前途了,
因为在他们脸上没有一点自信和乐观的感觉,不会回答问题的时候,也不会顺便
问问我们.
本来软件管理学院的那个朋友,我有意思给他个机会,(因为我和他一样是
民办大学毕业的)但是一问在大学的时候写过多少东西,结果说全玩了,问他为
什么选择新东方培训,他说是因为自己是学计算机的,这叫我心凉了一半,
因为他对计算机这个东西连基本的爱好都谈不上,只是很无奈的接受,估计要让
天天加班做开发难度比较大,想了想,最后好是和经理他们说不行.
原来以为自己找的工作的时候,是因为没有工作经验不好找(刚刚出来
的时候)结果发现自己错了,最重要的是你基本东西理解,第一份工作找的非常辛苦
现在还要感谢欢乐公司的机会,再找第二份工作的时候,就感觉不难了,第二份工作,
我没有考虑就去了,不过感到快乐的是认识我们头这样的好人,告诉我很多做技术需
要的东西和职场规则,找第三份工作的时候,我每次都是同时收到两份通知,而且这些
公司还都不错,是我在选择工作,而不是工作选择我.
感谢帮助过我所有的人,感谢上帝.
作为面试官来面试别人,
来应聘的人有做两年的经验,有和我一样民办大学,也国家重点大学
北京科技大学,北航,在我面前出现的大概有10来个人.
但是感觉都不行,基本都连下一次面试都进不去,
不行的原因有:
刚刚毕业的学生,大多数经过培训,但是培训的情况不行,差的很远
对基本的东西理解特别差.
还有就是,我们感觉这些人都脑子有问题,我和经理明明和他们说
我们要招一些视图层的人,但是每一个都说自己在数据库方面比较强,
说懂什么hibernate,spring struts了,但是问问,什么是IoC什么是MVC
什么是orm,hibernate这些东西能给我给我们做什么,却回答的模棱两可
还有就是有一个家伙说自己工作两年了用hibernate有一段时间了,但是
我问load,get的区别,却不知道,这个是最基本的, 还就是我问hibernate
中lazy是怎么回事的时候,却说不上了.
有一个家伙说自己,非常聪明,我问多对多的关系,怎么处理,却说不上了,
我问抽象类和接口的区别在哪儿,也不知道.
可以说今天下午面试的同志们,集体不行,而且我估计也没有什么前途了,
因为在他们脸上没有一点自信和乐观的感觉,不会回答问题的时候,也不会顺便
问问我们.
本来软件管理学院的那个朋友,我有意思给他个机会,(因为我和他一样是
民办大学毕业的)但是一问在大学的时候写过多少东西,结果说全玩了,问他为
什么选择新东方培训,他说是因为自己是学计算机的,这叫我心凉了一半,
因为他对计算机这个东西连基本的爱好都谈不上,只是很无奈的接受,估计要让
天天加班做开发难度比较大,想了想,最后好是和经理他们说不行.
原来以为自己找的工作的时候,是因为没有工作经验不好找(刚刚出来
的时候)结果发现自己错了,最重要的是你基本东西理解,第一份工作找的非常辛苦
现在还要感谢欢乐公司的机会,再找第二份工作的时候,就感觉不难了,第二份工作,
我没有考虑就去了,不过感到快乐的是认识我们头这样的好人,告诉我很多做技术需
要的东西和职场规则,找第三份工作的时候,我每次都是同时收到两份通知,而且这些
公司还都不错,是我在选择工作,而不是工作选择我.
感谢帮助过我所有的人,感谢上帝.
haohao
2006-11-16 23:07:04
阅读:318
评论:3
引用:0
hh.sql
create table hh(id int,name varchar(20),primary key(id));
create table ww(id int,name varchar(20),primary key(id));
Hh.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hh.Hh" table="hh">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="name" type="string" column="name"/>
<one-to-one name="ww" class="com.hh.Ww" cascade="all" outer-join="true"/>
</class>
</hibernate-mapping>
package com.hh;
public class Hh {
private int id;
private String name;
private Ww ww;
//getter
//setter
}
Ww.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hh.Ww" table="ww">
<id name="id" column="id" >
<generator class="foreign">
<param name="property">hh</param>
</generator>
</id>
<property name="name" type="string" column="name"/>
<one-to-one name="hh" class="com.hh.Hh" constrained="true"/>
</class>
</hibernate-mapping>
package com.hh;
public class Ww {
private int id;
private String name;
private Hh hh;
//getter setter
}
test.java
package com.hh;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
public class DaoTest extends AbstractDependencyInjectionSpringContextTests {
protected String[] getConfigLocations() {
return new String [] {"classpath*:/com/hh/applicationContext.xml"};
}
private Dao dao;
public Dao getDao() {
return dao;
}
public void setDao(Dao dao) {
this.dao = dao;
}
public void testSaveObject() {
Hh h = new Hh();
h.setName("haohao");
Ww w = new Ww();
w.setHh(h);
w.setName("www");
dao.saveObject(h);
dao.saveObject(w);
}
public void testGetObject() {
Hh h= (Hh)dao.getObject(Hh.class,3);
System.out.println(h.getName());
System.out.println(h.getWw().getName());
}
}
又一次调hibernate关系,弄了一个多小时,
估计以后还会有的, 做个记录吧!
haohao
2006-11-16 22:45:23
阅读:538
评论:0
引用:0
公司最近大力招人,也大量的挖人。
今天公司来了十来个面试java的,下午经理叫我要求去面试了一个。
我看看简历就不想再说了, 简历加起来不到500个字。
没有看出来还是国家统招的同志,工作两年了。
我问他说在项目是什么角色,按照他的回答,应该最初是copy的角色
比刚刚毕业的好不到哪儿去,并且连最起码的自信也没有,基本还不如我年
初找工作时的状态呢!
我就随便问了几个java的问题,结果让我这样底水平的人都感觉不舒服
这样更加证明了我原来想的一点。
如果一个人都工作两年了,还要通过网络投简历找工作的,证明这个人,
第一水平不怎么样,第二人本身有问题,第三没有什么潜力可谈。 让我再次
证明工作经验这个东西不能信。
今天公司来了十来个面试java的,下午经理叫我要求去面试了一个。
我看看简历就不想再说了, 简历加起来不到500个字。
没有看出来还是国家统招的同志,工作两年了。
我问他说在项目是什么角色,按照他的回答,应该最初是copy的角色
比刚刚毕业的好不到哪儿去,并且连最起码的自信也没有,基本还不如我年
初找工作时的状态呢!
我就随便问了几个java的问题,结果让我这样底水平的人都感觉不舒服
这样更加证明了我原来想的一点。
如果一个人都工作两年了,还要通过网络投简历找工作的,证明这个人,
第一水平不怎么样,第二人本身有问题,第三没有什么潜力可谈。 让我再次
证明工作经验这个东西不能信。
haohao
2006-11-15 21:11:25
阅读:79
评论:0
引用:0
突然回想了,我们yulog发展历史,
仔细查了一下,原来我的haohao是我们yulog的中的第一个注册用户。
接下来是hofman,coffee,meiking等
原来以为是是hofman第一个,结果查时间,发现我才是第一个2004 7.28
估计若干年后,我们yulog发达了,会有人找我签名的。
仔细查了一下,原来我的haohao是我们yulog的中的第一个注册用户。
接下来是hofman,coffee,meiking等
原来以为是是hofman第一个,结果查时间,发现我才是第一个2004 7.28
估计若干年后,我们yulog发达了,会有人找我签名的。
haohao
2006-11-14 17:00:20
阅读:97
评论:2
引用:0
