menu
書いてる野郎
orebike@gmail.com
実際のエンティティの使ったデータの取得はS2JDBC/クエリを投げる(タイプセーフ)を参照
S2JDBCでクエリを特殊マッピングできる特別なDTO・・・兼、DBの定義情報ということでいいかな
基本的にこうやって作る。
ユーザーエンティティを作ると想定すると↓みたいになる
package com.hoge.piyo.entity; import java.io.Serializable; import java.util.List; import javax.annotation.Generated; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; /** idプロパティ */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(precision = 10, nullable = false, unique = true) public Integer id; /** nameプロパティ */ @Column(length = 100, nullable = true, unique = false) public String name; }
後に使うS2JDBC/S2JDBC-Genのコードジェネレートの関係でパッケージを分けても同一名称のEntityを作ることはできない。
@Entity
アノテーションを使うことでこのクラスがエンティティのクラスであることを宣言する
@Entity public class User implements Serializable {
通常はエンティティクラス名をuppercaseしたものが自動決定されるが、明示的に指定したい場合は
@Entity @Table(name="hoge") public class User implements Serializable {
このように明示的に@Table
アノテーションで指定すると大文字のUSER
テーブルではなく小文字のhoge
テーブルを操作するエンティティとなる。
メンバはpublicフィールドとして宣言し、その名前のuppercaseのキャメル→スネークが自動的にカラム名として採用される。
hogePiyo
ならばHOGO_PIYO
テーブルに対応する
もし文字列型の長さ100、NULL許可、ユニーク制約無しというカラムと対応させたいならば
/** ほげぴよプロパティ */ @Column(length = 100, nullable = true, unique = false) public String hogePiyo;
となる。
明示的にカラム名を指定したいのならば
@Column(name="fugafuga", length = 100, nullable = true, unique = false) public String hogePiyo;
ようにnameで指定すればよい。
@Id
アノテーションで指定のプロパティが主キーとしてテーブルと対応することを示す
/** idプロパティ */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(precision = 10, nullable = false, unique = true) public Integer id;
対象がMySQLならば
@GeneratedValue(strategy = GenerationType.IDENTITY)
と指定しておけばauto_incriment
指定のカラムとなる。
複合キーを作りたいならば@Id
アノテーションを複数のメンバにつければよい
日時を扱うには
日付 | java.sql.Date |
時間 | java.sql.Time |
時刻 | java.sql.Timestamp |
をメンバの型に指定すればよい
MySQLのTimestamp型は若干変な挙動を持っている(MySQL / Field / Type / Timestamp型)ので時刻の管理はDatetime型で指定したい場合がある。
しかしJava側の型をjava.sql.Timestamp
にしてしまうと自動的にMySQLのTimestamp型になってしまう。
ここでエンティティのプロパティを
@Column(nullable = true, unique = false, columnDefinition="datetime") public Timestamp updatedAt;
このようにするとジェネレート時にDatetime型で作ることができる。
@Column(precision = 10, scale = 3, nullable = true) public BigDecimal hoge;
厳密な数値の保持が必要な場合 Java側では BigDecimal 型を使う。この BigDecimal に対応する MySQL の型は decimal 型である。
↑のように指定すると、decimal(10, 3)
、つまり全体10桁、小数部3桁の型を作ることになる。
エンティティでエンティティ間の関係を定義しておくとS2JDBCでjoin指定した時に結果を関係先のエンティティに格納してくれる
3つある
関係 | memo |
---|---|
1:1 | ユーザー情報とユーザー情報詳細のようなもともとテーブル1個で済むところを2個に分割したようなタイプの関係 |
1:n | 国(1)と県(n)みたいな片方が片方を所有しているような関係 |
n:1 | 1:nの逆パターン。県から見た国 |
リレーションの基本はn:1の接続になる。1:1の実装も1:nの実装も、相手側にn:1を実装する必要がある。
リレーションを実装するにはまずエンティティに相手エンティティを格納するメンバを作りどのような関係かアノテーションで示す。
name に自分のカラム、referencedColumnNameに接続対象のカラムを指定する。対象のテーブルは相手エンティティの型から導出される。
@ManyToOne @JoinColumn(name = "CREATED_BY", referencedColumnName = "ID") public Hoge hoge;
この例ならば自エンティティ由来のテーブルのCREATED_BYカラムとHOGEテーブルのIDカラムを結合してもってくることになる。 その結果のHOGEテーブル由来の部分がhogeメンバに格納される。
1:n ならば関係先のデータを複数所有することになるので相手エンティティのListを作る。
ここにアノテーションで相手がManyToOne指定しているメンバを指定する
@OneToMany(mappedBy = "piyo") public List<Hoge> hogeList;
1:1は1:nの特殊版でエンティティ1個だけ格納するように書けばよい
@OneToOne(mappedBy = "piyo") public Hoge hoge;
この状態で
select().leftOuterJoin(piyo().hoge())...
な感じで結合したいメンバを指定する(s2jdbc-genでpiyo().hoge()
が生成済とする)とメンバにも結合条件で引っ張ってきた値が自動的に格納される。
1:nならば複数個の関係先エンティティがマッピングされて突っ込まれる。
@MappedSuperclass public abstract class Base{ @Column(nullable = true, unique = false) public Date d; @Column(nullable = true, unique = false) public Time t; @Column(nullable = true, unique = false) public Timestamp ts; }
このように@MappedSuperclass
アノテーションをつけて共通化したいカラムに対応するメンバを作り、
各エンティティクラスで継承することで共通カラムを一気に実装できる。
このスーパークラスは多段で継承してもちゃんと動作する。
2012-08-11