JPA2.0入門 〜JPA2.0を使った、爆速RDB設計〜
事前準備
NetBeansをインストール。
http://netbeans.org/downloads/index.html?pagelang=ja からNetBeans7.2のJavaEEバンドル版をダウンロードしてインストール。
インストール時のウィザードでJUnitとGlassFishもインストールする。
NetBeansでJPA用のプロジェクトを作成
NetBeansのメニュー→ファイル→新規プロジェクト→Maven→Javaアプリケーション
作成したプロジェクト内にあるpom.xmlの
pom.xmlを修正したら、プロジェクトを右クリック→ビルドを実行し、必要なライブラリをダウンロードする。
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.3</version> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derbyclient</artifactId> <version>10.6.2.1</version> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>10.6.2.1</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId> <version>2.3.2</version> <scope>provided</scope> </dependency> </dependencies>
DB接続に必要なpersistence.xmlは、最初のエンティティを作るときにウィザードで名前と場所を入力する画面で、持続性ユニットの作成チェックボックスにチェックを入れると作成用のウィザードが表示される。
persistence.xml作成のウィザードでは次を選択・入力する。
RDBテーブルを設計し、Entityクラスを作成する。
設計手法は次の書籍の内容をそのまま使えばOK。最も早く確実にDBテーブルを設計できる手法が解説されている。
- 作者: (株)スターロジック羽生章洋
- 出版社/メーカー: 翔泳社
- 発売日: 2006/04/18
- メディア: 単行本
- 購入: 72人 クリック: 934回
- この商品を含むブログ (119件) を見る
Entityクラスの作成手順は楽々ERDレッスン (CodeZine BOOKS)で解説されているように、次の通りになる。
イベントとリソースを抜きだす→イベントとリソースに項目(プロパティ)を追加していく→イベントとリソースのリレーションを設定する。
NetBEansを使ったEntityクラスの作り方
- 作成したプロジェクトのソース・パッケージの上で右クリック→新規→エンティティ・クラス でidプロパティだけを持つEntityクラスが生成されるので、それに必要なプロパティを追加する。
それらのプロパティを設定できるコンストラクタを追加しておくと便利。
- 書籍の中では各テーブルに付ける識別子の項目名を「テーブル名+ID」にしているが、JPAでは全てIDにして問題無し。
- リレーションの設定を行う。FK(外部キー)を設定する代わりに、対象となるEntityクラスをプロパティとして設定し、アノテーションを付加する。
- リファクタリング→フィールドをカプセル化 で必要なsetter・getterを作成する。
- ビルドを実行し、エラーが出なければ完成。サービスタブをクリックして、JavaDBの中を見てみればテーブルが作成されているのが判る。
楽々ERDレッスン (CodeZine BOOKS)のP.126から説明されている「お持ち帰りご注文用紙」をJPA2.0で設計したのが以下のコード。コンストラクタ、getter/setter は省略。
@Entity public class Customers implements Serializable { // Customers と OrdersはOrderがCustomersを持つ一方向の一対一。 // だからCustomer側にはリレーションの設定は不要。 private String name; private String tel; } @Entity public class Orders implements Serializable { // CustomersとOrdersは、OrdersがCustomersを持つ一方向の一対一。 // このリレーションは自動解決されるので、@OneToOne は無くてもOK。 @OneToOne private Customers customer; // OrdersとProductsはOrdersが複数のProductsを所有する一方向の一対多。 @OneToMany private List<Products> products; @Column(length=100) private int orderNums; } @Entity public class Products implements Serializable { // OrdersとProductsはOrdersが複数のProductsを所有する一方向の一対多。 // 一方向なので、Productsからのリレーション設定は不要。 // ProductとProductCategoryは、ProductsがProductCategoryを所有する一方向の一対一。 private ProductCategory productCategory; //長さを指定しない場合はデフォルトでVARCHAR(200)にマッピングされる。 private String name; private BigDecimal price; private BigDecimal TaxIncludedPrice; } @Entity public class ProductCategory implements Serializable { // ProductsとProductCategoryは、ProductsがProductCategoryを所有する一方向の一対一。 // 一方向なので、Productsからのリレーション設定は不要。 private String name; }
リレーションの設定に使うアノテーションは次の四つだけで充分。
どのアノテーションも一方向の関係を表すのに使え、mappedBy属性を指定できるアノテーションは双方向の関係を表すのに使う。双方向の場合はどちらか一方を、もう片方の所有者として、mappedBy属性を指定する必要がある。
@OneToOne(mappedBy)
@OneToMany(mappedBy)
@ManyToOne
@ManyToMany(mappedBy)
これらのアノテーションには登録や削除をカスケードに行うように指定するためのcascae属性も指定できる。
JPA2.0で必須のアノテーションは先に挙げたリレーションの設定用と以下のコードに存在するものだけ。
これ以外のアノテーションは既存のDBをJPAにマッピングするために存在するようなものなので、覚える必要は無い。
@Entity //テーブル名を指定するアノテーション。 @Table(name="T_CUSTOMER") // このエンティティに関するキャッシュを無効化。キャッシュの設定はpersistence.xmlの<shared-cache-mode>属性で設定する。 @Cashable(false) public class Customer implements Serializable { // 双方向の一対多。mappedByで所有者指定する。 // cascade属性で登録時と削除時のカスケードを指定している。 // cascadeはEntityManager APIの呼び出しを減らせる。 // しかし不要なテーブル結合などコストのかかるDB呼び出しを引き起こす可能性があるため、 // 明確にカスケードが必要だと判断できる時以外は使うべきでは無い。 // fetch属性で即時フェッチを指定している。@OneToManyのデフォルトFetchはLAZY。 @OneToMany(mappedBy = "politician", cascade={CascadeType.PERSIST, CascadeType.REMOVE}, fetch= FetchType.EAGER) // リレーションの順序を指定している。nameで降順、noteで昇順の順序をつけるように指定している。 @OrderBy("name DESC, note ASC") private List<People> peoples; /*BlobやCLobへのマッピング */ @Lob private byte[] image; /* 日付、時刻、タイムスタンプ型へのマッピング */ @Temporal(TemporalType.DATE) private Date since; // バージョニングに使用するプロパティ。このプロパティの更新はJPAが自動で行う。 // LongやTimestampクラスも指定することが出来る。 // このエンティティが同時に変更される可能性がある場合は必須。 @Version private Integer version; /* 主キーと示すためのアノテーション。ウィザードで自動生成されるので触れる必要無し */ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;