6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MyBatis とは? Java初学者のための基礎解説

Posted at

はじめに

「Railsの『ActiveRecord』やLaravelの『Eloquent』などのORM(O/Rマッピング)に慣れて、あまりSQLを書くことがない」ということはありませんか?

この記事は、SQLの基礎知識を学んだ方、そしてJava初学者を対象に、MyBatisの基本的な使い方を解説します。実践に活かしやすいように必要最低限の情報だけをまとめました。

MyBatisとは

MyBatisは、Javaアプリケーションからデータベースを操作するための永続化フレームワークです。SQLをXMLファイルまたはアノテーションで記述することで、JDBC(Java Database Connectivity)を直接操作する手間を省き、オブジェクトとリレーショナルデータベース間のマッピングを容易にします。

MyBatisの特徴

主な特徴は以下の通りです。

  • SQLの分離: JavaコードからSQLを分離し、XMLファイルに記述することで、SQLの管理がしやすくなります
  • 柔軟なSQL記述: 動的なSQLを記述できるため、条件に応じた複雑なクエリも簡単に扱えます
  • シンプルなマッピング: データベースの行をJavaオブジェクトに自動的にマッピングできます
  • 高いパフォーマンス: 必要に応じて手動でSQLを最適化できるため、パフォーマンスを追求しやすいです

ORMとSQLマッピングの違い

ORM (Object-Relational Mapping)

ORMは、データベースのテーブルをプログラミング言語のオブジェクトクラス)として直接扱うための技術です。開発者はSQLを直接書く代わりに、オブジェクトの操作を通じてデータベースと対話します。

SQLマッピング

開発者がSQLを直接記述し、そのSQLの結果をプログラミング言語のオブジェクトに「マッピング」することを主な役割とする技術です。

ORMとSQLマッピングの比較表

特徴 ORM(オブジェクトリレーショナルマッピング) SQLマッピング(SQL Mapper)
SQLの扱い 自動生成される。開発者は原則書かない。 開発者が直接記述する。
抽象化 高い。オブジェクト中心の思考。 低い。SQLとデータベース構造を意識する。
開発速度 定型的なCRUDでは非常に速い。 定型的なCRUDではORMより遅い。複雑なクエリでは速い場合がある。
パフォーマンス 自動生成SQLの非効率性からボトルネックになる可能性あり。チューニングはフレームワークの知識が必要。 SQLを直接書くため、最適化しやすい。開発者のSQLスキルに依存。
DBの独立性 高い。フレームワークが吸収する。 低い。DB固有のSQLを書くと切り替えが難しい。
学習コスト フレームワークの複雑な概念を学ぶ必要がある。 SQLの知識が必須。マッピングの概念は比較的シンプル。
最適なユースケース オブジェクト指向的な設計を重視し、迅速な開発が必要なシステム。 複雑なクエリ、パフォーマンス要求の高い部分、既存DBとの連携が必要なシステム。
代表例 Hibernate/JPA(Java), ActiveRecord(Ruby on Rails), Eloquent ORM(Laravel), SQLAlchemy(Python) MyBatis(Java), Spring JDBCテンプレート(Java), jOOQ(Java),Dapper(.NET)

開発環境

この記事では、以下の環境を想定して解説を進めます。

設定

Spring BootアプリケーションでMyBatisを利用する場合、主にapplication.propertiesまたはapplication.ymlファイルでデータベース接続情報を設定します。

application.properties

spring.datasource.url=jdbc:postgresql://db:5432/dev
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver

mybatis.mapper-locations=classpath:/mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

application.yml

spring:
  datasource:
    url: jdbc:postgresql://db:5432/dev
    username: username
    password: password
    driver-class-name: org.postgresql.Driver
mybatis:
  mapper-locations: classpath:/mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

Mapper XMLファイル

MyBatisでは、SQL文をXMLファイルに記述するのが一般的です。これらのファイルをMapper XMLファイルと呼びます。通常、src/main/resources配下に配置します。
例: UserMapper.xml

<?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.example.demo.mapper.UserMapper">

</mapper>

namespace属性には、通常対応するJavaのMapperインターフェースの完全修飾名を指定します。

sql

sqlタグを使用すると、複数のクエリで共通して使用するSQLフラグメントを定義できます。これにより、SQLの再利用性を高めることができます。

<sql id="userColumns">
    id, name, email
</sql>

<select id="selectUserById" resultType="com.example.demo.model.User">
    SELECT
    <include refid="userColumns"/>
    FROM users
    WHERE id = #{id}
</select>

resultMap

resultMapは、データベースで取得した結果セットからJavaオブジェクトへのマッピングを詳細に定義するために使用します。特に、テーブルの列名とJavaオブジェクトのプロパティ名が異なる場合や、複合オブジェクト(ネストされたオブジェクトやコレクション)をマッピングする場合に強力です。

<resultMap id="userResultMap" type="com.example.demo.model.User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
    <result property="email" column="user_email"/>
</resultMap>
  • id: 主キーとなるプロパティと列をマッピングします
    • property: Javaオブジェクトのプロパティ名
    • column: データベースの列名
  • result: 主キー以外のプロパティと列をマッピングします。idタグと同様にpropertyとcolumn属性を使用します

association

associationは、あるオブジェクトが他の単一のオブジェクトを含む場合(1対1の関係)にマッピングを定義します。

<resultMap id="userAddressResultMap" type="com.example.demo.model.User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
    <association property="address" javaType="com.example.demo.model.Address">
        <id property="id" column="address_id"/>
        <result property="street" column="street_name"/>
        <result property="city" column="city_name"/>
    </association>
</resultMap>

collection

collectionは、あるオブジェクトが他のオブジェクトのコレクションを含む場合(1対多の関係)にマッピングを定義します。

<resultMap id="blogResultMap" type="com.example.demo.model.Blog">
    <id property="id" column="blog_id"/>
    <result property="title" column="blog_title"/>
    <collection property="posts" ofType="com.example.demo.model.Post">
        <id property="id" column="post_id"/>
        <result property="title" column="post_title"/>
        <result property="content" column="post_content"/>
    </collection>
</resultMap>

select

selectタグは、データベースからデータを取得するためのSQLクエリを定義します。

<select id="findAllUsers" resultType="com.example.demo.model.User">
    SELECT id, name, email FROM users
</select>

<select id="findUserById" parameterType="int" resultMap="userResultMap">
    SELECT user_id, user_name, user_email FROM users WHERE user_id = #{id}
</select>
  • id: Mapperインターフェースのメソッド名と一致させます
  • parameterType: SQLクエリに渡される引数の型を指定します。Javaのプリミティブ型や完全修飾クラス名を指定できます。省略することも可能です
  • resultType: クエリの結果をマッピングするJavaオブジェクトの完全修飾クラス名を指定します。データベースの列名とJavaオブジェクトのプロパティ名が一致する場合に便利です。
  • resultMap: resultTypeの代わりにresultMapのIDを指定することで、より詳細なマッピングルールを適用できます

insert, update, delete

insert, update, deleteタグは、それぞれデータベースにデータを挿入、更新、削除するためのSQLクエリを定義します。

<insert id="insertUser" parameterType="com.example.demo.model.User" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>

<update id="updateUser" parameterType="com.example.demo.model.User">
    UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>

<delete id="deleteUser" parameterType="int">
    DELETE FROM users WHERE id = #{id}
</delete>
  • useGeneratedKeys: データベースが自動生成するキー(例: オートインクリメントのID)をMyBatisが取得し、指定されたkeyPropertyにセットするかどうかを指定します
  • keyProperty: 自動生成されたキーをセットするJavaオブジェクトのプロパティ名を指定します

おわりに

ORMO/Rマッピング)による基本的なCRUD操作は、SQLを書かずに実装できるのでスピーディーに開発するのに適しています。
対してMyBatisのようなSQLマッピングは、開発者がSQLを直接記述する自由度と引き換えに、データベース操作のより細かい制御とパフォーマンスの最適化が可能です。
システム全体でどちらか一方だけを使うのではなく、両者を組み合わせる「ハイブリッド」なアプローチも大切です。

参考記事

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?