【IT168 技术文档】
这个文件我不解释了,自己看吧。结合上文StudentDAO的例子,我想你应该能看明白。
看了这么多,或许你会有点头皮发麻,POJO,DAO,配置文件...好像要写的东西还是很多。值得庆幸的是现在Hibernate已经发展的比较成熟了,有很多工具来帮助我们完成这些工作,比如MiddleGen,Hibernate Synchronizer等等。我使用的开发工具是Eclipse+MyEclipse,我所要做的只是把数据库表建好,然后MyEclipse提供的工具会自动根据数据库表生成POJO,DAO,*.hbm.xml,甚至hibernate.cfg.xml都是自动完成的(前提是MyEclipse知道你的数据库连接信息)。我并不打算介绍如何用IDE来开发Hibernate,你可以参考IDE的帮助文档。
到这里为止,使用Hibernate进行开发的基本组成元素我都介绍好了,强烈建议你马上实践一遍,即使有些不理解,也先依葫芦画瓢一个。对了,别忘了把Hibernate的包down下来放到classpath里面。
三、Session与SessionFactory
Session可以说是Hibernate的核心,Hibernate对外暴露的接口就是Session。所以我这里讲一下有关Session的常用函数和特性。
在讲Session之前,我想先提一下SessionFactory,这个东西不复杂,只要配置好就行了。顾名思义,SessionFactory就是用来创建Session的。SessionFactory是线程安全的,也就是说对于同一个数据库的所有操作共享一个SessionFactory就行了。回头看代码片段5,我们可以看到SessionFactory的常用配置方式。
代码片段8:
Configuration cfg = new Configuration();
cfg.configure("/hibernate.cfg.xml");
SessionFactory sessionFactory = cfg.buildSessionFactory();
我们通过Configuration来读取配置文件,然后就可以创建SessionFactory,这段代码在 所有系统中都大同小异,一般就是xml配置文件的名字不一样,所以也没什么好说的。
当我们有了SessionFactory以后就可以获取Session了。调用SessionFactory.openSession()就会返回一个Session实例,然后我们操作这个Session来访问数据库。值得一提的是Session并不是线程安全的,也就是每一个线程都必须有自己的Session。所以我们一般通过以下方法来获取和关闭Session:
代码片段9:
public static Session currentSession() throws HibernateException
...{
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen())
...{
if (sessionFactory == null)
...{
try
...{
cfg.configure(CONFIG_FILE_LOCATION);
sessionFactory = cfg.buildSessionFactory();
}
catch (Exception e)
...{
e.printStackTrace();
}
}
session = (sessionFactory != null) ?
sessionFactory.openSession(): null;
threadLocal.set(session);
}
return session;
}
![]()
public static void closeSession() throws HibernateException
...{
Session session = (Session) threadLocal.get();
threadLocal.set(null);
![]()
if (session != null)
...{
session.close();
}
}
可以看到,我们通过threadLocal来保存每个线程的session,这样就保证了各个线程之 间的互不干扰,也保证了系统只有一个SessionFactory实例(对于大多数应用来说已经 足够了)。如果你使用MyEclipse进行开发的话,它会自动生成一个 HibernateSessionFactory.java,其中就包含了以上代码。
好了,现在我们已经获得了Session,下面我来介绍以下Session的常用函数,这些函数都有很多重载函数,我只介绍以下大概是干嘛的,不一一解释,详细信息你可以查看Hibernate的API。
1.Session.get(),获取某个类的实例,一般都是通过id来获取比如
Session.get(Student.class, "0361095");
这句话的意思就是获取id(primary key)为“0361095”的Student对象。这里要注 意的是第二个参数必须是Object,也就是说,如果是long类型的1,那么必须转换 成new Long(1)再传入。
2.Session.load(),用法和意义都和get一样,不过它们还是有点区别,我稍后解释。
3.Session.save(),将某个实例保存到数据库中去(往往在数据库中形成一条新的记录)。
4.Session.update(),更新某个实例,这个实例必须和数据库中有对应,否则会报错。
5.Session.delete(),删除某个实例,也就是删除这个实例对应的数据表中的数据。
6.Session.saveOrUpdate(),保存或者更新某个实例,调用这个方法你就不用去关心到底是save还是update了,它会自己判断,然后调用相应的函数。其实save和update 涉及到实体对象生命周期中的三种状态,这个比较重要,我在后面会单独讲的。
对于get和load的区别,很难讲清楚,这里涉及到Hibernate的缓存机制,是一个非常 复杂的话题,我不打算深入讨论这个内容。简单的来讲,Session实现了Hibernate的一 级缓存,SessionFactory实现了Hibernate的二级缓存。load方法会先查找一级缓存再查 找二级缓存,最后再去数据库中找,而get只会查找一级缓存,然后就去数据库中找了。 这只是是get和load的一个区别,另外的区别如果你有兴趣的话自己去google吧。关于Hibernate的缓存机制,如果你只是一般用用Hibernate的话没有必要深入研究,就当它不存在好了,get和load到底用哪个也不用非常讲究,如果你用工具生成DAO的话, 生成的代码用什么就用什么吧。
