⇧ amazing...
MyBatisとは?
GitHubで公開されてるドキュメントによると、
The MyBatis SQL mapper framework makes it easier to use a relational database with object-oriented applications. MyBatis couples objects with stored procedures or SQL statements using an XML descriptor or annotations. Simplicity is the biggest advantage of the MyBatis data mapper over object relational mapping tools.
⇧ Java向けの「ORM(Object-relational mapping)」の1つかと。
「ORM(Object-relational mapping)」と言うと、
オブジェクト関係マッピング(英: Object-relational mapping、O/RM、ORM)とは、データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。オブジェクト関連マッピングとも呼ぶ。
⇧ ということらしい。
MyBatis はカスタム SQL、ストアドプロシージャ、高度なマッピング処理に対応した優れた永続化フレームワークです。 MyBatisを使うことで、直接 JDBC を扱うコードを書いたり、クエリ引数やクエリ結果を手動で設定する必要がほとんどなくなります。 MyBatis の設定やデータベースレコードと Java オブジェクトの関連付けは、XML またはアノテーションを使って行うことができます。
⇧ XML以外にもアノテーションでも使えるんですね、XMLを使ってる例が多いイメージがあるけど。
以前は iBATIS という名前で Apache プロジェクトの1つとして開発されていた。
しかし、 2010年6月に Apache ソフトウェア財団での開発が中止され、現在は MyBatis という名前で開発されている。
⇧ Apacheソフトウェア財団の手を離れても開発は継続されているようですかね。
MyBatis-Springとは?
公式のドキュメントによると、
MyBatis-Spring integrates MyBatis seamlessly with Spring. This library allows MyBatis to participate in Spring transactions, takes care of building MyBatis mappers and SqlSession
s and inject them into other beans, translates MyBatis exceptions into Spring DataAccessException
s, and finally, it lets you build your application code free of dependencies on MyBatis, Spring or MyBatis-Spring.
⇧ Spring Frameworkとの連携に特化してるってことなんですかね?
MyBatis-Spring adapter is an easy-to-use Spring bridge for MyBatis sql mapping framework.
⇧ う~む、分からん...
Spring Frameworkに特化ということなんだろうか?
MyBatis-Spring-Boot-Starterとは?
GitHubで公開してるドキュメントによりますと、
MyBatis Spring-Boot-Starter will help you to use MyBatis with Spring Boot
⇧ Spring BootでMyBatisを使う用途に特化したものらしい。
何か、
⇧ Apacheソフトウェア財団の手を離れたからなのかは分からないですが、様々なプロジェクトが入り乱れてる感があるよね...
Spring BootでMyBatisを使えるMyBatis-Spring-Boot-Starterを使ってみる
というわけで、
⇧ 上記サイト様を参考に使ってみる。
まぁ、公式のドキュメントの情報の足りないことこの上ない...
データベースはPostgreSQLを使っていきます。
テーブルなどは、
⇧ 上記の記事と同じものを利用していきます。
EclipseでSpring Bootなプロジェクトを作成で。
ビルドツールは、Gradleを使いたいので、「タイプ:」を「Gradle Project」で。
依存関係で「Spring Data JPA」は外します。
Spring Bootなプロジェクトが作成されました。
build.gradleにmybatis-spring-boot-starterの依存関係を追加。
plugins { id 'org.springframework.boot' version '2.7.5' id 'io.spring.dependency-management' version '1.0.15.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' // https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter implementation group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '2.2.2' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
で、application.propertiesにデータベースの接続設定を追記。
# データベース接続 spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5434/test spring.datasource.username=postgres spring.datasource.password=postgres # MyBatisでEntityクラスのフィールド名とデータベースのテーブルのカラム名の対応 mybatis.configuration.map-underscore-to-camel-case=true
⇧ 接続情報をご自分の環境に合わせてください。
まずは、Entityクラスを作成。
■/mybatis-example/src/main/java/com/example/demo/entity/ShikokuOhenro.java
package com.example.demo.entity; import lombok.Data; @Data public class ShikokuOhenro { private Long id; private String nameFudasyo; private String kanaNameFudasyo; private String romeNameFudasyo; private String nameTemple; private String kanaNameTemple; private String romeNameTemple; private Long prefecturesId; }
⇧ JPA(Java Persistence API)の時とは違い、@Entityアノテーションは不要。
続いてRepositoryインターフェイスを作成。MyBatisではMapperになるらしい。
■/mybatis-example/src/main/java/com/example/demo/repository/ShikokuOhenroMapper.java
package com.example.demo.repository; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import com.example.demo.entity.ShikokuOhenro; @Mapper public interface ShikokuOhenroMapper { @Select("select * from shikoku_ohenro where id = #{id}") ShikokuOhenro findById(@Param("id") Long id); @Select("select * from shikoku_ohenro") List<ShikokuOhenro> findAll(); }
続いてServiceクラスを作成
package com.example.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.entity.ShikokuOhenro; import com.example.demo.repository.ShikokuOhenroMapper; @Service public class ShikokuOhenroServiceImpl { @Autowired private ShikokuOhenroMapper shikokuOhenroMapper; public ShikokuOhenro findById(Long id) { return shikokuOhenroMapper.findById(id); } public List<ShikokuOhenro> findAll() { return shikokuOhenroMapper.findAll(); } }
RestControllerを作成
■/mybatis-example/src/main/java/com/example/demo/controller/ShikokuOhenroController.java
package com.example.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.example.demo.entity.ShikokuOhenro; import com.example.demo.service.ShikokuOhenroServiceImpl; @RestController public class ShikokuOhenroController { @Autowired private ShikokuOhenroServiceImpl shikokuOhenroServiceImpl; @GetMapping("find/{id}") public ShikokuOhenro findById(@PathVariable("id") Long id) { return shikokuOhenroServiceImpl.findById(id); } @GetMapping("find-all") public List<ShikokuOhenro> findAll() { return shikokuOhenroServiceImpl.findAll(); } }
で保存。
追加、追記したファイルは以下のような感じ。
諸々、用意できたら、アプリケーションを実行してみる。
ブラウザから、ControllerクラスのメソッドのURLにアクセスすると、
⇧ データベースのテーブルからデータが取得できてます。
XMLを使わなくてもMyBatisでデータ取得できるのは知らなんだけど、MyBatisもJPA(Java Persistence API)に劣らず使い方が複雑な気がしますかね...
XML使う方法だと、MyBatis流の記述で覚えることが多そうなのよね...
Spring BootでMyBatis使う場合、XMLとアノテーションのどっちが主流派なんですかね?
一応、
⇧ アノテーションでも、JOINとか使えるみたいだけど、JPA(Java Persistence API)のnativeQueryみたいに、普通のSQLに対応できるなら、一層、XML使いたくない気はするけども、ネットの情報が圧倒的にXMLを利用してるのが多いんよね...。
2022年11月9日(水)追記:↓ ここから
JOINを試してみます。areaテーブル作成
create table public.area ( id integer not null , name_area character varying(20) not null , kana_name_area character varying(50) not null , rome_name_area character varying(50) not null , created timestamp(6) with time zone default CURRENT_TIMESTAMP , updated timestamp(6) with time zone , is_deleted boolean default false , primary key (id) );
areaテーブルにデータ追加
-- エリアデータ INSERT INTO area (id, name_area, kana_name_area, rome_name_area) VALUES(1, '北海道地方', 'ほっかいどうちほう', 'hokkaido chihou') ,(2, '東北地方', 'とうほくちほう', 'touhoku chihou') ,(3, '関東地方', 'かんとうちほう', 'kantou chihou') ,(4, '中部地方', 'ちゅうぶちほう', 'chubu chihou') ,(5, '近畿地方', 'きんきちほう', 'kinki chihou') ,(6, '中国・四国地方', 'ちゅうごく・しこくちほう', 'chugoku sikoku chihou') ,(7, '九州地方', 'きゅうしゅうちほう', 'kyushu chihou');
で、Entityクラス作成
■/mybatis-example/src/main/java/com/example/demo/entity/Area.java
package com.example.demo.entity; import lombok.Data; @Data public class Area { private Long id; private String nameArea; private String kanaNameArea; private String romeNameArea; }
前に作っていたテーブルのEntityクラスも追加。
■/mybatis-example/src/main/java/com/example/demo/entity/Prefectures.java
package com.example.demo.entity; import lombok.Data; @Data public class Prefectures { private Long id; private String namePrefecture; private String kanaNamePrefecture; private String romeNamePrefecture; private String namePrefecturalCapital; private String kanaNamePrefecturalCapital; private String romeNamePrefecturalCapital; private Long areaId; }
JOINした時のEntityクラスを作成。
■/mybatis-example/src/main/java/com/example/demo/entity/custom/CustomShikokuOhenro.java
package com.example.demo.entity.custom; import lombok.Data; @Data public class CustomShikokuOhenro { private Long id; private String namePrefecture; private String kanaNamePrefecture; private String romeNamePrefecture; private String namePrefecturalCapital; private String kanaNamePrefecturalCapital; private String romeNamePrefecturalCapital; private Long areaId; private String nameFudasyo; private String kanaNameFudasyo; private String romeNameFudasyo; private String nameTemple; private String kanaNameTemple; private String romeNameTemple; private Long prefecturesId; private String nameArea; private String kanaNameArea; private String romeNameArea; }
Repositoryクラスの作成
■/mybatis-example/src/main/java/com/example/demo/repository/CustomShikokuOhenroMapper.java
package com.example.demo.repository; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.example.demo.entity.custom.CustomShikokuOhenro; @Mapper public interface CustomShikokuOhenroMapper { @Select("SELECT " + "so.id " + ",so.name_fudasyo " + ",so.kana_name_fudasyo " + ",so.rome_name_fudasyo " + ",so.name_temple " + ",so.kana_name_temple " + ",so.rome_name_temple " + ",so.prefectures_id " + ",ps.name_prefecture " + ",ps.kana_name_prefecture " + ",ps.rome_name_prefecture " + ",ps.name_prefectural_capital " + ",ps.kana_name_prefectural_capital " + ",ps.rome_name_prefectural_capital " + ",ps.area_id " + ",a.name_area " + ",a.kana_name_area " + ",a.rome_name_area " + "FROM shikoku_ohenro so " + "LEFT JOIN prefectures ps " + "ON so.prefectures_id = ps.id " + "LEFT JOIN area a " + "ON ps.area_id = a.id") List<CustomShikokuOhenro> findShikokuOhenroAndPrefecture(); }
Serviceクラスの追加。
■/mybatis-example/src/main/java/com/example/demo/service/CustomShikokuOhenroServiceImpl.java
package com.example.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.entity.custom.CustomShikokuOhenro; import com.example.demo.repository.CustomShikokuOhenroMapper; @Service public class CustomShikokuOhenroServiceImpl { @Autowired private CustomShikokuOhenroMapper customShikokuOhenroMapper; public List<CustomShikokuOhenro> findShikokuOhenroAndPrefectures() { return customShikokuOhenroMapper.findShikokuOhenroAndPrefecture(); } }
Controllerクラスに追記
■/mybatis-example/src/main/java/com/example/demo/controller/ShikokuOhenroController.java
package com.example.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.example.demo.entity.ShikokuOhenro; import com.example.demo.entity.custom.CustomShikokuOhenro; import com.example.demo.service.CustomShikokuOhenroServiceImpl; import com.example.demo.service.ShikokuOhenroServiceImpl; @RestController public class ShikokuOhenroController { @Autowired private ShikokuOhenroServiceImpl shikokuOhenroServiceImpl; @Autowired private CustomShikokuOhenroServiceImpl customShikokuOhenroServiceImpl; @GetMapping("find/{id}") public ShikokuOhenro findById(@PathVariable("id") Long id) { return shikokuOhenroServiceImpl.findById(id); } @GetMapping("find-all") public List<ShikokuOhenro> findAll() { return shikokuOhenroServiceImpl.findAll(); } @GetMapping("find-shikoku-ohenro-and-prefectures") public List<CustomShikokuOhenro> findShikokOhenroAndPrefectures() { return customShikokuOhenroServiceImpl.findShikokuOhenroAndPrefectures(); } }
で、ファイルの構成とかは以下になりました。
アプリケーションを起動して確認してみる。
⇧ テーブルの情報が取得できました。
MyBatisでアノテーションを使った場合でも通常のSQLのようにJOINとか使えるみたいですね。
2022年11月9日(水)追記:↑ ここまで
毎度モヤモヤ感が半端ない...
今回はこのへんで。