在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表。
自动生成及修改的代码如下:
package com.cn.vo;/** * UsersVo entity. @author MyEclipse Persistence Tools */public class UsersVo implements java.io.Serializable { // Fields private Integer id; private String name; private Integer age; private String tel; private String address; // Constructors /** default constructor */ public UsersVo() { } /** minimal constructor */ public UsersVo(Integer id) { this.id = id; } /** full constructor */ public UsersVo(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 public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Integer getAge() { return this.age; } public void setAge(Integer age) { this.age = age; } public String getTel() { return this.tel; } public void setTel(String tel) { this.tel = tel; } public String getAddress() { return this.address; } public void setAddress(String address) { this.address = address; }}
UsersVo.hbm.xml
hibernate.cfg.xml(修改)
org.hibernate.dialect.MySQLDialect true update thread jdbc:mysql://localhost:3306/bank root 1234 com.mysql.jdbc.Driver com.mysql.jdbc.Driver
HibernateSessionFactory.java
package com.cn.hibernate;import org.hibernate.HibernateException;import org.hibernate.Session;import org.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 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 ThreadLocalthreadLocal = 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 = (Session) threadLocal.get(); if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } 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 = (Session) threadLocal.get(); threadLocal.set(null); 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; }}
2. 编写数据持久层
为了使程序结构清晰,数据持久层独立出来,放在DAO层中,在DAO层的类中编写数据的增删修改查方法,通过这些方法操作数据。在使用时,只需要根据实际情况来调用DAO层中的方法就可以了。这个例子中,DAO层只有一个类,类名为HibernateDao,HibernateDao类的代码如下:
package com.cn.dao;import org.hibernate.HibernateException;import org.hibernate.Session;import java.util.List;import com.cn.hibernate.HibernateSessionFactory;import com.cn.vo.UsersVo;public class HibernateDao { //添加数据的方法 public void add(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 void modifyUsers(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(int id){ 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(int id){ Session session = HibernateSessionFactory.getSession(); UsersVo users = (UsersVo)session.get(UsersVo.class, id); return users; } //查找多条数据 @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操作。