本記事では、私がMyBatisを学ぶにあたって、一番基礎となる最初に最低限押さえるべきと感じた内容についてまとめました。
目次
MyBatis概要
MyBatisとは
- JavaのアプリケーションとRDBとのやりとりを簡略化するデータマッパーフレームワーク
- O/Rマッパーの一種
- SQLクエリを用いてデータベースの操作をより直接的に制御するため、複雑なクエリやパフォーマンス最適化が必要な場合に特に有用
MyBatisの特徴
手動のSQLコントロール | MyBatisはSQL文を直接書くことができる 複雑なクエリや最適化が必要な場合に、DBへのより直接的なアクセスが可能 |
柔軟なマッピング | クエリ結果をPOJOや他の任意のJavaオブジェクトにマッピングできる カスタムマッピングもサポートされていいる |
動的なSQL | 動的なSQLの生成をサポートしており、条件に基づいてクエリを組み立て可能 |
キャッシュ管理 | 結果をキャッシュする機能を提供し、クエリの再実行を最小限に抑えることができる |
トランザクション制御 | トランザクションの管理も可能 |
POJO(Plain Old Java Object)とは
- 特定のフレームワークやライブラリに依存せず、純粋なJavaコードで構成されたオブジェクトを指す
- 特別な規則や制約を必要とせずに、Javaの基本的な機能だけを使用して作成されたオブジェクト
- 特定のORMライブラリやDIコンテナなどに依存しないため、コードの再利用性やテスト容易性が高まる
- また、シンプルで読みやすいコードを提供するため、保守性が向上する
一般的なORMとの違い
- 従来のORMと比べ、MyBatisはよりSQLに近いアプローチを取るため、オブジェクトとデータベースのマッピングが明示的に行われる
- このため、繊細な制御が必要な場合や、既存のSQLクエリを活用したい場合に向いている
MyBatis使用方法
pom.xmlファイルでの事前設定(依存関係追加)
pom.xml
- pom.xmlに依存関係を追加
- バージョン確認もpom.xmlで確認可能
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
各ファイル(Model / Mapper / Service / XML)の作成
Model(Entity)ファイル
- DB名と同じ名前でModel(Entity)クラスを作成
@Data
public class User {
private int userId;
private String name;
private int age;
}
XMLファイル
- Mapperインターフェースと同名でXMLファイルを作成し、同一パッケージ内に配置する
- namespace属性にMapperインターフェースを完全修飾名で指定することで紐付けできる
- その上でCURDに対応したXMLタグのid属性をメソッドとして呼び出す
- resultMapで具体的にカラムや型を指定する
項目 | 内容 | 備考 |
---|---|---|
id | resultMapのID | 後のSQL文で指定 |
type | resultMapの型 | 用意したModel(Entity)を指定 原則DB名と一致する |
column | DBのカラム名 | 小文字大文字の違いは無視して紐付け |
jdbcType | カラムのデータ型 | —- |
property | プロパティとしての名前 | Model(Entity)のフィールド名を指定 |
<?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.co.hoge.mybatis.mapper.UserMapper">
<resultMap id="userMap" type="jp.co.hoge.mybatis.entity.User">
<result column="id" jdbcType="INTEGER" property="userId" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<select id="selectAll" resultMap="userMap">
SELECT id, name, age FROM user
</select>
</mapper>
クエリ結果のカラムとJavaオブジェクトのプロパティをマッピングする際に、カラム名とプロパティ名が一致しない場合、カラムの別名(AS句)を使用することが一般的
- 逆に、resultMap内でカラムとプロパティをマッピングできていればAS句によるマッピングは不要
- 正しくマッピングされていないと、null落ち等エラーの温床になるので要注意
- XML内でよくある処理として、複数の値をセットするやり方がある
<!-- idListが1,3,5の場合の出力:WHERE user.id IN (1, 3, 5) -->
WHERE user.id IN
<foreach close=")" collection="idList" item="e" open="(" separator=",">
#{e}
</foreach>
Mapper(Interface)ファイル
- Modelのファイル名の最後をMapperにするとわかりやすい
- 戻り値とXMLファイル側でマッピングするSQL文のidをメソッド的に設定
- @Paramアノテーションで複数の引数を渡す方法
- parameterTypeは必須ではない、2つ以上ある場合は設定しなくても良い
- 代わりに@Paramを付ける
- @Paramアノテーションで複数の引数を渡す方法
@Mapper
public interface UserMapper {
List<User> selectAll();
}
mapperタグ内で他に利用したいSQL文がすでに存在する場合、以下の構文でincludeできる
<include refid="sample" />
Serviceファイル
- Serviceファイルとは、ビジネスロジックを実装するためのコンポーネント
- Mapperファイルがデータベースとのやり取りを担当するのに対して、Serviceファイルはそれらのデータベース操作を利用して、具体的なアプリケーションの機能やビジネスロジックを実現する
public class UserService {
public List<User> getAllUser(){
return UsedMapper.selectAll();
}
}
Serviceファイル経由でMapperオブジェクトを呼び出す
Controller
@Controller
public class UserListController {
@GetMapping("/")
public ModelAndView listAll() {
ModelAndView mav = new ModelAndView("index");
// すべてのユーザーを取得する
mav.addObject("users", UserService.selectAll());
return mav;
}
}
View
<!DOCTYPE html>
<html lang="jp" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>All Users</h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.userId}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
</tr>
</tbody>
</table>
</body>
</html>
その他確認したこと
_parameter
- SQL文中の「_parameter」指定は、XML形式のSQLマッピングファイルで使用される
- 例えば、
<when test="null != _parameter">
という条件の場合、_parameter
という変数(またはパラメータ)がnullでない場合に真となる - マッピングファイル中の
_parameter
は、実際のコード実行時にパラメータ付与される値に置き換えられる- 具体的なコードの実装や実行環境によって、
_parameter
がどのように設定されるかは異なる
- 具体的なコードの実装や実行環境によって、
参考になったページ
非常に丁寧にまとまっていて、参考になりました!ありがとうございます!
https://camp.trainocate.co.jp/magazine/about-mybatis-spring/autoMapping等について参考にさせていただきました。ありがとうございます!
【MyBatis】resultMapで自動的にマッピング(autoMapping)する方法
階層構造でautoMappingを利用する方法 MyBatisでは、次のようにを利用することで、ネストしたリスト(階層構造)を手動でマッピングできます。
ルールが分かりやすく明記されています。ありがとうございます!
絶対分かるMyBatis!MyBatisで覚えるべきチェックルール25(前半) - Qiita
はじめに今回はO/R MappingツールであるMyBatisの概要とその使い方について、初心者がよく間違えるポイントを踏まえ、チェックルールとして纏めてみました。(2018/10/24 追...
@Paramについて調べた時にヒットしました。ありがとうございます!
Mybatisで複数の引数を識別させる方法 - Qiita
はじめに検索結果を取得する機能で、「入力フォームから取得した検索条件」と「事前に準備した非表示のリスト」という2つの引数で絞り込みを行いたい場面に遭遇した。そこ...
コメント