MyBatis Generatorとは?開発効率を3倍にする自動生成ツール
MyBatis Generatorは、MyBatisフレームワークにおけるボイラープレートコードを自動生成する強力なツールです。データベーステーブルの定義から、Javaのエンティティクラス、SQLマッパーインターフェース、XMLマッピングファイルを自動生成することで、開発効率を大幅に向上させます。
従来の実装方法と比較した際のメリット
以下の表で、従来の手動実装とMyBatis Generatorを使用した場合を比較します:
| 評価項目 | 従来の実装方法 | MyBatis Generator使用時 | 改善効果 |
|---|---|---|---|
| 実装時間 | 1テーブルあたり2-3時間 | 1テーブルあたり5-10分 | 約80%削減 |
| バグ発生率 | 100行あたり1.2件 | 100行あたり0.3件 | 約75%削減 |
| コード一貫性 | 開発者依存 | 完全な一貫性を確保 | 100%向上 |
| メンテナンスコスト | 高い | 低い | 約60%削減 |
実際の導入効果として、以下のような具体的な数値が報告されています:
- 開発速度の向上
- DAOレイヤーの実装時間: 約70%削減
- スキーマ変更への対応時間: 約80%削減
- テストコード作成時間: 約50%削減
- 品質の改善
- コードレビュー時間: 約40%削減
- バグ修正回数: 約60%削減
- ドキュメント作成時間: 約50%削減
- 運用効率の向上
- 新規開発者の立ち上げ時間: 約50%短縮
- コード保守の工数: 約40%削減
- CI/CDパイプラインの構築時間: 約30%削減
以下は、MyBatis Generatorを使用した場合の基本的なワークフローの例です:
<!-- generatorConfig.xml の基本構成例 -->
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- データベース接続設定 -->
<context id="MyTables" targetRuntime="MyBatis3">
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mydb"
userId="root"
password="password">
</jdbcConnection>
<!-- 生成されるファイルの設定 -->
<javaModelGenerator
targetPackage="com.example.model"
targetProject="src/main/java">
</javaModelGenerator>
<!-- テーブル設定 -->
<table tableName="users" />
</context>
</generatorConfiguration>
この設定により、以下のようなエンティティクラスが自動生成されます:
// 生成されるエンティティクラスの例
public class User {
private Long id;
private String username;
private String email;
// getter/setterメソッド
// equals/hashCode実装
// toString実装
}
MyBatis Generatorの導入により、開発者はビジネスロジックの実装に注力できるようになり、プロジェクト全体の生産性が大幅に向上します。次のセクションでは、具体的な導入手順について詳しく説明していきます。
MyBatis Generator導入手順:5分で環境構築
MyBatis Generatorを効率的に導入するための手順を、ビルドツール別に詳しく解説します。
Maven/Gradleでの依存関係の追加方法
Mavenの場合
pom.xmlに以下の設定を追加します:
<!-- プラグインの追加 -->
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.2</version>
<dependencies>
<!-- MySQL Connector の追加(MySQLの場合) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<!-- 依存関係の追加 -->
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.2</version>
</dependency>
</dependencies>
Gradleの場合
build.gradleに以下の設定を追加します:
plugins {
id 'org.mybatis.generator' version '1.4.2'
}
dependencies {
implementation 'org.mybatis:mybatis:3.5.13'
implementation 'org.mybatis.generator:mybatis-generator-core:1.4.2'
implementation 'mysql:mysql-connector-java:8.0.33' // MySQLの場合
}
mybatisGenerator {
verbose = true
configFile = 'src/main/resources/generatorConfig.xml'
}
設定ファイルの基本構成と解説
src/main/resources/generatorConfig.xmlに以下の設定を作成します:
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- コンテキスト設定 -->
<context id="MySQLTables" targetRuntime="MyBatis3">
<!-- コメント生成の抑制(任意) -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- データベース接続設定 -->
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mydb"
userId="root"
password="password">
<!-- SSL警告の抑制(必要な場合) -->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- Javaモデル生成設定 -->
<javaModelGenerator
targetPackage="com.example.model"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- SQLマッパーXML生成設定 -->
<sqlMapGenerator
targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- Mapperインターフェース生成設定 -->
<javaClientGenerator
type="XMLMAPPER"
targetPackage="com.example.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- テーブル設定 -->
<table tableName="users" domainObjectName="User">
<!-- 主キー設定 -->
<generatedKey column="id" sqlStatement="MYSQL" identity="true"/>
</table>
</context>
</generatorConfiguration>
データベース接続設定のポイント
データベース接続設定で注意すべき重要なポイントを表にまとめました:
一般的なデータベース製品別の設定例:
<!-- PostgreSQL -->
<jdbcConnection
driverClass="org.postgresql.Driver"
connectionURL="jdbc:postgresql://localhost:5432/mydb"
userId="postgres"
password="password">
</jdbcConnection>
<!-- Oracle -->
<jdbcConnection
driverClass="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@localhost:1521:XE"
userId="system"
password="password">
</jdbcConnection>
<!-- SQL Server -->
<jdbcConnection
driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"
connectionURL="jdbc:sqlserver://localhost:1433;databaseName=mydb"
userId="sa"
password="password">
</jdbcConnection>
実行方法:
- Maven の場合:
mvn mybatis-generator:generate
- Gradle の場合:
./gradlew mbGenerator
導入時のトラブルシューティング:
- 文字化けが発生する場合:
<jdbcConnection ...>
<property name="characterEncoding" value="utf8"/>
<property name="useUnicode" value="true"/>
</jdbcConnection>
- SSL警告が表示される場合:
<jdbcConnection ...>
<property name="useSSL" value="false"/>
</jdbcConnection>
- タイムゾーンエラーが発生する場合:
<jdbcConnection ...>
<property name="serverTimezone" value="UTC"/>
</jdbcConnection>
これらの設定を完了することで、MyBatis Generatorの基本的な環境構築は完了です。次のセクションでは、より実践的なコード生成の設定方法について解説していきます。
実践的なコード生成:5つの重要設定
実務で使えるコードを生成するための重要な設定とカスタマイズ方法を解説します。
エンティティクラスのカスタマイズ方法
1. モデルクラスの基本設定
<javaModelGenerator
targetPackage="com.example.model"
targetProject="src/main/java">
<!-- トリム設定 -->
<property name="trimStrings" value="true"/>
<!-- シリアライズ設定 -->
<property name="serializable" value="true"/>
<!-- イミュータブル設定 -->
<property name="immutable" value="true"/>
<!-- コンストラクタ設定 -->
<property name="constructorBased" value="true"/>
</javaModelGenerator>
2. カスタムプラグインの追加
// カスタムプラグインの実装例
public class LombokPlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
// Lombokアノテーションの追加
topLevelClass.addImportedType("lombok.Data");
topLevelClass.addImportedType("lombok.Builder");
topLevelClass.addAnnotation("@Data");
topLevelClass.addAnnotation("@Builder");
return true;
}
}
設定ファイルへの登録:
<context id="MySQLTables" targetRuntime="MyBatis3">
<plugin type="com.example.plugins.LombokPlugin" />
</context>
マッパーインターフェースの設定ポイント
1. 基本的なCRUD操作の生成設定
<table tableName="users" domainObjectName="User">
<!-- メソッド名のカスタマイズ -->
<property name="selectByExampleStatementId" value="findByCondition"/>
<property name="selectByPrimaryKeyStatementId" value="findById"/>
<property name="insertStatementId" value="create"/>
<property name="updateByPrimaryKeyStatementId" value="modify"/>
<property name="deleteByPrimaryKeyStatementId" value="remove"/>
<!-- 生成するメソッドの選択 -->
<property name="enableCountByExample" value="true"/>
<property name="enableUpdateByExample" value="true"/>
<property name="enableDeleteByExample" value="true"/>
<property name="enableSelectByExample" value="true"/>
<property name="selectByExampleQueryId" value="true"/>
</table>
2. カスタムメソッドの追加
// カスタムメソッドを含むマッパーインターフェース
public interface UserMapper {
// 自動生成されるメソッド
User findById(Long id);
List<User> findByCondition(UserExample example);
// カスタムメソッドの追加
@Select("SELECT * FROM users WHERE status = #{status}")
List<User> findByStatus(String status);
@Update("UPDATE users SET last_login = #{lastLogin} WHERE id = #{id}")
int updateLastLogin(@Param("id") Long id, @Param("lastLogin") Date lastLogin);
}
XMLマッピングファイルの生成オプション
1. 基本設定
<sqlMapGenerator
targetPackage="mapper"
targetProject="src/main/resources">
<!-- サブパッケージの生成 -->
<property name="enableSubPackages" value="true"/>
<!-- マージ可能なXMLの生成 -->
<property name="isMergeable" value="true"/>
</sqlMapGenerator>
2. カスタムSQLの追加
<!-- 自動生成されたXMLに追加するカスタムSQL -->
<select id="findActiveUsers" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM users
WHERE status = 'ACTIVE'
AND last_login > #{lastLoginDate}
</select>
<update id="batchUpdateStatus">
UPDATE users
SET status = #{newStatus}
WHERE id IN
<foreach collection="userIds" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</update>
日本語カラム名の適切な処理方法
1. コメント生成の設定
<commentGenerator>
<!-- 日本語コメントの有効化 -->
<property name="suppressAllComments" value="false"/>
<property name="addRemarkComments" value="true"/>
<!-- 日付情報の抑制 -->
<property name="suppressDate" value="true"/>
</commentGenerator>
2. 文字コード設定
<jdbcConnection ...>
<!-- 文字コード設定 -->
<property name="characterEncoding" value="utf8"/>
<property name="useUnicode" value="true"/>
<!-- メタデータの文字コード設定 -->
<property name="remarks" value="true"/>
<property name="useInformationSchema" value="true"/>
</jdbcConnection>
型変換の細かな制御方法
1. JavaTypeResolverの設定
<javaTypeResolver>
<!-- BigDecimal型の使用 -->
<property name="forceBigDecimals" value="false"/>
<!-- java.time APIの使用 -->
<property name="useJSR310Types" value="true"/>
</javaTypeResolver>
2. カスタム型変換の実装
// カスタム型変換クラス
public class CustomTypeResolver extends JavaTypeResolverDefaultImpl {
@Override
protected JavaType calculateJavaType(IntrospectedColumn introspectedColumn) {
if (introspectedColumn.getJdbcType() == Types.VARCHAR
&& introspectedColumn.getLength() > 1000) {
return new FullyQualifiedJavaType(String.class.getName());
}
return super.calculateJavaType(introspectedColumn);
}
}
設定への適用:
<javaTypeResolver type="com.example.resolver.CustomTypeResolver">
<property name="useJSR310Types" value="true"/>
</javaTypeResolver>
| データベース型 | Java型 | 設定オプション |
|---|---|---|
| TIMESTAMP | LocalDateTime | useJSR310Types=true |
| DATE | LocalDate | useJSR310Types=true |
| TIME | LocalTime | useJSR310Types=true |
| DECIMAL | BigDecimal | forceBigDecimals=true |
| NUMERIC | BigDecimal | forceBigDecimals=true |
| VARCHAR | String | デフォルト |
| BLOB | byte[] | デフォルト |
これらの設定を組み合わせることで、実務で必要となる高品質なコードを生成することができます。次のセクションでは、生成されたコードの保守性を高めるための実装テクニックについて解説していきます。
保守性を高める実装テクニック集
自動生成コードの保守性を高め、長期的な開発効率を向上させるための実践的なテクニックを解説します。
生成コードのバージョン管理戦略
1. 生成コードの管理方針
| 管理対象 | 推奨方針 | 理由 |
|---|---|---|
| 生成コード | Gitで管理 | レビュー・差分確認が可能 |
| 設定ファイル | Gitで管理 | チーム内での共有・変更管理が容易 |
| 一時ファイル | .gitignoreに追加 | 不要なファイルの混入を防止 |
2. .gitignore の設定例
# 生成された一時ファイル *.class *.jar *.war # MyBatisGenerator設定ファイルのバックアップ generatorConfig.xml.bak # ビルドディレクトリ target/ build/ # IDE固有のファイル .idea/ *.iml .vscode/
3. 生成コードの差分管理スクリプト
#!/bin/bash
# 生成前のコードをバックアップ
cp -r src/main/java/com/example/model model_backup
# コード生成実行
mvn mybatis-generator:generate
# 差分を確認
diff -r src/main/java/com/example/model model_backup > code_diff.txt
# 差分があれば通知
if [ -s code_diff.txt ]; then
echo "コードに変更があります。確認してください。"
cat code_diff.txt
fi
カスタムプラグインの活用方法
1. コード品質チェックプラグイン
public class CodeQualityPlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public boolean modelBaseRecordClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
// Javadocの追加
topLevelClass.addJavaDocLine("/**");
topLevelClass.addJavaDocLine(" * " + introspectedTable.getRemarks());
topLevelClass.addJavaDocLine(" * @author MyBatis Generator");
topLevelClass.addJavaDocLine(" */");
// コード品質チェック用アノテーション
topLevelClass.addImportedType("javax.validation.constraints.NotNull");
return true;
}
}
2. カスタムメソッド追加プラグイン
public class CustomMethodPlugin extends PluginAdapter {
@Override
public boolean clientGenerated(Interface interfaze,
IntrospectedTable introspectedTable) {
// バッチ処理用メソッドの追加
addBatchInsertMethod(interfaze, introspectedTable);
addBatchUpdateMethod(interfaze, introspectedTable);
return true;
}
private void addBatchInsertMethod(Interface interfaze,
IntrospectedTable introspectedTable) {
Method method = new Method("batchInsert");
method.setReturnType(new FullyQualifiedJavaType("int"));
method.addParameter(new Parameter(
new FullyQualifiedJavaType("List<" +
introspectedTable.getBaseRecordType() + ">"),
"records"));
interfaze.addMethod(method);
}
}
テストコードの自動生成と活用
1. テストケース生成プラグイン
public class TestGeneratorPlugin extends PluginAdapter {
@Override
public boolean modelBaseRecordClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
// テストクラスの生成
generateTestClass(topLevelClass, introspectedTable);
return true;
}
private void generateTestClass(TopLevelClass modelClass,
IntrospectedTable table) {
String testClassName = modelClass.getType().getShortName() + "Test";
TopLevelClass testClass = new TopLevelClass(
modelClass.getType().getPackageName() + ".test." + testClassName);
// JUnit5のアノテーション追加
testClass.addImportedType("org.junit.jupiter.api.Test");
testClass.addImportedType("org.junit.jupiter.api.DisplayName");
// テストメソッドの生成
for (Method method : modelClass.getMethods()) {
generateTestMethod(testClass, method);
}
}
}
2. テストコードの例
@DisplayName("User エンティティのテスト")
class UserTest {
private UserMapper userMapper;
@BeforeEach
void setUp() {
// テスト用のMyBatis設定
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(getClass().getResourceAsStream("/mybatis-config-test.xml"));
userMapper = sqlSessionFactory.openSession().getMapper(UserMapper.class);
}
@Test
@DisplayName("ユーザー作成のテスト")
void testCreateUser() {
// テストデータ作成
User user = User.builder()
.username("testUser")
.email("test@example.com")
.build();
// テスト実行
int result = userMapper.insert(user);
// 検証
assertThat(result).isEqualTo(1);
assertThat(user.getId()).isNotNull();
}
@Test
@DisplayName("バッチ更新のテスト")
void testBatchUpdate() {
// テストデータ準備
List<User> users = Arrays.asList(
createTestUser("user1"),
createTestUser("user2")
);
// テスト実行
int result = userMapper.batchUpdate(users);
// 検証
assertThat(result).isEqualTo(users.size());
}
}
3. テストデータ生成ユーティリティ
public class TestDataGenerator {
public static class Builder<T> {
private final Class<T> entityClass;
private final Map<String, Object> values = new HashMap<>();
public Builder(Class<T> entityClass) {
this.entityClass = entityClass;
}
public Builder<T> set(String field, Object value) {
values.put(field, value);
return this;
}
public T build() {
try {
T instance = entityClass.getDeclaredConstructor().newInstance();
for (Map.Entry<String, Object> entry : values.entrySet()) {
PropertyUtils.setProperty(instance,
entry.getKey(), entry.getValue());
}
return instance;
} catch (Exception e) {
throw new RuntimeException("テストデータ生成失敗", e);
}
}
}
public static <T> Builder<T> builder(Class<T> entityClass) {
return new Builder<>(entityClass);
}
}
これらのテクニックを組み合わせることで、保守性の高い実装を実現できます。次のセクションでは、実際のプロジェクトでの運用に関するベストプラクティスについて解説していきます。
MyBatis Generator活用のベストプラクティス
実際のプロジェクトでMyBatis Generatorを効果的に活用するためのベストプラクティスを解説します。
大規模プロジェクトでの運用ポイント
1. モジュール分割戦略
大規模プロジェクトでの効果的なモジュール分割例:
project-root/
├── common/
│ ├── entity/ # 共通エンティティ
│ └── generator/ # 生成設定
├── module-a/
│ ├── entity/ # モジュール固有エンティティ
│ ├── mapper/ # SQLマッパー
│ └── generator/ # モジュール用生成設定
└── module-b/
├── entity/
├── mapper/
└── generator/
設定ファイルの分割例:
<!-- common-generator-config.xml -->
<generatorConfiguration>
<context id="commonTables">
<!-- 共通設定 -->
<property name="javaFileEncoding" value="UTF-8"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- プラグイン設定 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<!-- 共通テーブル設定 -->
<table tableName="common_master" />
</context>
</generatorConfiguration>
<!-- module-specific-generator-config.xml -->
<generatorConfiguration>
<context id="moduleTables">
<!-- モジュール固有の設定 -->
<property name="moduleSpecificSetting" value="true"/>
<!-- モジュール固有のテーブル設定 -->
<table tableName="module_specific_table">
<domainObjectRenamingRule
searchString="^Tbl"
replaceString="" />
</table>
</context>
</generatorConfiguration>
2. チーム開発での運用ガイドライン
// 生成コードのカスタマイズポリシー
public interface CustomizationPolicy {
/**
* カスタマイズ可能な箇所
* 1. カスタムメソッドの追加(別ファイルで実装)
* 2. バリデーション制約の追加
* 3. ドキュメントコメントの追加
*/
/**
* カスタマイズ禁止の箇所
* 1. 生成されたメソッドの修正
* 2. エンティティのフィールド定義の変更
* 3. マッパーXMLの直接編集
*/
}
// カスタムメソッド実装例
@Repository
public class CustomUserMapper extends UserMapper {
// 追加メソッドはここに実装
public List<User> findByStatus(String status) {
UserExample example = new UserExample();
example.createCriteria().andStatusEqualTo(status);
return selectByExample(example);
}
}
トラブルシューティングと解決策
1. 一般的な問題と対処法
| 問題 | 原因 | 解決策 |
|---|---|---|
| メモリ不足 | 大量テーブル生成 | バッチサイズの調整 |
| 文字化け | 文字コード設定不足 | UTF-8の明示的指定 |
| 型変換エラー | 型マッピング不適切 | カスタム型リゾルバーの実装 |
2. エラー別の対処方法
// メモリ使用量の最適化
public class MemoryOptimizedGenerator extends MyBatisGenerator {
private static final int BATCH_SIZE = 10;
@Override
public void generate(ProgressCallback callback)
throws SQLException, InterruptedException {
List<String> tableNames = getTableNames();
for (int i = 0; i < tableNames.size(); i += BATCH_SIZE) {
List<String> batch = tableNames.subList(
i,
Math.min(i + BATCH_SIZE, tableNames.size())
);
generateBatch(batch, callback);
System.gc(); // バッチ処理後のメモリ解放
}
}
}
// 型変換エラー対処
public class CustomTypeResolver extends JavaTypeResolverDefaultImpl {
@Override
protected FullyQualifiedJavaType calculateBigDecimalReplacement(
IntrospectedColumn column,
FullyQualifiedJavaType defaultType) {
if (column.getScale() > 0 || column.getLength() > 18) {
return defaultType;
}
return new FullyQualifiedJavaType(Long.class.getName());
}
}
パフォーマンスチューニングの勘所
1. 生成コードの最適化
// バッチ処理の最適化例
public interface OptimizedMapper<T> {
@Options(useGeneratedKeys = true, keyProperty = "id")
int batchInsert(@Param("list") List<T> records);
// バッチ更新用SQLの生成
@UpdateProvider(type = BatchSqlProvider.class, method = "createBatchUpdate")
int batchUpdate(@Param("list") List<T> records);
}
public class BatchSqlProvider {
public String createBatchUpdate(Map<String, Object> params) {
List<?> list = (List<?>) params.get("list");
if (list.isEmpty()) return "";
SQL sql = new SQL();
sql.UPDATE("users");
sql.SET("status = #{item.status}");
sql.SET("updated_at = #{item.updatedAt}");
sql.WHERE("id = #{item.id}");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
if (i > 0) builder.append(" UNION ALL ");
builder.append(String.format("SELECT * FROM (%s) tmp%d",
sql.toString().replace("#{item.",
String.format("#{list[%d].", i)), i));
}
return builder.toString();
}
}
2. インデックス設定の最適化
<!-- generatorConfig.xml -->
<table tableName="large_table">
<!-- インデックス情報の自動生成 -->
<property name="useActualColumnNames" value="true"/>
<property name="addRemarkComments" value="true"/>
<!-- 検索用インデックスの指定 -->
<index>
<index-column name="status" />
<index-column name="created_at" />
</index>
<!-- 複合インデックスの指定 -->
<index type="UNIQUE">
<index-column name="email" />
<index-column name="tenant_id" />
</index>
</table>
3. キャッシュ戦略
<!-- マッパーXMLでのキャッシュ設定 -->
<cache
type="org.mybatis.caches.ehcache.EhcacheCache"
eviction="LRU"
flushInterval="60000"
size="1024"
readOnly="true"/>
<!-- 特定のステートメントでのキャッシュ制御 -->
<select id="selectByExample"
parameterType="com.example.UserExample"
resultMap="BaseResultMap"
useCache="true">
SELECT
<if test="distinct">
DISTINCT
</if>
<include refid="Base_Column_List" />
FROM users
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
これらのベストプラクティスを適切に適用することで、MyBatis Generatorを効果的に活用し、高品質なアプリケーション開発を実現できます。次のセクションでは、さらなる開発効率化に向けた展望について解説していきます。
次のステップ:さらなる開発効率化に向けて
MyBatis Generatorをベースに、より効率的な開発環境を構築するための次のステップを解説します。
関連ツールとの連携でさらなる効率化
1. IDEプラグインとの連携
<!-- IntelliJ IDEA用の設定例 -->
<idea-plugin>
<id>com.example.mybatis.generator.plugin</id>
<name>MyBatis Generator Integration</name>
<vendor>YourCompany</vendor>
<extensions defaultExtensionNs="com.intellij">
<!-- 生成コードのナビゲーション機能 -->
<codeInsight.lineMarkerProvider
language="JAVA"
implementationClass="com.example.plugin.MapperLineMarkerProvider"/>
<!-- SQLインジェクション設定 -->
<sql.dialectProvider
implementation="com.example.plugin.MyBatisSqlDialectProvider"/>
</extensions>
</idea-plugin>
Visual Studio Code用の設定例:
{
"mybatis-generator.config": {
"configFile": "src/main/resources/generatorConfig.xml",
"overwrite": true,
"verbose": true,
"contexts": ["default"]
},
"mybatis-generator.generate": {
"onSave": false,
"autoGenerateFiles": [
"Entity",
"Mapper",
"XML"
]
}
}
2. CI/CDパイプラインとの統合
# GitHub Actions での自動生成設定例
name: MyBatis Generator CI
on:
push:
paths:
- 'src/main/resources/generatorConfig.xml'
- 'database/schema/**'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: '17'
- name: Generate MyBatis files
run: |
mvn mybatis-generator:generate
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
title: 'Update MyBatis generated files'
commit-message: 'chore: update generated files'
branch: 'feature/update-mybatis-generated'
3. データベース管理ツールとの連携
// Liquibase/Flyway連携用カスタムプラグイン
public class DatabaseChangelogPlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public List<GeneratedJavaFile> contextGenerateJavaFiles(
IntrospectedTable introspectedTable) {
// 変更履歴の自動生成
String changeLog = generateChangeLog(introspectedTable);
writeToChangeLogFile(changeLog);
return super.contextGenerateJavaFiles(introspectedTable);
}
private String generateChangeLog(IntrospectedTable table) {
return String.format("""
-- changeset %s:%s
CREATE TABLE %s (
%s
);
""",
getAuthor(),
generateChangesetId(),
table.getFullyQualifiedTable(),
generateColumnDefinitions(table)
);
}
}
最新アップデートと今後の展望
1. 最新バージョンの新機能活用
MyBatis Generator 1.4.x の新機能活用例:
<!-- 新しい型解決機能の活用 -->
<javaTypeResolver>
<!-- Java 17の新しい型への対応 -->
<property name="useJSR310Types" value="true"/>
<!-- レコード型の生成サポート -->
<property name="generateRecordClasses" value="true"/>
</javaTypeResolver>
<!-- 新しいプラグイン機能の活用 -->
<plugin type="org.mybatis.generator.plugins.FluentBuilderMethodsPlugin" />
<plugin type="org.mybatis.generator.plugins.VirtualPrimaryKeyPlugin" />
2. マイクロサービス対応
// マイクロサービス用のカスタム生成設定
public class MicroserviceGenerator extends IntrospectedTableMyBatis3Impl {
@Override
public List<GeneratedJavaFile> getGeneratedJavaFiles() {
List<GeneratedJavaFile> files = super.getGeneratedJavaFiles();
// DTOクラスの生成
files.add(generateDTOClass());
// gRPC用のプロトファイル生成
files.add(generateProtoFile());
// OpenAPI仕様の生成
files.add(generateOpenAPISpec());
return files;
}
private GeneratedJavaFile generateDTOClass() {
TopLevelClass dtoClass = new TopLevelClass(
getBaseRecordType() + "DTO");
// DTO固有の設定
dtoClass.addAnnotation("@JsonInclude(JsonInclude.Include.NON_NULL)");
return new GeneratedJavaFile(dtoClass, ...);
}
}
3. 将来に向けた準備と推奨事項
- モジュール化とスケーラビリティ
// モジュール化対応の基本インターフェース
public interface ModularGenerator {
void generateModule(String moduleName);
void generateSharedComponents();
void generateAPIs();
}
// 実装例
public class ModularMyBatisGenerator implements ModularGenerator {
@Override
public void generateModule(String moduleName) {
// モジュール固有の生成ロジック
Context context = new Context(ModelType.CONDITIONAL);
context.setId(moduleName);
context.setTargetRuntime("MyBatis3");
// モジュール固有の設定
addModuleSpecificConfigurations(context);
// 生成実行
generate(context);
}
private void addModuleSpecificConfigurations(Context context) {
// モジュールごとの設定追加
JavaModelGeneratorConfiguration modelConfig =
new JavaModelGeneratorConfiguration();
modelConfig.setTargetPackage("com.example." +
context.getId() + ".model");
context.setJavaModelGeneratorConfiguration(modelConfig);
}
}
- 開発者向けのベストプラクティス
推奨される開発フロー: 1. スキーマ設計 - データベース設計ツールでの設計 - ERD作成と共有 - レビューと承認 2. 生成設定の準備 - チーム共通の設定テンプレート作成 - カスタマイズポイントの明確化 - 命名規則の統一 3. コード生成と検証 - 自動テストの実行 - コードレビュー - パフォーマンステスト 4. 継続的な改善 - フィードバックの収集 - 設定の最適化 - ドキュメントの更新
- 今後の技術動向への対応
| 技術トレンド | 対応方針 | 準備すべき点 |
|---|---|---|
| Cloud Native | クラウドDBへの対応 | 接続設定の柔軟化 |
| GraphQL | スキーマ自動生成 | 型定義の拡張 |
| Reactive | R2DBC対応 | 非同期処理の実装 |
これらの将来を見据えた準備と適切な実装により、MyBatis Generatorを長期的に活用し、継続的な開発効率の向上を実現できます。
まとめと次のステップ
- 短期的な改善ポイント
- IDE統合の強化
- CI/CD自動化の推進
- テスト自動化の拡充
- 中期的な目標
- マイクロサービス対応の完備
- クラウドネイティブ化への対応
- チーム開発プロセスの最適化
- 長期的な展望
- 新しい技術トレンドへの対応
- スケーラブルな開発基盤の確立
- 継続的な効率化の追求
これらの要素を計画的に実施することで、より効率的で保守性の高い開発環境を実現できます。