在Java Web程序中使用Hibernate与普通Java程序一样。本文中将使用Servlet和JSP结合Hibernate实现数据库表的增删改查操作。
Web程序中,hibernate.cfg.xml中必须配置current_session_context_class参数。如果使用JBoss等内置Hibernae的容器,参数值要配置为jta,其他容器(如Tomcat等)需要配置为thread。
1. 创建工程并搭建Hibernate框架
在MyEclipse中创建一个Web工程,工程名为hibernate_web,把MySQL数据库驱动包和JSTL需要的jar包复制到WebRoot/WEB-INF/lib目录下;然后使用MyEclipse向导把Hibernate的jar包导到工程中。关于搭建Hibernate框架,可以参考网上的教程,这里就不再介绍了。接着,使用Hibernate连接数据库,并通过数据库表自动生成数据库对应的实体类和实体类映射文件。所使用的数据库表是MySQL的bank数据库中的users表。
自动生成及修改的代码如下:
packagecom.cn.vo;/*** UsersVo entity.@authorMyEclipse Persistence Tools*/
public class UsersVo implementsjava.io.Serializable {//Fields
privateInteger id;privateString name;privateInteger age;privateString tel;privateString address;//Constructors
/**default constructor*/
publicUsersVo() {
}/**minimal constructor*/
publicUsersVo(Integer id) {this.id =id;
}/**full constructor*/
publicUsersVo(Integer id, String name, Integer age, String tel,
String address) {this.id =id;this.name =name;this.age =age;this.tel =tel;this.address =address;
}//Property accessors
publicInteger getId() {return this.id;
}public voidsetId(Integer id) {this.id =id;
}publicString getName() {return this.name;
}public voidsetName(String name) {this.name =name;
}publicInteger getAge() {return this.age;
}public voidsetAge(Integer age) {this.age =age;
}publicString getTel() {return this.tel;
}public voidsetTel(String tel) {this.tel =tel;
}publicString getAddress() {return this.address;
}public voidsetAddress(String address) {this.address =address;
}
}
UsersVo.hbm.xml
/p>
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
hibernate.cfg.xml(修改)
/p>
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
org.hibernate.dialect.MySQLDialect
true
update
thread
jdbc:mysql://localhost:3306/bank
root
1234
com.mysql.jdbc.Driver
com.mysql.jdbc.Driver
HibernateSessionFactory.java
packagecom.cn.hibernate;importorg.hibernate.HibernateException;importorg.hibernate.Session;importorg.hibernate.cfg.Configuration;/*** Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html}.*/
public classHibernateSessionFactory {/*** 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 = newConfiguration();private staticorg.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();
}
}privateHibernateSessionFactory() {
}/*** Returns the ThreadLocal Session instance. Lazy initialize
* the SessionFactory
if needed.
*
*@returnSession
*@throwsHibernateException*/
public static Session getSession() throwsHibernateException {
Session session=(Session) threadLocal.get();if (session == null || !session.isOpen()) {if (sessionFactory == null) {
rebuildSessionFactory();
}
session= (sessionFactory != null) ?sessionFactory.openSession()
:null;
threadLocal.set(session);
}returnsession;
}/*** Rebuild hibernate session factory
**/
public static voidrebuildSessionFactory() {try{
configuration.configure(configFile);
sessionFactory=configuration.buildSessionFactory();
}catch(Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}/*** Close the single hibernate session instance.
*
*@throwsHibernateException*/
public static void closeSession() throwsHibernateException {
Session session=(Session) threadLocal.get();
threadLocal.set(null);if (session != null) {
session.close();
}
}/*** return session factory
**/
public staticorg.hibernate.SessionFactory getSessionFactory() {returnsessionFactory;
}/*** return session factory
*
* session factory will be rebuilded in the next call*/
public static voidsetConfigFile(String configFile) {
HibernateSessionFactory.configFile=configFile;
sessionFactory= null;
}/*** return hibernate configuration
**/
public staticConfiguration getConfiguration() {returnconfiguration;
}
}
2. 编写数据持久层
为了使程序结构清晰,数据持久层独立出来,放在DAO层中,在DAO层的类中编写数据的增删修改查方法,通过这些方法操作数据。在使用时,只需要根据实际情况来调用DAO层中的方法就可以了。这个例子中,DAO层只有一个类,类名为HibernateDao,HibernateDao类的代码如下:
packagecom.cn.dao;importorg.hibernate.HibernateException;importorg.hibernate.Session;importjava.util.List;importcom.cn.hibernate.HibernateSessionFactory;importcom.cn.vo.UsersVo;public classHibernateDao {//添加数据的方法
public voidadd(UsersVo usersVo){//调用HibernateSessionFactory的会话
Session session =HibernateSessionFactory.getSession();try{
session.beginTransaction();//开启事务
session.persist(usersVo); //将对象添加到数据库
session.getTransaction().commit(); //提交事务
}catch(Exception e) {
session.getTransaction().rollback();//回滚事务
} finally{
session.close();//关闭session
}
}//修改数据的方法
public voidmodifyUsers(UsersVo usersVo){
Session session=HibernateSessionFactory.getSession();try{
session.beginTransaction();//开启事务
session.update(usersVo); //修改数据
session.getTransaction().commit(); //提交事务
} catch(Exception e) {
session.getTransaction().rollback();//回滚事务
} finally{
session.close();//关闭session
}
}//从表中删除数据
public void delete(intid){
Session session=HibernateSessionFactory.getSession();try{
session.beginTransaction();
UsersVo users= (UsersVo)session.get(UsersVo.class, id);
session.delete(users);
session.getTransaction().commit();
}catch(Exception e) {
session.getTransaction().rollback();
}finally{
session.close();
}
}//根据id查找数据
@SuppressWarnings("unchecked")public UsersVo queryUsersById(intid){
Session session=HibernateSessionFactory.getSession();
UsersVo users= (UsersVo)session.get(UsersVo.class, id);returnusers;
}//查找多条数据
@SuppressWarnings("unchecked")public Listshowlist(String hql){
Session session=HibernateSessionFactory.getSession();try{
session.beginTransaction();return session.createQuery(hql).list(); //使用HQL查询结果,返回List对象
} catch(Exception e) {
session.getTransaction().rollback();
}finally{
session.getTransaction().commit();
session.close();
}return null;
}
}
该类中接受UsersVo类,Hibernate能够判断实体类的类型,决定操作哪个数据表。HibernateDao封装了最基本的CURD操作。