Hibernate とりあえず使ってみた

なんとなく Hibernate 使ってみたので、ひとまずメモしておきます。

HibernateJPA ( Java Persistence API : 永続化、Java オブジェクトとリレーショナルデータベースのマッピング ) の実装になります。

Hibernate ORM
http://hibernate.org/orm/

今回はとりあえず使うってところで、チュートリアルを参考 ( ほぼそのまま ) にしてやってみました。

・Chapter 1. Tutorial
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch01.html

チュートリアルに従って以下の手順でやってみます。
0. pom.xml の作成
1. データベースとマッピングする Java クラス
2. マッピングファイル
3. Hibernate 定義ファイル
4. SessionFactory 生成するユーティリティクラス ( 今回みたいな小さいものなら Main クラスでやっても・・・ )
5. Main クラス


0. pom.xml の作成

Maven 使うので pom.xml の dependencies に Hibernate と、今回データベースは PostgreSQL を使ったので PostgreSQLJDBC を追加する。

■ pom.xml

    <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-core</artifactId>
     <version>4.3.8.Final</version>
    </dependency>

    <dependency>
	 <groupId>postgresql</groupId>
	 <artifactId>postgresql</artifactId>
	 <version>9.0-801.jdbc4</version>
    </dependency>


1. データベースとマッピングする Java クラス

■ Person.java

package com.example.domain;

public class Person {
	private int id;
	private String name;

	public int getId() { return id; }

	public void setId(int id) { this.id = id; }

	public String getName() { return name; }

	public void setName(String name) { this.name = name; }
}

データベース ( 今回は PostgreSQL ) にテーブルを作成しておく。

create table t2 (id int primary key, name varchar(50));


2. マッピングファイル

■ Person.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.example.domain">
  <class name="Person" table="T1">
    <id name="id" column="id"/>
    <property name="name"/>
  </class>
</hibernate-mapping>


3. Hibernate 定義ファイル

設定の意味等はちょっとわかってませんが、ひとまずチュートリアルの通りで、PostgreSQL に関連する箇所だけ変えてます。

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://127.0.0.1:5432/testdb</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <mapping resource="com/example/domain/Person.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

PostgreSQLDialect は Dialect のサブクラスで、データベース特有の SQL の違いを吸収してくれるって感じなんですかね。

・Dialect (Hibernate JavaDocs)
https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/dialect/Dialect.html

ドキュメントには、各設定値についてより適切なデフォルト値を使うようにしますよ、とも書いてます。

・Chapter 3. Configuration
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch03.html#configuration-optional-dialects


4. SessionFactory 生成するユーティリティクラス

■ HibernateUtil.java

package com.example.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		try {
			Configuration configuration = new Configuration();
			configuration.configure("hibernate.cfg.xml");
			ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
					.applySettings(configuration.getProperties()).build();
			SessionFactory sessionFactory = configuration
					.buildSessionFactory(serviceRegistry);
			return sessionFactory;

		} catch (Throwable ex) {
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}


5. Main クラス

データの永続化と検索を行なってます。

■ PersonManager.java

package com.example;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.example.domain.Person;
import com.example.util.HibernateUtil;

public class PersonManager {
	public static void main(String[] args) {
		new PersonManager().createAndStoreEvent();
		HibernateUtil.getSessionFactory().close();
	}

	private void createAndStoreEvent() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		// Person オブジェクトの永続化
		Person p1 = new Person();
		p1.setId(1);
		p1.setName("hoge");
		session.persist(p1);
		
		Person p2 = new Person();
		p2.setId(2);
		p2.setName("uga");
		session.persist(p2);
		
		// データの検索
		// 全件取得
		List<Person> persons = session.createCriteria(Person.class).list();
		for(Person p : persons) {
			System.out.println(p.getId() + ":" + p.getName());
		}

		// 条件指定して取得
		Criteria criteria = session.createCriteria(Person.class).add(Restrictions.eq("id", 2));
		Person p = (Person)criteria.uniqueResult();
		System.out.println(p.getId() + ":" + p.getName());
		
		session.getTransaction().commit();
	}
}

・Session (Hibernate JavaDocs)
https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/Session.html

■ 実行結果

*****
Hibernate: insert into T1 (name, id) values (?, ?)
Hibernate: insert into T1 (name, id) values (?, ?)
Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_ from T1 this_
  1:hoge
  2:uga
*****
Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_ from T1 this_ where this_.id=?
  2:uga

ちゃんと動いてそうですね。

以上です。

[ 環境情報 ]
Windows 7 SP1
Java SE 7 Update 51
Hibernate 4.3.8.Final
PostgreSQL 9.0.4
PostgreSQL JDBC Driver 9.0-801