一个简单的Hibernate实例

37.3  一个简单的Hibernate实例(V005)
37.3.1  创建Hibernate配置文件:hibernate.cfg.xml
在“Java Resourcess:src”下创建一个hibernate.cfg.xml文件如下。
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
         <session-factory>
                   <!-- 数据库 -->
                   <property name="connection.datasource">java:comp/env/jdbc/mysql</property>
                   <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
                   <property name="show_sql">true</property>
         <!-- 打开Hibernate的session自动管理机制 -->
         <property name="current_session_context_class">thread</property>
                   <!-- 把所有*.hbm.xml文件注册在这里 -->
                   <mapping resource="cn/com/chengang/sms/model/model.hbm.xml"/>
         </session-factory>
</hibernate-configuration>
配置说明:
  ● connection.datasource设定所用的连接池。
  ● dialect告诉Hibernate使用哪种SQL数据库方言(dialect)。不同数据库的SQL语法都有一些差异,Hibernate会根据设置的方言来适应这些差异。想知道其他数据的方言名称,可以利用Eclipse的代码提示功能,在Java程序中输入“org.hibernate.dialect.”然后按“Alt+/”快捷键。
  ● show_sql设定在控制台是否显示Hibernate生成的SQL语句,开发期间设为true,便于调试。
  ● model.hbm.xml是一个XML映射文件,这个文件创建在model目录下(内容将在以后给出)。注意,这里用的是相对路径,cn字串前面是没有“/”的。
  ● hibernate.cfg.xml还有一种hibernate.properties的写法,在Hibernate的解压目录etc可找到它的例子。两种写法选一种即可,本文选前一种。
  ● 某些属性对Hibernate的性能影响很大,比如batch_size项设置成0和30,性能相差会有4倍以上。属性会有一个默认值,但如果所开发的项目需要作性能优化,则可根据实际情况来重新设置。如果想了解hibernate.cfg.xml中更多的属性设置,可以参考Hibernate文档的“表3.3  Hibernate配置属性”,那里有属性的说明和建议值,本文不再复述。
37.3.2  创建XML映射文件:model.hbm.xml
Hibernate之所以能够智能地判断实体类和数据表之间的对应关系,就是因为有XML映射文件。本小节先在cn.com.chengang.sms.model包下创建一个名为model.hbm.xml的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="cn.com.chengang.sms.model.Grade" table="grade">
                   <id name="id">
                            <generator class="identity"/>
                   </id>
        <property name="name"/>
    </class>
</hibernate-mapping>
配置说明:
  ● model.hbm.xml可以任意命名及放置于其他目录下,当然hibernate.cfg.xml文件也要做相应修改。笔者建议将它和它所对应的实体类放在一个包下,并用包名做文件名。
  ● <class>项定义了实体类和数据表之间的关系:name是实体类(用类全名),table是对应的数据表(表名不分大小写)。可以省略掉table属性,这时默认表名和实体类同名。在model.hbm.xml文件中可以设置多个<class>项,笔者建议将一个包中的所有实体类都集中在一个*.hbm.xml文件中。
  ● <id>项定义了主键id字段所用的键值生成方法,identity是一种MSSQL、DB2、MySQL通用的主键值生成方法(Oracle不能用identity,可换成sequence)。要了解更多内容,可以查阅Hibernate文档。
  ● <property>子项定义了实体类和表字段的关联。本例只设置了定义类字段的name属性,还有一个column属性是定义数据库表字段名的,本例没有设置。Hibernate正是通过这里的设置建立起实体类和数据库表之间的字段对应关系。本例没有设置column,则Hibernate会默认为它和name属性同名。假如,想将Grade实体类的name字段对应于数据库表的grade_name字段,并将表字段的长度定义成16、不允许空值,则可以按照如下设置:
<property name="name">
      <column name="grade_name" length="16" not-null="true"/>
</property>
  ● <property>体现Hibernate的友好性:它可以设置得很详细,也可以很简洁,当设置简洁时,Hibernate会采用默认值。要了解更多关于<property>设置的内容,可以参阅Hibernate文档。
37.3.3  创建HibernateUtil类
HibernateUtil类用于得到一个SessionFactory,而SessionFactory可以得到Session。Session是Hibernate中最重要和使用最频繁的一个对象,实体对象都是通过它来和数据库交互。这个Session和JSP的Session不同,但是有一点类似于JDBC的Connection,即Session比Connection包含的内容更多,功能范围更广。在Hibernate的编程中将不会再使用Connection,而是通过Session来和数据库交互。
HibernateUtil类的内容如下:
package cn.com.chengang.sms.db;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
         private static final SessionFactory sessionFactory;
         static {
                   try {
                            // 实例化一个SessionFactory对象
                            sessionFactory = new Configuration().configure().buildSessionFactory();
                   } catch (Throwable ex) {
                            System.err.println("Initial SessionFactory creation failed." + ex);
                            throw new ExceptionInInitializerError(ex);
                   }
         }
         public static SessionFactory getSessionFactory() {
                   return sessionFactory;
         }
}
程序说明:
  ● HibernateUtil可以任意取名。它是一个静态方法类,即类中的方法都是静态方法。
  ● SessionFactory是一个静态变量,它由static {…}静态代码块来初始化一个实例。注意,static{…}代码块比较特殊,它既不是方法也不是变量。生成一个SessionFactory对象很耗费时间和资源,所以在这里整个Web系统共用一个SessionFactory。而生成一个Session对象的代价很小,在编程中千万不要把Session写成单例模式来进行实例共享,对Session的使用原则是用完就关闭,而且要尽量早关闭。
  ● 对于旧版本的Hibernate,此类还有将Session保存/剥离到当前线程中的两个方法。但现在已经不需要了,因为这里在新版本的hibernate.cfg.xml中用current_session _context_class属性打开了Hibernate的Session自动管理机制。
37.3.4  创建GradeManager类
GradeManager类似于DbOperate,它主要提供数据库操作方法。在这里编写了向Grade表插入一条记录的方法,以及取出Grade表中id值大于2的所有记录的方法。代码如下:
package cn.com.chengang.sms.db;
public class GradeManager {
         public void insertGrade() throws HibernateException {
                   Session session = HibernateUtil.getSessionFactory().getCurrentSession();
                   session.beginTransaction();
                   Grade grade = new Grade();// 生成一个年级对象
                   grade.setName("高四");
                   session.save(grade); // 将这个对象保存到数据库
                   session.getTransaction().commit();
         }
         public List<Grade> getGrades() throws HibernateException {
                   Session session = HibernateUtil.getSessionFactory().getCurrentSession();
                   session.beginTransaction();
                   // 创建一个条件查询语句
                   String hql = "from Grade as g where g.id > :id";
                   Query query = session.createQuery(hql); // 创建查询对象
                   query.setInteger("id", 2); // 设置查询参数
                   List<Grade> result = query.list(); // 从数据库取出数据,并自动封装到List集合中
                   //也可以三句合为一句:session.createQuery(hql).setInteger("id", 2).list();
                   session.getTransaction().commit();// 提交
                   return result;// 返回数据集
         }
         public void close(){
                   HibernateUtil.getSessionFactory().close();
         }
}
程序说明:
  ● 在Session中,每个数据库操作都是在一个事务(Transaction)中进行的,这样可以隔离开不同的操作。Hibernate的事务是JDBC事务的更高层次的抽象,它提供了更好的灵活性和适应性。
  ● 无论session.getTransaction().commit()提交,或session.getTransaction().rollback()回滚都会自动关闭session。
  ● 以前都是将实体对象的字段一个个拆散并组合成SQL语句,或者从数据库取出数据后将字段值一个个封装到实体对象。现在用了Hibernate,就再也不必这么处理数据了,这是Hibernate有魅力的一面。
  ● getGrades方法中用到的hql字串不是JDBC的SQL语句,而是Hibernate自有的HQL语句。关于HQL的更多内容,可查阅Hibernate文档。
37.3.5  创建hibernateTest.jsp
hibernateTest.jsp使用GradeManager类来获得数据,并将数据显示在页面上。代码如下:
<%@ page contentType="text/html; charset=utf8"%>
<%@ page import="cn.com.chengang.sms.db.GradeManager"%>
<%@ page import="cn.com.chengang.sms.model.Grade"%>
<%
         GradeManager mgr = new GradeManager();
         //插入一个年级对象
         mgr.insertGrade();
         //取出所有年级对象,并显示在页面上
         for (Grade g : mgr.getGrades())
                   out.print(g.getId() + "  " + g.getName() + "</br>");
         mgr.close();
%>
37.3.6  总结及实践建议
以上5步完成了一个简单的Hibernate实例,用浏览器运行hibernateTest.jsp的效果如  图37.5所示。
图37.5  hibernateTest.jsp的运行效果
本节用从底层到高层的次序来完成了一个实例的讲解,它虽然简单,但也反映了一个典型Hibernate程序的编写框架:
  ● HibernateUtil一经完成之后即可系统通用,以后很少改动。
  ● XML映射文件是项目前期要做的最重要的工作,在项目开发后期就很少会改动它。对初学者来说,编写XML映射文件也是难点所在。
  ● GradeManager是数据库操作类,这相当于以前的DbOperate类的功能。但它不再直接操作数据库,而是通过Hibernate去访问,所以在GradeManager类中看不到涉及JDBC的代码。
  ● 最后,就是位于最高层的JSP文件hibernateTest.jsp,这个文件主要使用GradeManager类来操作数据库。
实践建议:
  ● Lomboz支持XML映射文件的热修改,当XML映射文件改动之后,Lomboz会将它重新装入。不过这可能需要一两秒钟时间,具体时间要视读者所用电脑性能   而定。
  ● 在Java编程中要时刻注意区分大小写,这是编程中出错较多的原因。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值