MyBatis Generator 標準Pluginについて

2017/01/23 佐藤和彰
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0Share on Tumblr0

mybatis-logo

こんにちは。ユニトラストの佐藤です。
今回はなにかと使う機会の多いMyBatis。そのGeneratorについて、書いてみたいと思います。

MyBatis Generator プラグインとは?

MyBatis Generatorでは、MyBatisで使用するエンティティクラス、データ操作を行うマッパークラス(XMLでSQLを記載する場合、さらにMapper.xml)を自動生成してくれます。
MyBatis Generator プラグインでは、自動生成される各ファイルに対し、equalsメソッドの追加やクラス名の変更といったプロジェクトに合わせた機能の追加を行ってくれます。また、プラグインを独自実装することで、自動生成されるクラスに基底クラスを追加したりと、様々な機能を追加することが可能となります。
今回は、MyBatis Generatorで標準搭載されているプラグインはどのようなものがあるのか調べてみました。
よく使われそうな標準搭載プラグインをここで紹介したいと思います。
今回調査したMyBatis Generatorのバージョンは以下の通りです。
・mybatis-generator-core-1.3.2.jar

検証対象としたテーブル定義は以下の通りです。
USERSテーブル
USERSテーブル

プラグインなしで自動生成されるソースファイルは以下の通りです。
・Users.java(抜粋)

package sample.entity.base.normal;

public class Users {
    private String id;
    private String companyId;
    private String userId;

	~中略~

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

・UsersExample.java(抜粋)

package sample.entity.base.normal;

import java.util.ArrayList;
import java.util.List;

public class UsersExample {
    protected String orderByClause;
    protected boolean distinct;
    protected List<Criteria> oredCriteria;

    public UsersExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

	~中略~
}

・UsersMapper.java

package sample.entity.base.normal;

import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface UsersMapper {
    int countByExample(UsersExample example);
    int deleteByExample(UsersExample example);
    int deleteByPrimaryKey(String id);
    int insert(Users record);
    int insertSelective(Users record);
    List<Users> selectByExample(UsersExample example);
    Users selectByPrimaryKey(String id);
    int updateByExampleSelective(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByExample(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByPrimaryKeySelective(Users record);
    int updateByPrimaryKey(Users record);
}

 

■SerializablePlugin

Serializableプラグインは、モデルクラスにSerializableインターフェースを追加します。
generatorConfig.xmlにpluginタグを追加し、type属性にSerializablePluginクラスを完全修飾名で記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />

  ~以下省略~

・Users.java(抜粋)

package sample.entity.base.serializable;

import java.io.Serializable;

public class Users implements Serializable {
    private String id;
    private String companyId;
    private String userId;

・UsersExample.java(変更なし)
・UsersMapper.java(変更なし)

■RenameExampleClassPlugin

RenameExampleClassプラグインは、Exampleクラス名のsearchStringプロパティで指定した文字列と一致する部分を、replaceStringプロパティで指定した文字列に置き換えます。
以下の例では、xxxExample.javaをxxxCriteria.javaに置き換えます。
generatorConfig.xmlにpluginタグを追加し、type属性にRenameExampleClassPluginクラスを完全修飾名で記述します。
そして、pluginタグ内にproperyタグを追加し、
変換元として、name属性にsearchString、value属性に変換前文字列
変換後として、name属性にreplaceString、value属性に変換後文字列
を、それぞれ記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">
    <property name="searchString" value="Example"/>
    <property name="replaceString" value="Criteria"/>
  </plugin>

  ~以下省略~

・Users.java(変更なし)
・UsersCriteria.java(抜粋)

package sample.entity.base.rename;

import java.util.ArrayList;
import java.util.List;

public class UsersCriteria {
    protected String orderByClause;
    protected boolean distinct;
    protected List<Criteria> oredCriteria;

    public UsersCriteria() {
        oredCriteria = new ArrayList<Criteria>();
    }

・UsersMapper.java

package sample.entity.base.rename;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import sample.entity.base.Users;
import sample.entity.base.UsersCriteria;

public interface UsersMapper {
    int countByExample(UsersCriteria example);
    int deleteByExample(UsersCriteria example);
    int deleteByPrimaryKey(String id);
    int insert(Users record);
    int insertSelective(Users record);
    List<Users> selectByExample(UsersCriteria example);
    Users selectByPrimaryKey(String id);
    int updateByExampleSelective(@Param("record") Users record, @Param("example") UsersCriteria example);
    int updateByExample(@Param("record") Users record, @Param("example") UsersCriteria example);
    int updateByPrimaryKeySelective(Users record);
    int updateByPrimaryKey(Users record);
}

 

■RowBoundsPlugin

RowBoundsプラグインは、org.apache.ibatis.session.RowBoundsクラスにlimit、offsetを指定することで、検索結果のうち、特定の範囲を取り出すことができます。
generatorConfig.xmlにpluginタグを追加し、type属性にRowBoundsPluginクラスを完全修飾名で記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />

  ~以下省略~

・Users.java(変更なし)
・UsersExample.java(変更なし)
・UsersMapper.java(抜粋)

package sample.entity.base.rowbounds;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.RowBounds;

public interface UsersMapper {
    int countByExample(UsersExample example);
    int deleteByExample(UsersExample example);
    int deleteByPrimaryKey(String id);
    int insert(Users record);
    int insertSelective(Users record);
    List<Users> selectByExampleWithRowbounds(UsersExample example, RowBounds rowBounds);
    List<Users> selectByExample(UsersExample example);
    Users selectByPrimaryKey(String id);
    int updateByExampleSelective(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByExample(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByPrimaryKeySelective(Users record);
    int updateByPrimaryKey(Users record);
}

 

■ToStringPlugin

ToStringプラグインは、モデルクラスにtoStringメソッドを追加します。
generatorConfig.xmlにpluginタグを追加し、type属性にToStringPluginクラスを完全修飾名で記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />

  ~以下省略~

・Users.java(抜粋)

package sample.entity.base.tostring;

public class Users {
    private String id;
    private String companyId;
    private String userId;

    ~中略~

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", companyId=").append(companyId);
        sb.append(", userId=").append(userId);
        sb.append(", firstName=").append(firstName);
        sb.append(", lastName=").append(lastName);
        sb.append(", password=").append(password);
        sb.append("]");
        return sb.toString();
    }
}

・UsersCriteria.java(変更なし)
・UsersMapper.java(変更なし)

■EqualsHashCodePlugin

EqualsHashCodeプラグインは、モデルクラスにequalsメソッドとhashCodeメソッドを追加します。
generatorConfig.xmlにpluginタグを追加し、type属性にEqualsHashCodePluginクラスを完全修飾名で記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin" />

  ~以下省略~

・Users.java(抜粋)

package sample.entity.base.equals;

public class Users {
    private String id;
    private String companyId;
    private String userId;

    ~中略~

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Users other = (Users) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getCompanyId() == null ? other.getCompanyId() == null : this.getCompanyId().equals(other.getCompanyId()))
            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
            && (this.getFirstName() == null ? other.getFirstName() == null : this.getFirstName().equals(other.getFirstName()))
            && (this.getLastName() == null ? other.getLastName() == null : this.getLastName().equals(other.getLastName()))
            && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getCompanyId() == null) ? 0 : getCompanyId().hashCode());
        result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
        result = prime * result + ((getFirstName() == null) ? 0 : getFirstName().hashCode());
        result = prime * result + ((getLastName() == null) ? 0 : getLastName().hashCode());
        result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
        return result;
    }
}

・UsersExample.java(変更なし)
・UsersMapper.java(変更なし)

■VirtualPrimaryKeyPlugin

VirtualPrimaryKeyプラグインは、テーブル定義上主キーでない項目を疑似的に主キーとして扱い、Mapper.classのselectByPrimaryKeyメソッドで検索できるようにします。
以下の例では、USERSテーブルのCOMPANY_ID、USER_IDを疑似的な主キーとして各クラスを自動生成しています。
generatorConfig.xmlにpluginタグを追加し、type属性にVirtualPrimaryKeyPluginクラスを完全修飾名で記述します。
また、tableタグ内にpropertyタグを追加し、name属性にvirtualKeyColumns、value属性に擬似的な主キーとしたいカラム名をカンマ区切りで記述します。

・generatorConfig.xml(抜粋)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
  <classPathEntry location="C:/pleiades/workspace/hard-training-generator/lib/mysql-connector-java-5.1.38.jar"/>
  <context id="context" targetRuntime="MyBatis3">

  <plugin type="org.mybatis.generator.plugins.VirtualPrimaryKeyPlugin" />

  ~中略~

  <table tableName="USERS">
    <property name="virtualKeyColumns" value="COMPANY_ID, USER_ID"/>
  </table>

・Users.java(変更なし)
・UsersExample.java(変更なし)
・UsersMapper.java(抜粋)

package sample.mybatis.mapper.base;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import sample.entity.base.Users;
import sample.entity.base.UsersExample;
import sample.entity.base.UsersKey;

public interface UsersMapper {
    int countByExample(UsersExample example);
    int deleteByExample(UsersExample example);
    int deleteByPrimaryKey(UsersKey key);
    int insert(Users record);
    int insertSelective(Users record);
    List<Users> selectByExample(UsersExample example);
    Users selectByPrimaryKey(UsersKey key);
    int updateByExampleSelective(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByExample(@Param("record") Users record, @Param("example") UsersExample example);
    int updateByPrimaryKeySelective(Users record);
    int updateByPrimaryKey(Users record);
}

・UsersKey.java

package sample.entity.base;

public class UsersKey {
    private String id;
    private String companyId;
    private String userId;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCompanyId() {
        return companyId;
    }

    public void setCompanyId(String companyId) {
        this.companyId = companyId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
}

 

まとめ

MyBatis標準搭載のプラグインを調べてみて、自動生成されたクラスを大幅にカスタマイズするには独自のプラグインを実装する必要がありますが、Serializableインターフェースを実装させたり、equalsメソッドを追加したりといった基本動作は、標準プラグインは用意されていることがわかりました。
なんでも独自実装せず、すでに用意されている部品を使うことで”車輪の再発明”を行わないようにしましょう。

Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0Share on Tumblr0