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
##依頼注入一覧
<?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のサブクラスを作成する
ここでアノテーションを追加する。
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です。
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の設定
<?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>
#実行結果
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);
}
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;
}