用JSP/Servlet开发简单的用户注册系统

  作者:板桥banq

上页

2.6  Hibernate使用

Hibernatehttp://sourceforge.net/projects/hibernate/)是著名的开源O/R mapping产品,可以将普通的Java对象直接映射到数据库持久层中,无需insertupdate之类的SQL操作语句。

在前面章节中,例如Profile中,将Profile对象中属性保存到数据库时,需要使用如下语句:

  mysql.setString(1, username);

  mysql.setString(2, this.email);

  mysql.setInt(3, this.gender);

  mysql.setInt(4, this.occupation);

 

这其实是一种非常琐碎的工作,使用Hibernate可以避免这种工作。

Profile的修改保存为例子,以下是直接使用JDBC和使用Hibernate的两段语句:

  //直接使用JDBC保存修改的数据

  public int update() throws Exception {

    if (!isValid())

      return Constants.FORM_ERROR;

    String birthday = new String(year + "-" + month + "-" + day);

    char current = ' ';

    String updatesql = "update profile set " +

        "username=?,email=?,gender=?,occupation=?,location=?,city=?,country=?," +

        "zipcode=?,homephone=?,cardnumber=?,birthday=? where userid=?";

    Mysql mysql = new Mysql(updatesql);

    try {

      mysql.setString(1, username);

      mysql.setString(2, this.email);

      mysql.setInt(3, this.gender);

      mysql.setInt(4, this.occupation);

      mysql.setString(5, this.location);

      mysql.setString(6, this.city);

      mysql.setInt(7, this.country);

      mysql.setString(8, this.zipcode);

      mysql.setString(9, this.homephone);

      mysql.setString(10, this.cardnumber);

      mysql.setString(11, birthday);

      mysql.setString(12, this.userid);

      mysql.executeUpdate();

    } catch (Exception ex) {

      throw new Exception("Profile.update()" + ex.getMessage());

    } finally {

      mysql.close();

      mysql = null;

    }

    return Constants.OK;

  }

 

  //使用Hibernate 保存修改语句

  public void updateHBM() throws Exception {

    Session session = HibernateUtil.openSession();

    Transaction transaction;

    try {

      transaction = session.beginTransaction(); //启动事务跟踪

      session.update(this);//保存当前的Java Object

      transaction.commit();

    } catch (Exception he) {

      throw new Exception(he);

    } finally {

      HibernateUtil.closeSession(session);

    }

  }

对比上面两个方法,发现使用Hibernate简单方便得多,这就是O/R Mapping的优点,开发使用关系数据表可以像使用一般对象一样,因为Hibernate这样的产品自动完成了对象到关系数据表之间的转换处理。

当然,Hibernate的使用还需要进行一些配置,以上面Hibernate使用为例子,需要设置hibernate.cfg.xml文件如下:

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration

    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"

    "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

 

<hibernate-configuration>

 

    <session-factory>

        <property name="hibernate.connection.datasource">

java:comp/env/jdbc/userDB

</property>

        <property name="hibernate.show_sql">true</property>

        <property name="hibernate.dialect">

net.sf.hibernate.dialect.MySQLDialect

</property>

        <!-- Mapping files -->

        <mapping resource="user_hbm.xml"/>

    </session-factory>

</hibernate-configuration>

 

这个hibernate.cfg.xml需要放置在WEB-INF/classes目录下。配置中使用了数据库连接池jdbc/userDBjdbc/userDB数据库连接在2.6节已经配置完成,在这里只要写入数据库连接池的Datasource JNDI就可以了,如同在MySQL.java中使用一样。

同时还需要配置一个Java对象和数据表的一一映射表user_hbm.xml,如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

 

<hibernate-mapping>

    <!--  com.jdon.simpleregister.Profile对应数据表profile  -->

    <class name="com.jdon.simpleregister.Profile" table="profile">

        <id name="userid" type="java.lang.String">

                <generator class="assigned" />

        </id>

        <property name="username" />

        <property name="email" />

        <property name="gender" />

        <property name="occupation" />

        <property name="location" />

        <property name="city" />

        <property name="country" />

        <property name="zipcode" />

        <property name="homephone" />

        <property name="cardnumber" />

        <property name="birthday" />

    </class>

</hibernate-mapping>

这两个配置文件都要放置在WEB-INF/classes目录下,这样在使用Hibernate时,Hibernate能够自动寻找到这些配置文件,将Hibernate的初始化和使用做成一个工具类HibernateUtil如下:

import java.io.InputStream;

import java.util.Properties;

 

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.Session;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.cfg.Configuration;

/**

 * 直接调用本类可以使用Hibernate

 * <p>Copyright: Jdon.com Copyright (c) 2003</p>

 * <p>Company: 上海极道计算机技术有限公司</p>

 * @author banq

 * @version 1.0

 */

public class HibernateUtil {

  private Properties hbmProps = new Properties();

  private static HibernateUtil _instance;

  private SessionFactory _sessionFactory;

 

  private static HibernateUtil _getInstance() {

    if (_instance == null) {

      synchronized (HibernateUtil.class) {

        if (_instance == null) {

          _instance = new HibernateUtil();

        }

      }

    }

    return _instance;

  }

  public Properties getProperties(){

      return hbmProps;

  }

  public static Session openSession() throws HibernateException {

    return _getInstance()._openSession();

  }

  public static void closeSession(Session session) {

    try {

      if (session != null) {

        session.close();

      }

    } catch (Exception e) {

      e.printStackTrace();

    }

  }

  private HibernateUtil() {

    try {

      _sessionFactory = new Configuration().configure().buildSessionFactory();

    } catch (Exception e) {

      e.printStackTrace();

    }

  }

  private Session _openSession() throws HibernateException {

    return _sessionFactory.openSession();

  }

}

HibernateUtil是一个工具使用类,直接调用HibernateUtil可以获得Session实例。通过Session实例可以实现数据表的插入或更新存储。

更深入的使用可以参考Hibernate手册。

 

下页