16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

(初心者向け)MyBatisの基礎知識

Last updated at Posted at 2022-05-15

学習中のSpring bootで、新しくMybatisの学習をおこなったので、アウトプットも兼ねて投稿します。

MyBatisとは

DB(データベース)にアクセスできるフレームワークのこと。
Spring bootには他にもSpring data JpaやJPQLといったSQLを扱うライブラリやクエリ言語があるが、大きな違いとしては以下の通り。

①SQLをガッツリ書く必要がある。
②DBMSを意識する必要がある。(DBMSによってかけるSQLが異なるから)
③①、②を意識するためにSQLの知識が必要。

特にSpring Data Jpaは自動生成なのでほとんどSQLを意識することなくデータの取得等を行うことができる(※ORM)が、型が決まっていたりキーワードを組み合わせたりと、柔軟性がかけるところがある。逆にMyBatisは全てコードを記入する分面倒だが、より複雑なSQLも実行することができる利点がある。

※ORM = Object Relational Mappingの略。オブジェクトとデータベースをマッピングすることができ、SQLを直接書かなくてもオブジェクトのメソッドでDB操作ができる。
MyBatisもORMに含まれるが、完全なORMではない。

実際に書いてみた

手順は以下の通り。

①Modelクラスの作成
②Mapperの作成
③Serviceの作成
④Controllerの作成
⑤DBの設定

①Model(User.java) の作成

package dev.itboot.mb.model;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
	
	private Long id;
	
	@NotBlank
	@Size(max = 60)
	private String userName;
	
	@NotBlank
	@Email
	@Size(max = 254)
	private String email;

}

②Mapper(UserMapper.java)の作成

package dev.itboot.mb.repository;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import dev.itboot.mb.model.User;

@Mapper
public interface UserMapper {
	
	//全件取得
	@Select("SELECT * FROM user")
	List<User> selectAll();
	
	
	//1件取得
	@Select({"SELECT * FROM user",
			 "WHERE id = #{id}"
		})
	User selectByPrimaryKey(Long id);
	
	
	//登録
	@Insert({
		"INSERT INTO user(user_name, email)",
		"VALUES(#{userName}, #{email})"
	})
	int insert(User record);
	
	
	//更新
	@Update({
		"UPDATE user",
		"SET user_name = #{userName}, email = #{email}",
		"WHERE id = #{id}"
	})
	int updateByPrimaryKey(User record);
	
	
	//削除
	@Delete({
		"DELETE FROM user",
		"WHERE id = #{id}"
	})
	int deleteByPrimaryKey(Long id);
}

③Service(UserService.java)の作成

package dev.itboot.mb.service;

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.stereotype.Service;

import dev.itboot.mb.model.User;
import dev.itboot.mb.repository.UserMapper;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Transactional
@Service
public class UserService {

	private final UserMapper mapper;
	
	//全件取得
	public List<User> selectAll(){
		return mapper.selectAll();
	}
	
	//1件取得
	public Teacher 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);
	}
}

④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.UserService;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Controller
public class UserController {
	
	private final UserService service;
	
	//全件取得
	@GetMapping("/")
	public String getAllUsers(Model model) {
		
		model.addAttribute("page", service.selectAll());
		
		return "list";
	}
	
	@GetMapping("/add")
	public String addUser(@ModelAttribute User user) {
		return "form";
	}
	
	@PostMapping("/process")
	public String process(@Validated @ModelAttribute User user, BindingResult result) {
		if(result.hasErrors()) {
			return "form";
		}
		service.save(User);
		
		return "redirect:/";
	}
	
	@GetMapping("/edit/{id}")
	public String editUser(@PathVariable Long id, Model model) {
		model.addAttribute("user", service.selectByPrimaryKey(id));
		return "form";
	}
	
	@GetMapping("/delete/{id}")
	public String deleteUser(@PathVariable Long id) {
		service.deleteByPrimaryKey(id);
		return "redirect:/";
	}

}

⑤DBの設定

application.properties に下記を記載。(今回はh2データベースを使用。)

spring.datasource.url=jdbc:h2:mem:testdb

schema.sql ファイルを作成。下記を記載。

create table if not exists user (
	id bigint not null auto_increment primary key,
	user_name varchar(60) not null,
	email varchar(254) not null
);

data.sql ファイルを作成。下記を記載。

insert into user(user_name, email)
values('user', 'user@example.com');

MyBatis作成時のポイント

ポイント①

アノテーションの使い方は以下の通り。

アノテーション 用途
@Select データ取得
@Insert データ登録
@Update データ更新
@Delete データ削除

ポイント②

SQL内で変数を渡すときは、

"#{変数名}"

で宣言する。メソッドの引数の変数名と合わせると、メソッドで渡ってきた引数の値がSQLに反映される。

@Select({"SELECT * FROM user",
			 "WHERE id = #{id}"
		})
	User selectByPrimaryKey(Long id);

クラスの中身を渡すときは、

"#{フィールド名}"

と宣言する。これにより、メソッドの引数で渡ってきたインスタンスのフィールドにアクセスできる。

	@Insert({
		"INSERT INTO user(user_name, email)",
		"VALUES(#{userName}, #{email})"
	})
	int insert(User record);

ポイント③

改行をするときは、配列 {} か文字列連結 + で行う。

// 配列{}の場合
@Select({"SELECT * FROM user",
			 "WHERE id = #{id}"
		})
	
//+の場合
@Select({"SELECT * FROM user"
			+ "WHERE id = #{id}"
		})

以上でMyBatis側の設定は完了になります。
あとはHtmlを作成し、うまく表示できれば完了です。
※今回はMyBatisの設定方法をまとめたので、Htmlは省略。

簡単なCRUD操作のみであればSpring Data Jpa、複雑なSQLが必要であればMyBatisで使い分けていけば良いかと思いました。
SQLとSpring bootをどちらも並行して学ぶのであれば、やはりMyBatisを利用していくのが良いかと思いました。

参考文献

16
14
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
16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?