S2JDBC/エンティティ

S2JDBC/エンティティ

実際のエンティティの使ったデータの取得は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のDatetime型を指定したい

MySQLのTimestamp型は若干変な挙動を持っている(MySQL / Field / Type / Timestamp型)ので時刻の管理はDatetime型で指定したい場合がある。 しかしJava側の型をjava.sql.Timestampにしてしまうと自動的にMySQLのTimestamp型になってしまう。

ここでエンティティのプロパティを

    @Column(nullable = true, unique = false, columnDefinition="datetime")
    public Timestamp updatedAt;

このようにするとジェネレート時にDatetime型で作ることができる。

BigDecimal型のプロパティ

@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の逆パターン。県から見た国

リレーションの実装のしかた

ManyToOne

リレーションの基本は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メンバに格納される。

OneToMany

1:n ならば関係先のデータを複数所有することになるので相手エンティティのListを作る。

ここにアノテーションで相手がManyToOne指定しているメンバを指定する

@OneToMany(mappedBy = "piyo")
public List<Hoge> hogeList;

OneToOne

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

タグ

s2/s2jdbc/entity.txt · 最終更新: 2020-07-24 12:12 by ore