Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

IT勉強会での初プレゼンなどお助けします!

勉強会でスピーカーをやりたいけど、プレゼンが初めて、苦手という方に無償でコーチできます。スライドのレビューや録画したリハへのアドバイスなどなど。Twitter@jyukutyoまでメンションでもDMでもお気軽にご連絡ください。

私はIT講師の経験があり、プレゼンはデブサミやJJUG CCCなど200人規模の経験が豊富で最大800人の前でプレゼンしました。海外ではDevoxxUSで。デブサミ2017では公募スピーカー1位、デブサミ関西2012アワードで5位となりました。

MyBatis Generatorで出力するクラスをカスタマイズする

Generator - mybatis - An introduction to the code generation tool for MyBatis - SQL Mapping Framework for Java - Google Project Hosting
http://code.google.com/p/mybatis/wiki/Generator


MyBatis(旧iBatis)には、ジェネレータがあって、DBのスキーマからエンティティとマッパーXMLファイル、Mapperクラスを生成できます。
プラグインクラスを作成すると、その生成をカスタマイズできます。
エンティティのクラス名を変更したい場合や、特定のインタフェースを実装したい場合などに便利です。

エンティティのクラス名を変更する

package plugin;

import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;

/**
 * MyBatis Generatorで生成するクラス名を変更するプラグイン。
 */
public class BeanClassNamePlugin extends PluginAdapter {

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

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

        String name = table.getBaseRecordType();
        table.setBaseRecordType(name + "Dto");
    }
}

エンティティにインタフェースを実装させる

package plugin;

import java.util.List;

import org.mybatis.generator.api.FullyQualifiedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.TopLevelClass;

/**
 * MyBatis Generatorで生成するクラスに、特定のインタフェースを実装させるプラグイン。
 */
public class BeanImplementationPlugin extends PluginAdapter {
    
    private FullyQualifiedJavaType bean;

    public BeanImplementationPlugin() {
        bean = new FullyQualifiedJavaType(
                "net.kronosjp.jyukutyo.MyInterface");
    }
    
    public boolean validate(List<String> warnings) {
        return true;
    }

    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        implementBean(
                topLevelClass,
                introspectedTable.getFullyQualifiedTable());
        return true;
    }

    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        implementBean(
                topLevelClass,
                introspectedTable.getFullyQualifiedTable());
        return true;
    }

    public boolean modelRecordWithBLOBsClassGenerated(
            TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        implementBean(
                topLevelClass,
                introspectedTable.getFullyQualifiedTable());
        return true;
    }

    protected void implementBean(TopLevelClass topLevelClass,
            FullyQualifiedTable table) {
        topLevelClass.addImportedType(bean);
        topLevelClass.addSuperInterface(bean);
    }

    
}

ちなみに、Mapperクラス名はデフォルトで「〜Mapper」になります。

Mapperクラス名を変更する

package plugin;

import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;

/**
 * MyBatis Generatorが生成するマッパークラス名の末尾を、MapperからDaoに変更するプラグイン。
 */
public class MapperClassNamePlugin extends PluginAdapter {

	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}

	@Override
	public void initialized(IntrospectedTable table) {
		super.initialized(table);
		
		String name = table.getMyBatis3JavaMapperType();
		table.setMyBatis3JavaMapperType(name.replaceAll("Mapper$", "Dao"));
	}
}

こんな感じです。
あとは、ジェネレータの設定ファイルに記述します。

<?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:\oralce\ojdbc6.jar" />
	<context id="context1" targetRuntime="MyBatis3">

		<plugin type="plugin.MapperClassNamePlugin" />
		<plugin type="plugin.DtoExtendedPlugin" />

		<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
			connectionURL="jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:DB" userId="user"
			password="password" />
		<javaTypeResolver>
			<property name="forceBigDecimals" value="true" />
		</javaTypeResolver>
		<javaModelGenerator targetPackage="net.kronosjp.jyukutyo.dto"
			targetProject="project\src\main\java" />
		<sqlMapGenerator targetPackage="net.kronosjp.jyukutyo.mapper"
			targetProject="project\src\main\java" />
		<javaClientGenerator targetPackage="net.kronosjp.jyukutyo.mapper"
			targetProject="project\src\main\java" type="XMLMAPPER"
			implementationPackage="net.kronosjp.jyukutyo.mapper">
			<property name="methodNameCalculator" value="default" />
			<property name="rootInterface" value="net.kronosjp.jyukutyo.dao.Dao" />
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		<table schema="" tableName="TABLE_NAME" domainObjectName="TableName"
			enableDeleteByExample="false" enableCountByExample="false"
			enableUpdateByExample="false" selectByExampleQueryId="false"
			enableSelectByExample="false" modelType="flat">
			<columnOverride column="update_date" javaType="java.sql.Timestamp" />
		</table>
	</context>
</generatorConfiguration>

plugin要素で指定すればOKです。例ではOracleに接続してます。

ちなみに、ジェネレータで生成したエンティティのJavadocにある@mbggeneratedが、Javadoc生成のときに警告が出ます。
Mavenで出力するときは、設定しましょう。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-javadoc-plugin</artifactId>
	<version>2.8</version>
	<configuration>
		<author>false</author>
		<source>1.6</source>
		<encoding>UTF-8</encoding>
		<charset>UTF-8</charset>
		<docencoding>UTF-8</docencoding>
		<quiet>true</quiet>
		<tags>
			<tag>
				<name>mbggenerated</name>
				<placement>X</placement>
			</tag>
		</tags>
	</configuration>
</plugin>