1. プロジェクト依存関係の構築
MyBatisを使用する場合、まずビルドツールに対してコアライブラリと対象とするRDBMSのドライバーを登録します。以下はMavenプロジェクトでの標準的な設定例です。
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jp.tech.sample</groupId>
<artifactId>MyBatisXmlDemo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
</project>
2. ドメインモデルとスキーマ準備
オブジェクトとテーブルの対応付けを行うため、単純なPOJOクラスを定義します。プロパティ命名はキャメルケースを基調とし、デフォルトコンストラクタとアクセサを提供します。
package jp.tech.sample.model;
public class Member {
private long memberId;
private String displayName;
private int memberStatus;
public Member() {}
public long getMemberId() { return memberId; }
public void setMemberId(long memberId) { this.memberId = memberId; }
public String getDisplayName() { return displayName; }
public void setDisplayName(String displayName) { this.displayName = displayName; }
public int getMemberStatus() { return memberStatus; }
public void setMemberStatus(int memberStatus) { this.memberStatus = memberStatus; }
@Override
public String toString() {
return String.format("Member{Id=%d, Name='%s', Status=%d}", memberId, displayName, memberStatus);
}
}
対応するデータベース側のDDLは以下の通りです。
CREATE DATABASE IF NOT EXISTS app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE app_db;
CREATE TABLE members (
member_id BIGINT AUTO_INCREMENT PRIMARY KEY,
display_name VARCHAR(100) NOT NULL,
member_status INT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. SQLマッピング定義
SQL文をXMLファイルに分離することで、Javaコードとの結合度を下げます。namespaceにはパッケージ構造を反映させ、各ステートメントに一意の識別子を割り当てます。
<?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="jp.tech.sample.mapping.MemberMapper">
<!-- 特定IDによる単一検索 -->
<select id="findMember" parameterType="long" resultType="jp.tech.sample.model.Member">
SELECT member_id, display_name, member_status FROM members WHERE member_id = #{targetId}
</select>
<!-- 全件取得 -->
<select id="listAll" resultType="jp.tech.sample.model.Member">
SELECT member_id, display_name, member_status FROM members
</select>
<!-- 新規登録(JDBCネイティブの主キー取得を有効化) -->
<insert id="registerMember" parameterType="jp.tech.sample.model.Member" useGeneratedKeys="true" keyProperty="memberId">
INSERT INTO members(display_name, member_status) VALUES(#{displayName}, #{memberStatus})
</insert>
<!-- 状態更新 -->
<update id="changeStatus" parameterType="jp.tech.sample.model.Member">
UPDATE members SET display_name = #{displayName}, member_status = #{memberStatus} WHERE member_id = #{memberId}
</update>
<!-- 指定IDによる削除 -->
<delete id="dropMember" parameterType="long">
DELETE FROM members WHERE member_id = #{targetId}
</delete>
</mapper>
4. フレームワーク初期化設定
データソース、トランザクションポリシー、およびMapperファイルの配置場所を定義する構成ファイルを作成します。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="local-env">
<environment id="local-env">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/app_db?serverTimezone=UTC"/>
<property name="username" value="db_admin"/>
<property name="password" value="secure_pass_123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="jp/tech/sample/mapping/MemberMapper.xml"/>
</mappers>
</configuration>
5. セッション制御とCRUD実行ロジック
`SqlSessionFactory`から`SqlSession`を取得する際、引数に`true`を設定するとトランザクション自動コミットが有効になります。この場合、明示的な`commit()`呼出は不要となり、コードが簡素化されます。ただし、バッチ処理やロールバック要件がある場合は`false`として手動管理を推奨します。
また、レコード登録後の主キー値取得については、上記マッパーのように`useGeneratedKeys="true"`属性をインサートタグに直接付与する方法が、MySQLやPostgreSQLにおいて最も効率的で標準的な実装パターンとなります。
以下は、作成したセッションを使用して登録・検索・更新・削除を一連のフローで実行する統合サンプルです。
package jp.tech.sample;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import jp.tech.sample.model.Member;
public class DataOperationRunner {
public static void main(String[] args) throws IOException {
Reader configStream = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(configStream);
// autoCommit=true を適用し、明示的なコミット省略を実現
try (SqlSession session = factory.openSession(true)) {
String baseNs = "jp.tech.sample.mapping.MemberMapper";
System.out.println(">>> 新規レコード登録");
Member record = new Member();
record.setDisplayName("sample_account_01");
record.setMemberStatus(1);
session.insert(baseNs + ".registerMember", record);
System.out.println("Assigned Primary Key: " + record.getMemberId());
System.out.println(">>> 単一レコード取得");
Member retrieved = session.selectOne(baseNs + ".findMember", record.getMemberId());
System.out.println(retrieved);
System.out.println(">>> フィールド更新");
record.setDisplayName("updated_sample_01");
session.update(baseNs + ".changeStatus", record);
Member confirmed = session.selectOne(baseNs + ".findMember", record.getMemberId());
System.out.println("Post-update state: " + confirmed);
System.out.println(">>> 全件一覧表示");
List<Member> allRecords = session.selectList(baseNs + ".listAll");
allRecords.forEach(System.out::println);
System.out.println(">>> 指定IDによる削除処理");
session.delete(baseNs + ".dropMember", record.getMemberId());
List<Member> residual = session.selectList(baseNs + ".listAll");
System.out.println("Remaining records count: " + residual.size());
}
}
}