ラベル MyBatis の投稿を表示しています。 すべての投稿を表示
ラベル MyBatis の投稿を表示しています。 すべての投稿を表示

2012年11月13日火曜日

MyBatis/iBATIS用のコードを自動生成する「MyBatis Generator」を使う

前回は、MyBatisの基本的な使い方を見てきました。今回はそこで手作業にて行ってきた各ファイルの自動生成ツール「MyBatis Generator」の使い方を説明していきたいと思っています。

MyBatis Generator Eclipse pluginのセットアップ
EclipseのメニューからHelp -> New Install Softwareを選択し、以下のURLを入力することでEclipse pluginがセットアップされます。
http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/

インストールできましたら、メニューからFile -> New -> Other...を選択し、MyBatis Generator Configuration Fileを指定して、設定ファイル(デフォルトではgeneratorConfig.xml)を生成し、環境に合わせて編集します。このファイルは、Generateするための設定情報です。


  
    
    
    
    
    

各タグの説明ですが、javaModelGeneratorタグはエンティティクラスファイル、sqlMapGeneratorタグはXMLのMapperファイル、javaClientGeneratorタグはMapperクラスファイルの出力先を指定するためのタグです。tableタグで対象とするテーブル名を記述します。このtableNameにはワイルドカードも指定できるようです。ファイル編集後は、このgeneratorConfig.xmlを選択して、右クリックで「Generate MyBatis/iBATIS Artifacts」を選択しますと、エンティティクラスファイルとMapperファイル、Mapperクラス、Exampleクラスの4つのファイルが生成されます。(ちなみにMyBatis用だけでなく、2.2以上のiBATIS以上のファイルを生成できるようです。)

例えば、blogテーブルの場合は以下の4つのファイルが生成。
  • Blog.java :エンティティクラス。
  • BlogExample.java :Generator独自のクラスっぽい。SQL を呼び出す際、条件を指定するために利用するクラス。
  • BlogMapper.java :クエリを実行するための Java インターフェイス。
  • BlogMapper.xml :Mapper XML ファイルで、ほとんどの SQL はこのファイルに記述。
ちなみに、自動生成された JavaとXML ファイルのコメントには@mbggeneratedというアノテーションがあります。MyBatis Generatorが再度コードを生成するとき、このアノテーションが付加された要素だけを削除してから再度新しい要素を生成されます。そのため、このアノテーションがある場合は、手動で修正すると消えてしまいますのでご注意を。 話はそれましたが、続けますとBlogMapper.xmlを前回のように、mybatis-config.xmlのmapperタグに記述されていればデータベースアクセスできるようになります。例えば以下のようなコードでレコードを登録して、件数をカウントするということが簡単にできます。

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(0);
blog.setContent("Test-Test");
mapper.insert(blog);
int count = mapper.countByExample(new BlogExample());
System.out.println(count);
session.close();

myBatis Generatorをカスタマイズ
このMyBatis GeneratorをPluginを作ることで、カスタマイズできます。具体的にはファイル名やクラス名を変えたり、インターフェースやスーパークラスを追加できたり、メソッド、コンストラクタなどを追加できたりと、結構いろいろ生成するファイルを変更することができます。
まずはここから"Mapping Generator"をダウンロードして、解凍します。そのmybatis-generator-core-x.x.x.jarファイル(私は1.3.2を利用)をEclipseにコピーして、ビルドパスを設定します。
次にorg.mybatis.generator.api.PluginAdapterを継承したクラスを作成します。このクラス内で生成するタイミングに合わせてオーバーライドするメソッドを選択肢、中身を実装します。(例えば、初期化時ならinitializedメソッドをオーバーライド。)以下の例では、エンティティクラスを生成する際に、エンティティクラスにコンストラクタを追加するというサンプルです。

package com.test.generator.plugins;

import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

public class GenPlugin extends PluginAdapter {

 @Override
 public boolean validate(List arg) {
  return true;
 }

 @Override
 public void initialized(IntrospectedTable introspectedTable) {
  super.initialized(introspectedTable);
 }

 @Override
 public boolean modelBaseRecordClassGenerated(
   TopLevelClass topLevelClass,
   IntrospectedTable introspectedTable) {
  Method method = new Method();
  method.setVisibility(JavaVisibility.PUBLIC);
  method.setConstructor(true);
  method.setName(topLevelClass.getType().getShortName());
  method.addBodyLine("System.out.println(\"Called constructor\");");
  topLevelClass.addMethod(method);
  return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
 }
}

この作成したクラスをgeneratorConfig.xmlにcontextタグの中にpluginタグとして、追加します。

  
    
       .....
  

そうすると以下のコンストラクタがBlogクラスに追加されます。

public Blog() {
 System.out.println("Called constructor");
}

このプラグイン機能でいろいろと生成もいじれそうなので、開発の生産性向上に役立ちそうですね。

外部キーなどの対応
ここまで来たら、以下のように参照関係のあるテーブルの場合に自動生成してくれるかを試してみようと思います。

CREATE TABLE blog (
  id INT,
  content VARCHAR(255),
  PRIMARY KEY(id)
);
CREATE TABLE tag (
  id INT,
  blog_id INT,
  name VARCHAR(100),
  PRIMARY KEY(id),
  FOREIGN KEY (blog_id) REFERENCES blog(id)
);

generateConfig.xmlのtableにtagテーブルも追加して、"Generate"!ってやってみたら、Tag関連のファイルは生成されましたらが、参照関係についてのフィールドなどは全然生成されなかったです。本来であれば、Blog.getTags()みたいなメソッドが追加されてList<Blog>を取得できるようなコード生成してくれることを期待したのですが、外部キーの生成は自動的にやってくれないらしいですね。これは手動でやるとMapperなどの修正も必要なので結構めんどくさく、非常に残念。。
こちらのフォーラムにも同様の記事がありました。。。これもまたプラグインを使って作ってみるしかなさそうですね。。

これらMyBatis Generatorの詳細はこちらのチュートリアルを参照ください。

オープンソースORMのMyBatis(旧iBATIS)を使う

オープンソースのORM(Object-Relational Mapping)で、結構日本では利用されているiBATISの後継であるMyBatisについて触ってみました。

MyBatisはiBATISがApacheファンデーションからスピンアウトして新しくフォークされたiBATISの後継フレームワークであり、バージョンで言うとiBATIS3.0という位置づけらしいです。ライセンスはApache Licenseで自由かつ無償にて利用することができます。現在はGoogle Codeでソースコードが管理されているようです。
http://code.google.com/p/mybatis/

MyBatis/iBATISは、JPA(Java Persistence API)ベースのHibernateOracle Toplinkなどと比べ、SQL文を中心に作成していくということもあり、企業システムなどではSpringなどと組み合わせて多用されているようです。(ちなみにSpringは3.0以上をサポートしているらしいです。こちらを参照。Spring2.xであればiBATISを使う必要がありそうですね。)


ちなみに日本では上記のようなトレンドですが、全世界では下図のように圧倒的にHibernateの方が人気があるようです。

では早速試してみたいと思いますが、ここではEclipse4.2とMySQLデータベースをあらかじめインストールされている前提で進めていきたいと思います。ちなみにデータベースとテーブルはシンプルすぎますが、以下のものを利用します。

CREATE DATABASE mydb;

CREATE TABLE blog (
  id INT NOT NULL,
  content VARCHAR(255)
);

MyBatisセットアップ
ここから"Core Framework"をダウンロードして、解凍します。

mybatis-x.x.x.jar(私は3.1.1を利用)とlibフォルダに入っているjarファイルをすべてEclipse上の自分で作成したプロジェクトにコピーしてビルドパスに設定します。さらにMySQLのJDBCドライバーであるConnector/Jをダウンロードして、同様にコピーしてビルドパスに設定します。
次にMyBatis設定ファイルであるmybatis-config.xmlファイルを作成します。このファイルはデータベースの基本的な接続情報と各Mapperファイル(単純に言えばSQL文の書かれているファイル)への外部リンクURLで構成されています。



  
    
      
      
        
        
        
        
      
      
    
  
  
    
  


コーディング
MyBatis設定ファイルで各Mapperファイルはmapperタグに外部ファイルとして指定します。通常は1テーブル(エンティティ)単位で作成することになると思います。そのblogテーブル(エンティティ)用のMapperファイルであるBlogMapper.xmlは以下のようにSQL文を書くことでBlogクラス(エンティティクラス)と紐付けます。


  
  
  
  
      insert into Blog (id, content) values (#{id}, #{content})
  
  
      delete from Blog;
  


このblogテーブル用のBlogクラスは以下のようになります。このクラスは通常のPOJOで書くことができます。
public class Blog {
 private int id;
 private String content;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 
 public Blog(int id, String content) {
  this.id = id;
  this.content = content;
 }
 
 public Blog() {
  super();
 }
}

以下はこれらBlogクラスとMapperファイルを利用してデータベースアクセスするサンプルで、mybatis-config.xmlとBlogMapper.xmlを読み込み、Blogクラス経由でblogテーブルにアクセスするコードです。


String resource ="mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
// delete records
session.delete("deleteAllBlogs");

// insert records
session.insert("insertBlog", new Blog(0, "Test1"));
session.insert("insertBlog", new Blog(1, "Test2"));

// select records
Blog blog = (Blog) session.selectOne("selectBlog", 1); 
System.out.println(blog);  
for (Object v : session.selectList("selectAllBlogs")) {
 System.out.println((Blog) v);
}
session.close();


詳細は、こちらのチュートリアルを参照ください。

次回は、これらのテーブル情報からエンティティクラスやMapperファイル(クラス)を自動的に生成するMyBatis Generatorについて説明したいと思います。