Top / Hibernate / TIPS集

基本操作

HQLでクエリを発行する

SessionFactory sessionfactory = config.buildSessionFactory();
session = sessionfactory.openSession();
List list = session.find("from UserId as userid where userid.userId like 'Masatomi%'");
↑ 結果(UserIdクラス)の格納されたListが返ってくる

Hibernate3.0から上のfindはdeprecatedになりました。3.0からは

Query query = session.createQuery
   ("from UserId as userid where userid.userId like 'Masatomi%'");
List messages = query.list();

としてください。

HQLの文法などはいろんなサイトで説明されているので割愛。上の意味だけ。

from UserId[1] as userid[2] where userid[2].userId[3] like 'Masatomi%'
↑ 意味は、[1]のクラスを検索します。条件は[3]のフィールドが'Masatomi%'であるようなレコード
↑ [2]はエイリアスなんでなんでもよいでしょう

キー値指定で直接レコードを取得する

SessionFactory sessionfactory = config.buildSessionFactory();
session = sessionfactory.openSession();
UserId aUser=(UserId)session.load(UserId.class,"Masatomi"); <- 第二引数がUniqueKeyの値

レコードのUpdate

SessionFactory sessionfactory = config.buildSessionFactory();
session = sessionfactory.openSession();
UserId aUser=(UserId)session.load(UserId.class,"Masatomi");
userid.setGroupId("GROUP01");
session.flush();
session.connection().commit(); //コレしないと、行ロックしちゃうっぽい

レコードのInsert

SessionFactory sessionfactory = config.buildSessionFactory();
session = sessionfactory.openSession();

UserId userid = new UserId("HOGEHOGE");
userid.setGroupId("1111");
//その他必要なカラムをセット
session.save(userid);
session.flush();
session.connection().commit();

レコードのDelete

SessionFactory sessionfactory = config.buildSessionFactory();
session = sessionfactory.openSession();

UserId userid=(UserId) session.load(UserId.class,"HOGEHOGE");
session.delete(userid);

session.flush();
session.connection().commit();

その他

複数の設定ファイルを使用したい

hibernate.cfg.xmlはどうもひとつのデータベース設定しか書けないみたい(たぶん)。 でも場合によっては一つのデータベースだけではなく、複数のデータベースに接続することがあります。そのときに、複数の設定ファイルを切り替える方法がようやく分かりました。ちなみにTorqueで試行錯誤した経緯はTorque/複数のDBで同時に利用するをご参照。

Configuration config = new Configuration();
//    config = config.configure(); // <-通常の設定の読み込み
config = config.configure(new File(
      getServlet().getServletContext().getRealPath(
        "/WEB-INF/lib/hibernate.cfg.hoge.xml")));

このようにすることで、ランタイムに設定ファイルを指定することが出来るようです。。

結合(関連)を考える

fig1.gif

JavaBeans?(ここではMember)にプロパティを追加してマッピングファイル(Member.hbm.xml)に

<many-to-one name ="workgroup" column="GROUPNO"
 class="nu.mine.kino.binding.ait.hibernate.Workgroup" cascade="all" outer-join="auto"
 update="false" insert="false" />

を追加すればよいようだ。追加しない場合はMember#getWorkgroup()の返り値がnullになるみたい。

Member(N) -> WorkGroup?(1) なので、many-to-oneとなる

JavaBeans?(ここではWorkGroup?)にプロパティを追加してマッピングファイル(WorkGroup?.hbm.xml)に

<set name="memberList" >
 <key ><column name="groupno" /></key>
 <one-to-many class="nu.mine.kino.binding.ait.hibernate.Member" />
</set>

を追加すればよいようだ。追加しない場合はWorkgroup#getMemberList?()の返り値がnullになるみたい。

WorkGroup?(1) -> Member(N) なので、one-to-manyとなる

クラス設計で考えるとWorkGroup? -> Member はあってもその逆はあまりないかなぁ。ようするに

aWorkGroup.getMembers()

はあっても

aMember.getWorkGroup()

はないことが多いように思うけど。。。

http://www.atmarkit.co.jp/fjava/rensai3/ormap05/ormap05_1.html

WEBアプリの時、設定ファイルなどはどこに置くべきか。

hibernate.cfg.xml
classesの直下などに置いて、各リソースの設定ファイルは
<mapping resource="nu/mine/kino/MtAuthor.hbm.xml" />
などと指定する
各オブジェクトの設定ファイル
Javaファイルと同じ場所に置く。

middlegenで作ったhbmファイルについて

たとえば

<id name="id" type="java.lang.Integer" column="id" >
  <meta attribute="field-description">
     @hibernate.id
     generator-class="Increment"
     type="java.lang.Integer"
     column="id"
  </meta>
  <generator class="Increment" />
</id>

  <meta attribute="field-description">
     @hibernate.id
     generator-class="Increment"
     type="java.lang.Integer"
     column="id"
  </meta>

の部分は、コメントに使われるだけ、だと思う。

MySQLのauto_incrementについて

`name_id` int(10) unsigned NOT NULL auto_increment,

と定義されるカラムがあるテーブルについて、middlegenでJavaBeans?とhbm.xmlファイルを作成したら以下のようになりました。

<id
    name="nameId"
    type="java.lang.Object"
    column="name_id"
>
    <meta attribute="field-description">
       @hibernate.id
        generator-class="assigned"
        type="java.lang.Object"
        column="name_id"

    </meta>
    <generator class="assigned" />
</id>

実際はIntegerとマッピングして欲しいのですが、うまくいかないですね。とりあえず自分でjava.lang.Integerに変更しました。あと

<generator class="assigned" />

<generator class="increment" />

に変更しました。もちろんJavaソースも作り直しました。

複合キーを使ったテーブルのマッピング。

主キーが複数、たとえば

create table Customer3 (customer_id varchar(20) not null, 
item_id varchar(20) not null, 
value varchar(255), 
upd_date timestamp,
primary key (customer_id, item_id));

というようにcustomer_id,item_idでユニークになるテーブルのマッピングについてです。

XDocletなどを使ってhbm.xmlを作る場合がほとんどだと思いますので、まずはPOJOから。結論を言うと、上の複合キーを一つのオブジェクトとするために一つPOJOを作ります。

public class Customer3Id implements Serializable {
  private String customerId;
  private String itemId;
  public Customer3Id() {
  }


  /**
   * @hibernate.property column = "customer_id" not-null = "true" length ="20"
   */
  public String getCustomerId() {
    return customerId;
  }

  /**
   * @hibernate.property column = "item_id" not-null = "true" length = "20"
   */
  public String getItemId() {
    return itemId;
  }

  public String toString(){...}
  public boolean equals(Object obj) {...}
  public int hashCode() {...}
}

どうも、

で、実際のレコードの方(?)のPOJOはさっきの複合オブジェクトを保持しておきます。

/**
 * @hibernate.class table = customer3 
 */
public class Customer3 {
  private Customer3Id compositeId;

  ....

  /**
   * @return compositeId を戻します。
   * @hibernate.id generator-class="assigned"
   */
  public Customer3Id getCompositeId() {
    return compositeId;
  }
}

XDocletでhbmを生成したところ、

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
  <class
    name="nu.mine.kino.plugin.hsqldb.hibernate.Customer3" >
    <composite-id  name="compositeId"
      class="nu.mine.kino.plugin.hsqldb.hibernate.Customer3Id">
           <key-property
            name="customerId"
            type="java.lang.String"
            column="customer_id"
            length="20"
        />
           <key-property
            name="itemId"
            type="java.lang.String"
            column="item_id"
            length="20"
        />
    </composite-id>
    <property
      name="value"
    ....................
  </class>
</hibernate-mapping>

なんてのができあがりました。ポイントは複合キーはそのキーのオブジェクトを作る必要がある、ってことですかね。これ、結構めんどくさいね。


この記事は

選択肢 投票
おもしろかった 2  
そうでもない 0  

Top / Hibernate / TIPS集

現在のアクセス:1060


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