[[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||