返回介绍

1.3 Hibernate

发布于 2025-04-26 13:08:31 字数 5487 浏览 0 评论 0 收藏

最初 SUN 公司推出了 Java EE 服务器端组件模型(EJB),但是由于 EJB 配置复杂,且适用范围较小,于是很快就被淘汰了。与 EJB 的失败伴随而来的是另外一个框架的应运而生。它就是从诞生至今都十分流行的 Hibernate。

Hibernate 一问世就成了 Java 世界首选的 ORM 模型,它是建立在 POJO 和数据库表模型的直接映射关系上的。

Hibernate 是建立在若干 POJO 通过 XML 映射文件(或注解)提供的规则映射到数据库表上的。换句话说,我们可以通过 POJO 直接操作数据库的数据。它提供的是一种全表映射的模型。如图 1-2 所示是 Hibernate 模型的开发过程。相对而言,Hibernate 对 JDBC 的封装程度还是比较高的,我们已经不需要编写 SQL 语言(Structured Query Language),只要使用 HQL 语言(Hibernate Query Langurage)就可以了。

015_0001

图 1-2 Hibernate 模型的开发过程

首先我们需要提供 hbm.xml 文件,制定映射规则。下面以开发角色类为例进行讲解,如代码清单 1-2 所示。

代码清单 1-2:TRole.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 2015-12-12 22:50:58 by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="com.learn.mybatis.chapter1.po.TRole" table="t_role" catalog="mybatis" optimistic-lock="version">
        <id name="id" type="long">
            <column name="id" />
            <generator class="assigned" />
        </id>
        <property name="roleName" type="string">
            <column name="role_name" length="60" />
        </property>
        <property name="note" type="string">
            <column name="note" length="512" />
        </property>
    </class>
</hibernate-mapping>

这是一个简单的 XML 文件,它描述的是 POJO 和数据库表的映射关系。Hibernate 通过配置文件(或注解)就可以把数据库的数据直接映射到 POJO 上,我们可以通过操作 POJO 去操作数据库记录。对于不擅长 SQL 的程序员来说,这是莫大的惊喜,因为通过 Hibernate 你几乎不需要编写 SQL 就能操作数据库的记录。代码清单 1-3 是 Hibernate 的配置信息。

代码清单 1-3: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="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mybatis?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">learn</property>
    <mapping resource="com/learn/mybatis/chapter1/po/TUser.hbm.xml"/>
    <mapping resource="com/learn/mybatis/chapter1/po/TRole.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

别看代码很多,但是全局就是这样的一个 XML 文件,作为数据库连接信息,配置信息也相对简易。然后建立 Hibernate 的工厂对象(SessionFactory),用它来做全局对象,产生 Session 接口,就可以操作数据库了,如代码清单 1-4 所示。

代码清单 1-4:HibernateUtil

public class HibernateUtil {
    private static final SessionFactory sessionFactory;
    static {
        try {
            Configuration cfg = new Configuration().configure ("hibernate.cfg.xml");
            sessionFactory = cfg.buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

上面的操作为的是产生 Hibernate 的 SessionFactroy。它作为全局,可以到处引用,那么剩下来的使用就非常简单了。比如我们可以用它来实现代码清单 1-1 的功能,如代码清单 1-5 所示。

代码清单 1-5:HibernateExample.java

public class HibernateExample {
    public static void main(String[] args) {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            TRole role = (TRole)session.get(TRole.class, 1L);
            System.err.println("role_name = >" + role.getRoleName());
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

按照代码清单 1-5 的方法来实现代码清单 1-1 的功能有以下好处:

  • 消除了代码的映射规则,它全部被分离到了 XML 或者注解里面去配置。

  • 无需再管理数据库连接,它也配置在 XML 里面。

  • 一个会话中,不要操作多个对象,只要操作 Session 对象即可。

  • 关闭资源只需要关闭一个 Session 便可。

这就是 Hibernate 的优势,在配置了映射文件和数据库连接文件后,Hibernate 就可以通过 Session 操作,非常容易,消除了 JDBC 带来的大量代码,大大提高了编程的简易性和可读性。此外,它还提供级联、缓存、映射、一对多等功能,以便我们使用。正因为具有这些优势,Hibernate 成为了时代的主流框架,被大量应用在各种 Java 数据库的访问中。Hibernate 是全表映射,你可以通过 HQL 去操作 POJO 进而操作数据库的数据。

但是 Hibernate 有缺陷吗?当然有,世界上没有完美无缺的方案。作为全表映射框架,举个例子来说,如果我们有张账务表(按年分表),比如 2015 年表命名为 bill2015,到了 2016 年表命名为 bill2016,要动态加映射关系,Hibernate 需要破坏底层封装才能做到。又比如说,一些账务信息往往需要和某些对象关联起来,不同的对象有不同的列,因此列名也是无法确定的,显然我们没有办法配置 XML 去完成映射规则。再者如果使用存储过程,Hibernate 也是无法适应的。这些都不是致命的,最为致命的问题是性能。Hibernate 屏蔽了 SQL,那就意味着只能全表映射,但是一张表可能有几十到上百个字段,而你感兴趣的只有 2 个,这是 Hibernate 无法适应的。尤其是在大型网站系统,对传输数据有严格规定,不能浪费带宽的场景下就更为明显了。有很复杂的场景需要关联多张表,Hibernate 全表逐级取对象的方法也只能作罢,写 SQL 还需要手工的映射取数据,这带来了很大的麻烦。此外,如果我们需要优化 SQL,Hibernate 也是无法做到的。

我们稍微总结一下 Hibernate 的缺点:

  • 全表映射带来的不便,比如更新时需要发送所有的字段。

  • 无法根据不同的条件组装不同的 SQL。

  • 对多表关联和复杂 SQL 查询支持较差,需要自己写 SQL,返回后,需要自己将数据组装为 POJO。

  • 不能有效支持存储过程。

  • 虽然有 HQL,但是性能较差。大型互联网系统往往需要优化 SQL,而 Hibernate 做不到。

在当今大型互联网中,灵活、SQL 优化,减少数据的传递是最基本的优化方法,显然 Hibernate 无法满足我们的要求。这时 MyBatis 框架诞生了,它提供了更灵活、更方便的方法,弥补了 Hibernate 的这些缺陷。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。