2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MyBatisGeneratorのMapper自動生成機能をカスタマイズして見た

Last updated at Posted at 2022-01-17

MyBatisでSpringプロジェクトの環境構築をして、MyBatisGeneratorのDto,Dao,Mapperの自動生成機能を使って見たが、いくつ改善したいところがあります。
・Springのアノテーションを自動追加したい
・Lombokを対応したい
・DtoとDaoのファイル名を馴染みなXXXDto.javaとXXXDao.javaに改修したい
以上の課題を解決するため、MyBatisGeneratorのPluginAdapterによって自動生成機能をカスタマイズして見ました。

##環境構成
・eclipse
・Java
・MyBatis-Spring
・MyBatisGenerator
・Spring-boot
・Lombok
・Maven

##依頼注入一覧

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>springBatchTest</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springBatchTest</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.4.0</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

#PluginAdapterのサブクラスを作成する
ここでアノテーションを追加する。

MyBatisPlugin.java
package com.example.demo.conf;

import java.util.List;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

public class MyBatisPlugin extends PluginAdapter {

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

	/*
	 * Daoクラスの自動生成をコントロールするメソッド
	 */
	@Override
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		
		// Lombok機能をimportする
		topLevelClass.addImportedType("lombok.Data");
		// アノテーション追加
		topLevelClass.addAnnotation("@Data");

		return true;
	}

	/*
	 * Dtoクラスの自動生成をコントロールするメソッド
	 */
	@Override
	public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {

		// Spring機能をimportする
		interfaze.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
		interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
		// アノテーション追加
		interfaze.addAnnotation("@Mapper");
		interfaze.addAnnotation("@Repository");

		return true;
	}

	/*
	 * DtoクラスのSetterメソッドをコントロールするメソッド
	 */
	@Override
	public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass,
			IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		
		// DtoクラスのSetterメソッドを自動生成しないようにする
		return false;
	}

	/*
	 * DtoクラスのGetterメソッドをコントロールするメソッド
	 */
	@Override
	public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass,
			IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		
		// DtoクラスのGetterメソッドを自動生成しないようにする
		return false;
	}

}

##IntrospectedTableMyBatis3Implのサブクラスを作成する
ここでファイル名を改修する、やり方はシンプルで、IntrospectedTableにあるDto、Daoのファイル名編集に関するメソッドをそのままコピーして、改修したい部分だけ改修して、オーバーライドすればOKです。

MyBatis3Ex.java

package com.example.demo.conf;

import static org.mybatis.generator.internal.util.StringUtility.*;

import org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl;

public class MyBatis3Ex extends IntrospectedTableMyBatis3Impl{

	/*
	 * IntrospectedTableのcalculateJavaClientAttributesメソッドの丸コピー
	 */
	@Override
    protected void calculateJavaClientAttributes() {
        if (context.getJavaClientGeneratorConfiguration() == null) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        sb.append(calculateJavaClientInterfacePackage());
        sb.append('.');
        if (stringHasValue(tableConfiguration.getMapperName())) {
            sb.append(tableConfiguration.getMapperName());
        } else {
            if (stringHasValue(fullyQualifiedTable.getDomainObjectSubPackage())) {
                sb.append(fullyQualifiedTable.getDomainObjectSubPackage());
                sb.append('.');
            }
            sb.append(fullyQualifiedTable.getDomainObjectName());
            // ↓↓ 元は"Mapper"と書いてる、"Dao"に改修します。
            sb.append("Dao"); //$NON-NLS-1$
        }
        setMyBatis3JavaMapperType(sb.toString());

        sb.setLength(0);
        sb.append(calculateJavaClientInterfacePackage());
        sb.append('.');
        if (stringHasValue(tableConfiguration.getSqlProviderName())) {
            sb.append(tableConfiguration.getSqlProviderName());
        } else {
            if (stringHasValue(fullyQualifiedTable.getDomainObjectSubPackage())) {
                sb.append(fullyQualifiedTable.getDomainObjectSubPackage());
                sb.append('.');
            }
            sb.append(fullyQualifiedTable.getDomainObjectName());
            sb.append("SqlProvider"); //$NON-NLS-1$
        }
        setMyBatis3SqlProviderType(sb.toString());
        
        sb.setLength(0);
        sb.append(calculateJavaClientInterfacePackage());
        sb.append('.');
        sb.append(fullyQualifiedTable.getDomainObjectName());
        sb.append("DynamicSqlSupport"); //$NON-NLS-1$
        setMyBatisDynamicSqlSupportType(sb.toString());
    }
	
	/*
	 * IntrospectedTableのcalculateModelAttributesメソッドの丸コピー
	 */
	@Override
    protected void calculateModelAttributes() {
        String pakkage = calculateJavaModelPackage();

        StringBuilder sb = new StringBuilder();
        sb.append(pakkage);
        sb.append('.');
        sb.append(fullyQualifiedTable.getDomainObjectName());
        sb.append("Key"); //$NON-NLS-1$
        setPrimaryKeyType(sb.toString());

        sb.setLength(0);
        sb.append(pakkage);
        sb.append('.');
		sb.append(fullyQualifiedTable.getDomainObjectName());
		// ↓↓ "Dto"を追加する
        sb.append("Dto");
        setBaseRecordType(sb.toString());

        sb.setLength(0);
        sb.append(pakkage);
        sb.append('.');
        sb.append(fullyQualifiedTable.getDomainObjectName());
        sb.append("Record"); //$NON-NLS-1$
        setKotlinRecordType(sb.toString());

        sb.setLength(0);
        sb.append(pakkage);
        sb.append('.');
        sb.append(fullyQualifiedTable.getDomainObjectName());
        sb.append("WithBLOBs"); //$NON-NLS-1$
        setRecordWithBLOBsType(sb.toString());

        String exampleTargetPackage = calculateJavaModelExamplePackage();
        sb.setLength(0);
        sb.append(exampleTargetPackage);
        sb.append('.');
        sb.append(fullyQualifiedTable.getDomainObjectName());
        sb.append("Example"); //$NON-NLS-1$
        setExampleType(sb.toString());
    }
}

##generatorConfigの設定

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>
  <!-- targetRuntimeを上記のMyBatis3Exに設定する -->
  <context id="context1"  targetRuntime="com.example.demo.conf.MyBatis3Ex">
  
    <!-- pluginを追加する -->
	<plugin type="com.example.demo.conf.MyBatisPlugin" >
     <property name="custom" value="true"/>
    </plugin>
    
    <jdbcConnection connectionURL="jdbc:mysql://localhost/mysql" driverClass="com.mysql.jdbc.Driver" password="root" userId="root" />
    
    <javaModelGenerator targetPackage="com.example.demo.dto" targetProject="SpringBatchDemo/src/main/java" >
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    
    <sqlMapGenerator targetPackage="com.example.demo.mapper" targetProject="SpringBatchDemo/src/main/resources" >
     <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    
    <javaClientGenerator targetPackage="com.example.demo.dao"  targetProject="SpringBatchDemo/src/main/java" type="XMLMAPPER">
   	 <property name="enableSubPackages" value="true" />
    </javaClientGenerator>
    
    <table schema="mysql" tableName="main" />
    
  </context>
</generatorConfiguration>

#実行結果

MainDao.java
package com.example.demo.dao;

import com.example.demo.dto.MainDto;
import com.example.demo.dto.MainExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface MainDao {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    long countByExample(MainExample example);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int deleteByExample(MainExample example);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int deleteByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int insert(MainDto record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int insertSelective(MainDto record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    List<MainDto> selectByExample(MainExample example);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    MainDto selectByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int updateByExampleSelective(@Param("record") MainDto record, @Param("example") MainExample example);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int updateByExample(@Param("record") MainDto record, @Param("example") MainExample example);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int updateByPrimaryKeySelective(MainDto record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table main
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    int updateByPrimaryKey(MainDto record);
}
MainDto.java
package com.example.demo.dto;

import lombok.Data;

@Data
public class MainDto {
    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column main.id
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    private Integer id;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column main.name
     *
     * @mbg.generated Mon Jan 17 23:38:28 JST 2022
     */
    private String name;
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?