[[HOME>http://www.trance.co.jp/]] > [[技術情報]] > [[Java>http://www.trance.co.jp/wiki/index.php?%B5%BB%BD%D1%BE%F0%CA%F3#xe479566]] > Java Persistence API
* Java Persistence API 1.0(JPA) [#p067abdd]
#contents
** Java Persistence APIとは [#ye590c98]
- Javaオブジェクトの永続化のためのAPI
以前はEJBの仕様に含まれていたものが、EJB3.0より切り離され、EJBコンテナ以外での使用が可能となった.
また、O/Rマッピング、アノテーションを使用することにより、以前のEJBのような複雑な仕組みではなく、よりPOJOとして開発できるようになった.

** 特徴 [#s2f8465e]
- ''アノテーションによるマッピング''
-- XML設定ファイル減
-- コード量減
- ''4つのエンティティ状態(ライフサイクル)''
|~状態|~説明|~Persistent Indentity|~Persistence Context|
|&color(blue){''new''};|Entityが生成された状態|持たない|結びつきなし|
|&color(blue){''managed''};|EntityがEntityManagerに管理されている状態|持つ|結びつきあり|
|&color(blue){''removed''};|Entityが削除予約となっている状態|持つ|結びつきあり|
|&color(blue){''detached''};|Entityがデータベースと関連がなくなった状態|持つ|結びつきなし|
 

** 実装プロダクト [#h478525f]
Java Persistence APIは仕様であるため、実装プロダクトがいくつか存在する.
- Hibernate
- TopLink
- OpenJPA

** 使用方法 - 準備 (実装プロダクト:Hibernate) [#hc112776]
今回は、実装プロダクトとして、「Hibernate」を使用する.
*** インストール [#zf7238d6]
- ''ダウンロード''
以下のサイトより、3つのパッケージをダウンロードする.
サイト:http://www.hibernate.org/
パッケージ (2007/09/13時点)
-- Hibernate Core 3.2.5.ga
-- Hibernate Annotations 3.3.0 GA
-- Hibernate EntityManager 3.3.1 GA

- ''クラスパスを通す''
それぞれのパッケージは多くのライブラリに依存しているため、必要なライブラリ全てクラスパスを通す.
必要であるかは、同封のドキュメントにて確認する.
今回は実行時に必要なライブラリのみパスを通す.
-- Hibernate Core 3.2.5.ga
--- jta.jar
--- commons-logging-1.0.4.jar
--- xml-apis.jar
--- asm-attrs.jar
--- dom4j-1.6.1.jar
--- antlr-2.7.6.jar
--- cglib-2.1.3.jar
--- asm.jar
--- jdbc2_0-stdext.jar
--- xerces-2.6.2.jar
--- jaxen-1.1-beta-7.jar
--- commons-collections-2.1.1.jar
--- javassist.jar
--- hibernate3.jar

-- Hibernate Annotations 3.3.0 GA
--- hibernate-annotations.jar
--- ejb3-persistence.jar
--- hibernate-commons-annotations.jar

-- Hibernate EntityManager 3.3.1 GA
--- hibernate-entitymanager.jar
--- hibernate-validator.jar
--- jboss-archive-browsing.jar

*** 設定ファイル - persistence.xml [#k3cbb4f0]
&color(blue){''persistence.xml''};と言うファイルを作成し、DB等の設定を定義する.
ファイルの配置場所は、クラスパスの通った「META-INF」配下に配備する.
META-INF/persistence.xml
以下のサンプルはDBにMySQLを使用した例.
|[DB_ID]|ユーザID|
|[DB_PASSWORD]|パスワード|
|[DB_IP]|DBのIP|
|[DB_PORT]|DBのポート|
|[DB_DBNAME]|使用するDB名|

 <?xml version="1.0" encoding="UTF-8"?>
 <persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="jpa-sample" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>sample.entity.User</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.username" value="[DB_ID]" />
            <property name="hibernate.connection.password" value="[DB_PASSWORD]" />
            <property name="hibernate.connection.url" value="jdbc:mysql://[DB_IP]:[DB_PORT]/[DB_DBNAME]" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.use_sql_comments" value="true" />
            
        </properties>
    </persistence-unit>
 </persistence>

- ''解説''
-- &color(blue){''<class>''}; - ''EntityBeanクラスの定義''
パッケージ名を含むクラス名を定義することで、JPAで使用するEntityBeanとみなされる.

-- &color(blue){''<properties>''}; - ''JDBC接続情報の定義''
Hibernateの''<property>''タグのname属性値
|~<property>タグのname属性値|説明|
|hibernate.dialect|使用するDBクラス|
|hibernate.connection.driver_class|DBドライバクラス|
|hibernate.connection.username|ユーザ名|
|hibernate.connection.password|パスワード|
|hibernate.connection.url|DBのURL|
|hibernate.hbm2ddl.auto|自動的にDDLを有効にしデータベース出力する&br;validate:&br;update:&br;create:&br;create-drop:|
|hibernate.show_sql|ログにSQLを表示するか&br;true:表示する&br;false:表示しない|
|hibernate.format_sql|ログに表示したSQLをフォーマットするか&br;true:フォーマットする&br;false:フォーマットしない|
|hibernate.use_sql_comments|SQLコメントを表示するか&br;true:表示する&br;false:表示しない|


** 使用方法 - 実装 (単独テーブルへの追加、変更、削除、参照)[#ycd1e543]
以下のテーブルを操作するサンプルを作成する.
''テーブル名:User''
|~フィールド|~種別|~主キー|
|id|varchar(255)|●|
|age|int(11)||
|name|varchar(255)||

*** Entity Bean [#x982fa42]
EntityBeanを作成する.

 import java.io.Serializable;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
 @Entity
 @Table(name="User")
 public class User implements Serializable {
 	@Id
 	@Column(name="id")
 	private String id;
 
 	@Column(name="name")
 	private String name;
 
 	@Column(name="age")
 	private int age;
  	
 	public int getAge() {
 		return age;
 	}
 	public void setAge(int age) {
 		this.age = age;
 	}
 	public String getId() {
 		return id;
 	}
 	public void setId(String id) {
 		this.id = id;
 	}
 	public String getName() {
 		return name;
 	}
 	public void setName(String name) {
 		this.name = name;
 	}
 	
 }

- ''解説''
ユーザ情報を保持するためのユーザクラス(POJO)を作成し、以下のアノテーションを定義することで、EntityBeanとなる.
-- &color(blue){''@Entity''}; - ''Entity Beanであることを定義''
クラス定義の前に「@Entity」を記述し、「Entity Bean」であることを定義する.

-- &color(blue){''@Table(name="User")''}; - ''このEntity Beanとマッピングするテーブル名を定義''
クラス定義の前に「@Table(name="User")」を記述し、name要素にマッピングするテーブル名記述する.
クラス名テーブル名が同じ場合は、&color(red){「@Table(name="User")」は省略できる.};

-- &color(blue){''@Id''}; - ''Primary Keyを定義''
「Primary Key」となるインスタンス変数に定義する.

-- &color(blue){''@Column(name="id")''}; - ''このインスタンス変数とマッピングするカラム名を定義''
インスタンス変数定義の前に「@Column(name="id")」を記述し、name要素にマッピングするカラム名を記述する.
インスタンス変数名とカラム名が同じ場合は、&color(red){「@Column(name="id")」は省略できる.};

*** EntityManager [#t9605dc6]
EntityManagerは、Entity Beanの永続性を管理するためのオブジェクト.
EntityManagerは以下のようにして取得する.

 // 永続化
 EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-sample");
 EntityManager entityManager = factory.createEntityManager();

- ''解説''
-- &color(blue){''Persistence.createEntityManagerFactory("jpa-sample");''}; - ''EntityManagerFactoryを取得''
Persistence#createEntityManagerFactory()を使用し、EntityManagerFactoryを取得する.
引数に、設定ファイル「persistence.xml」で記述した「persistence-unit name="jpa-sample"」の「jpa-sample」を渡す.

*** サンプル [#s31d4867]
データベースへの、新規追加(Insert)、更新(Update)、削除(Delete)、参照(find)のサンプル(Junit4.4).
設定ファイル(persistence.xml)は、上記の設定とする.

 package sample;
 import static org.junit.Assert.*;
 import static org.hamcrest.CoreMatchers.*;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Persistence;
 
 import org.junit.Test;
 
 import sample.entity.User;
 
 public class JpaHibernateTest {
 	private static final String PERSISTENCE_UNIT_NAME = "jpa-sample1";
 	
 	/**
 	 * 新規追加(Insert)
 	 */
 	@Test
 	public void insert() {
 		// 永続化
 		// ------------------------------
 		EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
 		EntityManager entityManager = factory.createEntityManager();
 		
 		// データの追加
 		// ************************************
 		
 		// EntityBeanをnew 
 		// ライフサイクル:new
 		// ------------------------------
 		User user = new User();
 		user.setId("1");
 		user.setName("Insert");
 		user.setAge(10);
 	
 		// Insert
 		// ライフサイクル:managed
 		// ------------------------------
 		entityManager.getTransaction().begin();
 		entityManager.persist(user);
 		entityManager.getTransaction().commit();
 		
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 	
 		
 		// 確認
 		// ************************************
 		User actual = entityManager.find(User.class, "1");
 		assertThat(actual.getId(), is("1"));
 		assertThat(actual.getName(), is("Insert"));
 		assertThat(actual.getAge(), is(10));
 	}
 
 	/**
 	 * 更新(Update)
 	 */
 	@Test
 	public void update() {
 		// 永続化
 		// ------------------------------
 		EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
 		EntityManager entityManager = factory.createEntityManager();
 		
 		// データの追加
 		// ************************************
 		
 		// EntityBeanをnew 
 		// ライフサイクル:new
 		// ------------------------------
 		User user = new User();
 		user.setId("1");
 		user.setName("Insert");
 		user.setAge(10);
 	
 		// Insert
 		// ライフサイクル:managed
 		// ------------------------------
 		entityManager.getTransaction().begin();
 		entityManager.persist(user);
 		entityManager.getTransaction().commit();
 		
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 	
 		
 		// データの更新
 		// ************************************
 		
 		// Select
 		// ライフサイクル:managed
 		// ------------------------------				
 		User user2 = entityManager.find(User.class, "1");
 		user2.setName("Update");
 		
 		// Update
 		// ライフサイクル:managed
 		// ------------------------------		
 		entityManager.getTransaction().begin();
 		entityManager.merge(user2);
 		entityManager.getTransaction().commit();
 	
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 		
 		
 		// 確認
 		// ************************************
 		User actual = entityManager.find(User.class, "1");
 		assertThat(actual.getName(), is("Update"));
 	}
 
 	/**
 	 * 削除(Delete)
 	 */
 	@Test
 	public void delete() {
 		// 永続化
 		// ------------------------------
 		EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
 		EntityManager entityManager = factory.createEntityManager();
 		
 		// データの追加
 		// ************************************
 		
 		// EntityBeanをnew 
 		// ライフサイクル:new
 		// ------------------------------
 		User user = new User();
 		user.setId("1");
 		user.setName("Insert");
 		user.setAge(10);
 
 		// Insert
 		// ライフサイクル:managed
 		// ------------------------------
 		entityManager.getTransaction().begin();
 		entityManager.persist(user);
 		entityManager.getTransaction().commit();
 		
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 
 		
 		// データの削除
 		// ************************************
 		
 		// Select
 		// ライフサイクル:managed
 		// ------------------------------				
 		User user2 = entityManager.find(User.class, "1");
 		
 		// Delete
 		// ライフサイクル:removed
 		// ------------------------------		
 		entityManager.getTransaction().begin();
 		entityManager.remove(user2);
 		entityManager.getTransaction().commit();
 
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 		
 		
 		// 確認
 		// ************************************
 		User actual = entityManager.find(User.class, "1");
 		assertThat(actual, nullValue());
 	}
 
 	/**
 	 * 主キーによる参照(Select)
 	 */
 	@Test
 	public void selectByPk() {
 		// 永続化
 		// ------------------------------
 		EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
 		EntityManager entityManager = factory.createEntityManager();
 		
 		// データの追加
 		// ************************************
 		
 		// EntityBeanをnew 
 		// ライフサイクル:new
 		// ------------------------------
 		User user = new User();
 		user.setId("1");
 		user.setName("Insert");
 		user.setAge(10);
 	
 		// Insert
 		// ライフサイクル:managed
 		// ------------------------------
 		entityManager.getTransaction().begin();
 		entityManager.persist(user);
 		entityManager.getTransaction().commit();
 		
 		// 管理していたEntityBeanをクリア
 		// ライフサイクル:detached
 		// ------------------------------		
 		entityManager.clear();
 	
 		
 		// Select
 		// ライフサイクル:managed
 		// ------------------------------
 		User actual = entityManager.find(User.class, "1");
 		
 		// 確認
 		// ************************************
 		assertThat(actual.getId(), is("1"));
 		assertThat(actual.getName(), is("Insert"));
 		assertThat(actual.getAge(), is(10));
 	}
 }



- ''解説''
-- &color(blue){''DBアクセス''};
|Insert|EntityManager#persist(Object[EntityBean]));|
|Update|EntityManager#merge(Object[EntityBean]);|
|Delete|EntityManager#remove(Object[EntityBean]);|
|Select (Primary Key)|EntityManager#find(EntityClass, String[primary key]);|

-- &color(blue){''トランザクション''};
|トランザクション開始|EntityManager#getTransaction()#begin();|
|コミット|EntityManager#getTransaction()#commit();|
|ロールバック|EntityManager#getTransaction()#rollback();|

*** サンプルダウンロード [#ffb1d2a1]
- [[jpa_hibernate-sample.zip[6.4MB]>http://www.trance.co.jp/wiki/index.php?down=jpa_hibernate-sample.zip]]
//** アノテーション一覧 [#jd01ea3f]
//|@Entity||
//|@Id||
//|@Column||

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS