MyBatis入門:データベース操作の基礎

本記事では、JavaベースのWebアプリケーション開発において、データベースアクセスを効率化するためのフレームワークであるMyBatisについて解説します。まず、MyBatisとは何かを理解しましょう。

MyBatisは、優れた永続化層(データを永続的に保存する層)のフレームワークです。アプリケーションのデータを一時的な状態(メモリ上)と永続的な状態(データベース)の間で変換する役割を担います。

JDBC(Java Database Connectivity)に比べて、より使いやすく、テンプレートが豊富であるため、開発のスピードアップにも貢献します。

永続層とは? 永続層とは、DAO層、サービス層、コントローラ層など、データの永続化処理を担うコードのブロックを指します。各層の役割は明確に分かれています。

なぜMyBatisを使うのか? 伝統的なJDBCは複雑なコードを書く必要がありました。MyBatisのようなフレームワークは、このプロセスを自動化し、開発者の手間を軽減します。SQL文とJavaコードを分離することで、保守性が向上し、学習曲線も緩やかになります。また、広く使われているため、情報も豊富です。

重要:技術に優劣はありません。優劣があるのは、プログラマーのスキルです。

実装の流れ:環境構築、依存関係の追加、コードの記述、テスト

手順:

  1. データベースの作成
  2. Mavenプロジェクトの新規作成
  3. srcディレクトリの削除(親プロジェクトとして扱う)
  4. 必要なライブラリの依存関係を追加(基本環境の構築完了)
  5. サブモジュールの作成とMyBatisの設定ファイルの記述
  6. コア設定ファイルの記述
  7. MyBatisの主要なコンポーネントの実装

MyBatisの実装手順:

  1. ユーティリティクラスの作成 まず、SqlSessionFactoryを生成するためのユーティリティクラスを作成します。このクラスは、設定ファイルを読み込む必要があります。そのため、リソースディレクトリに設定ファイルを配置します。

    MyBatisのアプリケーションは、SqlSessionFactoryのインスタンスを中心に構築されます。このファクトリからSqlSessionを取得でき、SQLコマンドを実行するためのすべてのメソッドが含まれています。

    staticブロックは、クラスがロードされた時点で実行されるため、初期化エラーを防ぐことができます。

    注意:SqlSessionFactoryを取得できれば、SqlSessionインスタンスを生成できます。まず、SqlSessionFactoryのスコープを広げるために、private static SqlSessionFactory factory; として宣言します。

package com.util;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.io.Resources;
import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory factory;
    static {
        try {
            String configPath = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(configPath);
            // リソースを読み込み、使用可能なオブジェクトを作成します。(Connectionに似ています)
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession openSession() {
        return factory.openSession();
    }
}
  1. 設定ファイルの記述
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/your_database?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8"/>
                <property name="username" value="your_username"/>
                <property name="password" value="your_password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/dao/UserMapper.xml"/>
    </mappers>
</configuration>
  1. エンティティクラス(POJO)の作成

エンティティクラスは、privateなフィールド、コンストラクタ、getter/setterメソッドを持ちます。通常、pojoパッケージに配置します。

package com.pojo;

public class User {
    private String userName;
    private String password;
    private String idNumber;
    private String departmentInfo;

    public User(String userName, String password, String idNumber, String departmentInfo) {
        this.userName = userName;
        this.password = password;
        this.idNumber = idNumber;
        this.departmentInfo = departmentInfo;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getIdNumber() {
        return idNumber;
    }

    public void setIdNumber(String idNumber) {
        this.idNumber = idNumber;
    }

    public String getDepartmentInfo() {
        return departmentInfo;
    }

    public void setDepartmentInfo(String departmentInfo) {
        this.departmentInfo = departmentInfo;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + ''' +
                ", password='" + password + ''' +
                ", idNumber='" + idNumber + ''' +
                ", departmentInfo='" + departmentInfo + ''' +
                '}';
    }
}
  1. Mapper(DAO)とMapper XMLの作成

DAOインターフェースはdaoパッケージに配置し、interface型で定義します。DAOはMapperと同義です。

設定ファイルを作成します。任意の場所に作成できますが、今回はリソースディレクトリに配置します。ファイル名はxxxxMapper.xmlとします。 このファイルの書き方: ヘッダにnamespaceを追加し、SQL文を使用するインターフェースを紐付けます。 mapper内のidは、元のメソッド名に相当します。 resultTypeは単一の結果を返し、resultMapはコレクションを返します。

注意:各mapper.xmlは、MyBatisの設定ファイルで登録する必要があります。

package com.dao;

import com.pojo.User;
import java.util.List;

public interface UserMapper {
    List<User> selectAllUsers();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.UserMapper">
    <select id="selectAllUsers" resultType="com.pojo.User">
        SELECT * FROM users;
    </select>
</mapper>

これでテストに進む準備が整いました。以下のコードを使用してテストを実行します。

リソースのフィルタリング問題が発生する可能性があります。その場合は、上記のXMLファイルをリソースディレクトリの直下に移動してください。 最後に、JUnitを使用してテストします。testディレクトリ内に上記と同じパッケージを作成し、そこにxxxMapperTestクラスを作成します。SqlSessionオブジェクトを取得し、SQLを実行します。

package com.dao;

import com.pojo.User;
import com.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {
    @Test
    public void testSelectAllUsers() {
        // SqlSessionオブジェクトを取得
        SqlSession session;
        session = MyBatisUtil.openSession();
        // 方法1:推奨。Mapperインターフェースを取得するため、キャストが不要で安全です。
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> userList = mapper.selectAllUsers();
        // 方法2:直接、インターフェース内の具体的なメソッドを使用する
        // List<User> userList = session.selectList("com.dao.UserMapper.selectAllUsers");
        for (User user : userList) {
            System.out.println(user);
        }
        session.close();
    }
}

テストが成功すれば、機能が正常に動作します。

mapperRegistryは、コア設定ファイル内でmappersを登録する場所です。 発生する可能性のある問題:

  1. 設定ファイルが登録されていない
  2. インターフェースの紐付けが誤っている
  3. メソッド名が一致しない
  4. 戻り値の型が一致しない
  5. Mavenのリソースエクスポートの問題

以下にプロジェクトのディレクトリ構造を示します。参考にしてください。

最後に、リソースのクローズを忘れないでください!

タグ: MyBatis Java JDBC Maven ORM

7月11日 20:19 投稿