MyBatisの実行フローにおいて、複数のマッピングファイルを管理する場合の設定手順と、namespace 属性の衝突回避機能について解説します。
まず、対象となるデータベースおよびテーブルの定義例を示します。
CREATE DATABASE `project_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `project_db`;
CREATE TABLE `employee` (
`emp_id` INT AUTO_INCREMENT PRIMARY KEY,
`emp_name` VARCHAR(50) NOT NULL,
`join_year` INT NOT NULL,
`salary` DECIMAL(10,2) NOT NULL
) ENGINE=InnoDB;
フレームワークの初期化プロセスを確認します。設定ファイルは Resources.getResourceAsStream("mybatis-config.xml") でストリームとして読み込まれ、SqlSessionFactoryBuilder の build() メソッドに渡されます。この段階で、設定内に定義された全Mapper XMLが解析され、SQLステートメントとパラメータの対応テーブルがメモリ上に構築されます。セッションオープン後、SqlSession インスタンスに対して insert("addRecord", data) のように文字列キーを指定して呼び出すと、MyBatisは登録済みMapper群を走査し、一致する id を持つSQL文を実行します。
各Mapperファイルの記述形式は以下の通りです。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.employee_dao">
<insert id="addRecord" parameterType="model.Employee">
INSERT INTO employee (emp_name, join_year, salary)
VALUES (#{name}, #{joinedAt}, #{baseSalary})
</insert>
</mapper>
Mapperファイルが単一の場合、namespace の値は呼び出し側で使用しないため任意の文字列でも動作しますが、複数ファイルに分割する運用では必須の識別子となります。異なるファイル間で同一の id が存在すると、フレームワークは実行対象を特定できず IllegalArgumentException をスローします。この場合、実行キーに namespace をプレフィックスとして付与することでスコープを限定し、競合を解消します。
複数ファイルを読み込ませるための設定ファイル側記述は以下のようになります。
<configuration>
<environments default="production">
<!-- 接続パラメータ定義 -->
</environments>
<mappers>
<mapper resource="mappings/EmployeeMapper.xml"/>
<mapper resource="mappings/DepartmentMapper.xml"/>
</mappers>
</configuration>
アプリケーションコードからの呼び出しでは、完全修飾名による指定が必要になります。
try (SqlSession session = factory.openSession()) {
Employee record = new Employee();
record.setName("山田次郎");
record.setJoinedAt(2020);
record.setBaseSalary(new BigDecimal("450000.00"));
// namespace と id を結合した形式で指定
session.insert("dao.employee_dao.addRecord", record);
session.commit();
}
IDの一意性が設計段階で担保されている場合は直接 id のみでの実行も可能ですが、モジュール分割やチーム開発を想定した場合、namespace による明示的な名前空間分離が保守性の観点で強く推奨されます。