現在学習中のSpring bootで、SQLをXMLに記入し、Mybatisと合わせて利用することを学んだので、アウトプットも兼ねて投稿します。
MyBatisとは
DB(データベース)にアクセスできるフレームワークのこと。
Spring bootには他にもSpring data JpaやJPQLといったSQLを扱うライブラリやクエリ言語があるが、大きな違いとしては以下の通り。
①SQLをガッツリ書く必要がある。
②DBMSを意識する必要がある。(DBMSによってかけるSQLが異なるから)
③①、②を意識するためにSQLの知識が必要。
MyBatisは完全なORMでは無いのでSQLを手書きする必要があるが、より複雑なSQLも実行することができる利点がある。
なぜXMLに記入するの?
MyBatisを利用するだけでも、アノテーションを用いて複雑なSQLを記入することはできます。
しかし、複雑なSQLをアノテーションを用いて記入しようとすると以下のようなデメリットもあります。
①可読性が悪くなる。
②アノテーション固有の制限もあって若干使いづらくなる
用途に合わせて使い分けられれば強いですね✨
実際に書いてみた
今回の手順は以下の通りで進めていきます。
1)プロジェクトの作成
2)MyBatipseのインストール
3)XMLファイルの作成
4)各クラスの作成
5)SQLの設定
6)application.propertiesを編集
7)schema.sqlファイルの作成
プロジェクトの作成
新規作成 → Springスタータープロジェクト でプロジェクトを作成します。
設定は以下の通りです。
依存関係は以下を選択します。
これでプロジェクトの作成は完了です。
MyBatipseのインストール
mybatipseは、XMLファイルの編集などを補助するプラグインです。
インストール方法
メニュー「ヘルプ」 → 「Eclipseマーケットプレース」をクリック。 →
検索欄で「Mybatipse」を検索 → インストールをクリック。
その後、
「使用条件に同意」 → 「完了」 → 「インストール」 → 「今すぐ再起動」
ここまででMyBatipseのインストールは完了です。
XMLファイルの作成。
「src/main/resources」ディレクトリ内にXMLファイルを作成。
作成方法
src/main/resourcesを右クリック → その他を選択
→MyBatis内の「MyBatis XML Mapper」を選択。
以下のように設定し、XMLファイルを作成します。
※親フォルダーを入力している点に注意!!
各クラスの作成
Model
package dev.itboot.mb.Model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
@NotBlank
@Size(max = 50)
private String name;
}
Mapper
package dev.itboot.mb.repository;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import dev.itboot.mb.Model.User;
@Mapper
public interface SampleMapper {
//全件取得
List<User> selectAll();
//1件取得
User selectByPrimaryKey(Long id);
//登録
int insert(User user);
//更新
int updateByPrimaryKey(User user);
//削除
int deleteByPrimaryKey(Long id);
}
解説
@Mepper → マッパーであることを示すアノテーションです。
insert、update、deleteのメソッドには、引数をintになっています。
Mybatisの標準では、これらのメソッドは処理した件数を返すようになっているからです。
戻り値は他にも、なし「void」、真偽「true」を選ぶことができます。
//登録
void insert(User user);
//登録 (成功した場合、trueを返す)
boolean insert(User user)
Service
package dev.itboot.mb.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import dev.itboot.mb.Model.User;
import dev.itboot.mb.repository.SampleMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
@Transactional
public class SampleService {
private final SampleMapper mapper;
//全件取得
public List<User> selectAll(){
return mapper.selectAll();
}
//1件取得
public User selectByPrimarykey(Long id) {
return mapper.selectByPrimaryKey(id);
}
//登録
public void save(User user) {
if(user.getId() == null) {
mapper.insert(user);
}else {
mapper.updateByPrimaryKey(user);
}
}
//削除
public void deletebyPrimaryKey(Long id) {
mapper.deleteByPrimaryKey(id);
}
}
解説
@Service → クラスがServiceであることを示すアノテーションです。
サービスはビジネスロジック層を表します。
※ビジネスロジック → 業務に関わる処理を行う層。例えば、SQLで取得した値に応じてJava側何らかの処理を行いたい場合、このService層でその処理を記述するということ。
トランザクション処理にすると、DB処理をまとめて一貫性を持たせることができます。
サービス層ではその一貫性を持たせるために、@Transactional アノテーションをつけることが主流です。
※トランザクション処理 → 分割できない一連の処理、流れのこと。
Controller
package dev.itboot.mb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import dev.itboot.mb.Model.User;
import dev.itboot.mb.service.SampleService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
public class SampleController {
final private SampleService service;
@GetMapping("/")
public String top(Model model) {
model.addAttribute("users" , service.selectAll());
//トップページへ遷移
return "index";
}
@GetMapping("/add")
public String add(@ModelAttribute User user) {
//登録用ページに遷移
return "form";
}
@PostMapping("/add")
public String insert(@Validated @ModelAttribute User user, BindingResult result) {
if(result.hasErrors()) {
return "form";
}
service.save(user);
return "redilect:/";
}
@GetMapping("/edit/{id}")
public String edit(@PathVariable Long id, Model model) {
model.addAttribute("user", service.selectByPrimarykey(id));
return "form";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable Long id) {
service.deletebyPrimaryKey(id);
return "redilect:/";
}
}
SQLの設定
XMLファイルを以下のように設定していきます。
<?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="dev.itboot.mb.repository.SampleMapper">
<!-- 全件取得 -->
<select id="selectAll" resultType="User">
select * from user;
</select>
<!-- 1件取得 -->
<select id="selectByPrimaryKey" resultType="User">
select * from user
where id = #{id}
</select>
<!-- 登録 -->
<insert id="insert">
insert into user(user_name)
values(#{name})
</insert>
<!-- 更新 -->
<update id="updateByPrimaryKey">
update user
set name = #{name}
where id = #{id}
</update>
<!-- 削除 -->
<delete id="deleteByPrimaryKey">
delete from user
where id = #{id}
</delete>
</mapper>
解説
SQLはタグ内に記入します。このとき、
id → java側のメソッド名と同じものにします。
resultType → 戻り値の型を記入します。コレクションを返す場合、中のオブジェクトを指定します。
resultMapタグを使用すれば、resultMapを返すことも可能です。
<resultMap id="user" type="User">
<id column ="id" property="id"/>
<result column ="name" property="name"/>
</resultMap>
<select id="selectAll" resultType="user">
select * from user;
</select>
application.propertiesを編集
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.type-aliases-package=dev.itboot.mb.model
#Add
spring.datasource.url=jdbc:h2:mem:testdb
解説
mybatis.configuration.map-underscore-to-camel-case
Javaのフィールド名にDBのカラム名をマッピングします。(キャメルケースにアンダースコアをマップします。)
mybatis.type-aliases-package
ここにはmodelのパッケージ名を記載します。
この設定を行うことで、XMLのresultTypeに記入するパッケージ名を省略することができます。
<!-- 設定あり -->
<select id="selectAll" resultType="User">
<!-- 設定なし -->
<select id="selectAll" resultType="dev.itboot.mb..model.User">
spring.datasource.url
DBの接続先URLを設定します。
今回はH2を使用します。
schema.sqlファイルの作成
schema.sqlでH2にDBを作成します。
create table if not exists user (
id bigint not null auto_increment primary key,
name varchar(60) not null
);
以上で設定は終了になります!
Viewの設定は今回は省略します。
Mybatisとアノテーションだけを使用してSQLを実行することは可能ですが、SQL文の記入のしづらさがやはりネックになると思います。
個人的にもXMLに記入する方法がおすすめです!
参考文献
前回投稿した参考記事