HelloWorld of Hibernate with Native API

通过 Hibernate Native API 写 HelloWorld 一般有如下几个步骤:

1. 创建 SessionFactory 实例(一般通过读取配置文件 hiberante.cfg.xml)

2. 创建 session

3. 开启事务 transaction

4. 编写事务内容

5. 提交事务

6. 关闭 session

7. 关闭 SessionFactory 实例。

workflow of hibernate with native api

以上是一个典型的 Hiberante 本地执行流程,这里具体写一个例子说明这些关系

创建项目

先用 Eclipse 创建一个 Java 项目

然后转成 maven 工程:右键单击项目属性,Configure -> Convert to Maven Projects...

(如果用 IntelliJ IDEA, 可以通过选中项目,右键单击,选择 Add Frameworks Support...,选择 Maven 支持。)

pom.xml 添加 hibernate 和 mysql driver 的依赖,内容如下:

 <dependencies>
     <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>4.3.5.Final</version>
          <type>jar</type>
          <scope>compile</scope>
     </dependency>
     <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.30</version>
     </dependency>
</dependencies>

创建好项目后,按是否使用 Annotation 分为两种使用方式。下面分别就这两种不同的使用方式各举一例。

老式做法:完全使用配置文件

1. 实体类和配置文档

实体类(Entity)

public class Event {
     private Long id;
     private String title;
     private Date date;
     public Event() {
          // this form used by Hibernate
     }
     public Event(String title, Date date) {
          // for application use, to create new events
          this.title = title;
          this.date = date;
     }
... getters and setters
}

对应的配置文档:

<?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">
<hibernate-mapping package="org.iridium.hlearning.entity">
    <class name="Event" table="EVENTS">
        <id name="id" column="EVENT_ID">
            <generator class="increment"/>
        </id>
        <property name="date" type="timestamp" column="EVENT_DATE"/>
        <property name="title"/>
    </class>
</hibernate-mapping>

2. hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
     <session-factory>
          <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
          <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
          <property name="connection.url">jdbc:mysql://localhost:3306/hlearning?useUnicode=true&amp;characterEncoding=UTF-8</property>
          <property name="connection.username">pis</property>
          <property name="connection.password">123456</property>
          <property name="show_sql">true</property>
          <property name="generate_statistics">true</property>
          <property name="current_session_context_class">jta</property>   
          <property name="hbm2ddl.auto">create</property>         
         
          <mapping resource="org/iridium/hlearning/entity/Event.hbm.xml"/>
     </session-factory>
</hibernate-configuration>

注:

hibernate.cfg.xml 的模板可以在 {hibernate release package home}/project/etc 中找到。

强烈推荐使用 IntelliJ IDEA 编辑此文件,属性提示非常方便,如果用 eclipse 可能需要手工配置,很麻烦。

3. HelloWorld

public class HelloWorld {
     public static void main(String[] args) {
          SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); //注1
          Session session = sessionFactory.openSession();
          session.beginTransaction();
          session.save(new Event("Our very first event! 第一条记录", new Date()));
          session.save(new Event("A follow up event! 第二条记录", new Date()));
          session.getTransaction().commit();
          session.close();
         
          session = sessionFactory.openSession();
          session.beginTransaction();
          List result = session.createQuery(" from Event").list();
          for (Event event: (List<Event>) result) {
               System.out.println("Event (" + event.getDate() + "): " + event.getTitle());
          }
          session.getTransaction().commit();
          session.close();

sessionFactory.close();

     }
}

代码如附件 helloworldofhibernate.7z

注1:

这里将 hibernate.cfg.xml 放置在默认位置,如果要改变 hibernate.cfg.xml 的位置,相应地,这里也要做出变化:

new Configuration().configure("/confs/hibernate.cfg.xml")

配置文件的路径不能使用绝对路径。

改进做法:使用 Annotation

如果用 Hibernate 的 Annotation 取代上面的配置文件,可以大大简化程序配置工作。

1. 只简化表的映射文件

在本例中,即简化 EVENTS 表对应的配置工作。这种方式和前面的方式,仅有几项改动:

1. 删除 Event.hbm.xml

2. 为 Event.java 增加标注:

@Entity
@Table(name = "EVENTS")
public class Event {
     private Long id;
     private String title;
     private Date date;
     public Event() {
          // this form used by Hibernate
     }
     public Event(String title, Date date) {
          // for application use, to create new events
          this.title = title;
          this.date = date;
     }
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "EVENT_ID")
     public Long getId() {
          return id;
     }
     private void setId(Long id) {
          this.id = id;
     }
     @Column(name="EVENT_DATE")
     public Date getDate() {
          return date;
     }
// ... other getters and setters
}

3. 修改 hibernate.cfg.xml 的配置。

相对于前面的示例,只需要将

<mapping resource="org/iridium/hlearning/entity/Event.hbm.xml"/>

变成

<mapping class="org.iridium.hlearning.entity.Event"/>

即可。

这种使用 hibernate.cfg.xml 配置,但实体类使用 Annotation 的方式,是我最喜欢的做法。

代码如附件 helloworldofhibernate2.7z

2. 完全零配置(不推荐)

理论上因为 Hibernate 支持 Annotation,可以去除所有的配置文件。那么,再对上面的示例做进一步修改:

// contained in HelloWorld.java

// ...

    Configuration cfg = new Configuration()
//        .addClass(org.iridium.hlearning.entity.Event.class)
        .addAnnotatedClass(org.iridium.hlearning.entity.Event.class)
        .setProperty("hibernate.connection.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
        .setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver")
        .setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hlearning?useUnicode=true&amp;characterEncoding=UTF-8")
        .setProperty("hibernate.connection.username", "pis")
        .setProperty("hibernate.connection.password", "123456")
        .setProperty("hibernate.show_sql", "true")
        .setProperty("hibernate.generate_statistics", "true")
        .setProperty("hibernate.current_session_context_class", "jta")
        .setProperty("hibernate.hbm2ddl.auto", "create");
    SessionFactory sessionFactory = cfg.buildSessionFactory();
// ...

可见配置信息都通过 Configuration 的方法写进去了。这里需要注意的是:

  1. 配置名称,相对 hibernate.cfg.xml 的写法,都加上了 hibernate 字头,如方言类型,在 hibernate.cfg.xml 中是 connection.dialect, 这里就需要使用 hibernate.connection.dialect
  2. addClass() 和 addAnnotationClass() 特别需要留意,前者的实体类,使用旧的配置文件方式,后者的实体类使用 Annotation. 可参阅相应的 API 说明文档:http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/cfg/Configuration.html

这种将 hibernate.cfg.xml 也去配置化的方式,并非哥喜欢的方式,仅为示例而已,表明当前的 Hibernate 有这个功能。

后记

本例参考并借用了官方网站的 Quick Start:http://docs.jboss.org/hibernate/orm/4.2/quickstart/en-US/html/ 和官方的 Developer Guide 第一章。