MyBatisについて(2)
関連記事になります
↓ ↓ ↓ ↓
1. カスタムSQLと動的SQLの書き方
1-1 カスタムSQLの基本概念
カスタムSQLにより、コードがフレームワークと分離され、メンテナンス性や可読性が向上します。
例えば、ユーザーIDで情報を取得するクエリは以下のように実装されます。
<select id="getUserById" parameterType="int" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
id: SQL文を識別するための一意なID。このIDは、MyBatisがマッパーファイル内でメソッドを呼び出す際に使用される名前として機能します。
parameterType、resultType: SQL文で使用されるパラメータや結果セットをJavaオブジェクトと対応付けるための設定。parameterTypeはSQL文に渡すパラメータの型を指定し、resultTypeはSQL文の結果をマッピングするJavaオブジェクトの型を指定します。
#{}: SQLインジェクションを防ぐためのプレースホルダを利用
1-2 動的SQLの実装
変動するコンディションに対応するため、MyBatisは動的SQLを構築するためのタグを提供します。
タグ: 条件に従いてSQLを分岐
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
タグ: 複数条件の分岐を最適化
<choose>
<when test="type == 1">SELECT * FROM admin_users</when>
<when test="type == 2">SELECT * FROM normal_users</when>
<otherwise>SELECT * FROM users</otherwise>
</choose>
タグ: UPDATE文での動的SQLの構築
<update id="updateUser">
UPDATE users
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>
2. MyBatisのキャッシュ機能について
2-1 キャッシュの概要
MyBatisはパフォーマンスを向上させるために2種類のキャッシュを提供します。
1次キャッシュ: 同一のSqlSession内で作成されるキャッシュ
2次キャッシュ: スコープをマッパー単位で保持するキャッシュ
2-2 1次キャッシュ
デフォルトで有効
SqlSessionが終了すると消去
コード例
SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("getUserById", 1);
User user2 = session.selectOne("getUserById", 1); // キャッシュが利用される
2-3 2次キャッシュ
設定例
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
詳細説明
eviction: キャッシュ解除の方法。
flushInterval: キャッシュの自動消去インターバル
size: キャッシュサイズ
3. 複数マッピングやリレーションの扱い方
3-1 1対1のマッピング
1対1のマッピングは、エンティティ間の単純なリレーションを表現する際に使用されます。
例: ユーザーとアドレスの関係
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
</association>
</resultMap>
この設定では、usersテーブルのデータに基づいてaddressテーブルのデータをネストした形で取得できます。associationタグを使用することで、関連データが1対1の形で正確にマッピングされます。
3-2 1対複数のマッピング
1対複数のマッピングは、親エンティティが複数の子エンティティを持つ場合に使用されます。
例: ユーザーと注文の関係
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="item" column="item"/>
</collection>
ここでは、collectionタグを使い、ユーザーごとに関連する注文をリストとして取得できます。このようなマッピングは、親エンティティ(ユーザー)とその子エンティティ(注文)を効率的に関連付けるために役立ちます。また、N+1クエリ問題を避けるために<select>の中でjoinを使用することも検討すべきです。
3-3 複数対複数のマッピング
複数対複数の関係は、中間テーブルを使用して管理されます。
例: 学生とコースの関係
<resultMap id="studentWithCoursesResultMap" type="Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<collection property="courses" ofType="Course">
<id property="id" column="course_id"/>
<result property="name" column="course_name"/>
</collection>
</resultMap>
このマッピングは、中間テーブルを活用して、学生とコースの関係を適切に取得します。中間テーブルを介したデータのフェッチを最適化するために、joinを使用することが推奨されます。
まとめ
MyBatisのカスタムSQL、キャッシュ、マッピングを理解し活用することで、柔軟かつ効率的なデータ操作が可能になります。
今回はここまでとなります。最後まで閲覧いただきありがとうございます。