首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

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)条】

最近评论



正在载入评论列表...
热点评论