Springboot+Tymeleaf+Mybatis+MySQLでのCRUD処理実装(基本)

やったこと

  •  基本のCRUD処理の実装
  •  Javaコードの処理の流れをまとめ

コード

application.propertiesにmySqlとの接続情報を記述

spring.datasource.url = jdbc:mysql://localhost/データベース名?serverTimezone=Asia/Tokyo
spring.datasource.username = root
spring.datasource.password = データベースのパスワード
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.mvc.hiddenmethod.filter.enabled: true

Pom.xmlへの依存関係の記述(プロジェクト生成時依存関係セットに足りないものを追加)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>SymphogearTest</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SymphogearTest</name>
	<description>project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.2.0</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>ture</optional>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

コントローラークラス(画面操作と処理の実行をつなぐクラス)

package io.spring.gungnir.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
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 org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import io.spring.gungnir.dto.UserSearchRequest;
import io.spring.gungnir.entity.User;
import io.spring.gungnir.service.UserService;

@Controller //コントローラークラスの宣言
public class UserController {
	
	@Autowired //サービスクラスのnewを自動でしてくれるアノテーション
	UserService userService;
	
	/*
	 * URL(localhost:8080/user)でアクセスでトップ画面の表示
	 */
	@GetMapping(value = "/user") //このURLにマッピングされておりGetするとメソッドが動く
	public String display() {
		return"top"; //top.htmlの画面を表示
	}
	

	/*
	 * 一件検索するためのフォームを表示
	 */
	@GetMapping(value = "/user/search") //トップ画面でto search formを押下した時の画面遷移
	public String displaySearch() {
			return"player_search"; //player_search.htmlの画面を表示
	}
	

	/*
	 * 一件検索の実行
	 */
	@RequestMapping(value = "/user/id_search", method = RequestMethod.POST ) 
  //searchボタンを押され/user/id_seachが呼ばれたとき動く。フォームに入力されたIDをpostで受け取る
	
 public String search(@ModelAttribute UserSearchRequest userSearchRequest, Model model){  
  //@ModelAttributeがpostされたリクエストをuserSearchReqesutに格納する(同時にnewする)
		
  User user = userService.search(userSearchRequest); //サービスクラスのメソッドにuserSerchReqestを引数として渡す
		model.addAttribute("user_info",user); 
   //サービスクラスメソッドの結果をuserに詰める。テンプレートで使うキーとして”user_info”を指定
		
  return"player_search"; //player_search.htmlの画面を表示
	}
	

  /*
	 * 全件表示
	 */
	@PostMapping(value = "/user/list") //player listボタンで/user/listが呼ばれたとき動く
	public String getUserList(Model model) {
		List <User> list = userService.searchAll();
		//リスト型でサービスクラスのインスタンスメソッドを呼び出す(リスト取得の指示だし)
		model.addAttribute("users_info", list); //結果をlistに詰める。(users_infoがキー)
		return "list";	//list.htmlの画面を表示
	}
	

 /*新規プレイヤー登録画面を表示
	 * 画面遷移のみ
	 */
	@PostMapping(value = "/user/add") //to sing up formのボタンで/user/addが呼ばれたとき動く
	public String displayAdd() {
		return "add_player"; //add_playerの画面を表示
	}
	
	
 /*登録の実行
	 * 登録情報の表示
	 */
	@RequestMapping(value = "user/add_comp", method = RequestMethod.POST ) 
  //sign upが押され/user/add_compが呼ばれた時動く。フォームの内容をpostで受け取る
	
 public String create(@ModelAttribute UserSearchRequest userAdd, Model model) {
		//postされたリクエストをusesrAddに格納+new
		
  userService.create(userAdd);//追加処理の実行をサービスクラスに指示
		User user = userService.createCheck(userAdd); //追加した情報をセレクトしとってくるよう指示
		model.addAttribute("user_add", user); //セレクト結果をuserに詰める。(user_addをキー)
		return "add_comp";	//add_comp.htmlの画面を表示	
	}
	
	
 /*
	 * 編集画面への遷移
	 */
	@PutMapping(value = "/user/conf/id={id}") //updateが押されたとき動く
	public String editSelect(@PathVariable("id")String id ,Model model){
  //@PathVariableでURL内のidを引数に取得

		User user = userService.editSelect(id); //取得したidを渡してセレクト指示
		model.addAttribute("user_select",user); //セレクト結果をuserに詰める。(user_selectがキー)
		return "conf_player"; //conf_player.htmlを表示
 }
 

 /*
  *編集の実行
  */
	@RequestMapping(value = "/user/edit/id={id}", method = RequestMethod.POST) //editボタンが押されたとき動く
	public String update(@ModelAttribute UserSearchRequest edit) {
		userService.update(edit); //postされたリクエストが格納されたeditを引数にupdateメソッド呼び出し
		
		return "edit"; //edit.htmlを表示	
	}
	
	
 /*削除の実行
	 * 
	 */
	@DeleteMapping(value = "user/delete/id={id}") //deleteボタンが押されたとき動く
	public String displayDelete(@ModelAttribute UserSearchRequest delete) {
		userService.deleteOne(delete); postされたリクエストが格納されたdeleteを引数にdeleteOneメソッド呼び出し
		return "delete"; //delete.htmlを表示
	}
}

サービスクラス(画面からのリクエストを実行するクラス)

package io.spring.gungnir.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import io.spring.gungnir.dto.UserSearchRequest;
import io.spring.gungnir.entity.User;
import io.spring.gungnir.repository.UserMapper;

@Service //サービスクラスの宣言
public class UserService {
	
	@Autowired //userMapperを自動でnewしてくれる
	private UserMapper userMapper;
	
 
  /*
  * 一件検索表示
   */
  public User search(UserSearchRequest userSearchRequest) {
		return userMapper.search(userSearchRequest); //検索結果をリターンで受け取る
	}
	

 /*
	 * 全件表示
	 */
	public List<User> searchAll(){
		return userMapper.searchAll(); //全件のリストをリターンで受け取る
	}
	

	/*
	 * 新規追加処理
	 */
	public void create(UserSearchRequest userAdd) {
		userMapper.create(userAdd);
	}
	

 /*
	 * 追加情報を画面表示
	 */
	public User createCheck(UserSearchRequest userAdd) {
		return userMapper.createCheck(userAdd);
	}
	
 
 /*
   * 編集対象の検索
   */
	public User editSelect(String id) {
		return userMapper.editSelect(id);
	}
	

 /*
   * 編集実行
   */
	public void update(UserSearchRequest edit) {
		userMapper.edit(edit);	
	}
	

 /*
	 * レコード情報削除
	 */
	public void deleteOne(UserSearchRequest delete) {
		userMapper.deleteOne(delete);
	}

}

マッパークラス(データベースを操作するクラス)

package io.spring.gungnir.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 io.spring.gungnir.dto.UserSearchRequest;
import io.spring.gungnir.entity.User;


@Mapper //マッパークラスの宣言
public interface UserMapper {



	/*
	 * プレイヤー情報検索
	 */
	@Select("SELECT * FROM symphogear_players WHERE id = #{id}")
	User search(UserSearchRequest user);

	
	/*
	 * 全件表示
	 */
	@Select("SELECT * FROM symphogear_players")
	List<User> searchAll();
	
	
	/*
	 * 新プレイヤー情報登録 
	 */
	
	@Insert("INSERT INTO symphogear_players(id,name,symphogear_name)"
			+ "VALUES (#{id},#{name},#{symphogear_name})")
	void create(UserSearchRequest userAdd);
	
	
	/*
	 * 新追加情報表示
	 */
	@Select("SELECT * FROM symphogear_players WHERE id = #{id}")
	User createCheck(UserSearchRequest userAdd);
	
	
	/*
	 * 編集用の情報セレクト
	 */
	@Select("SELECT * FROM symphogear_players WHERE id = #{id}")
	User editSelect(String id);
	
	
	/*
	 * 情報編集 
	 */
	@Update("UPDATE symphogear_players "
			+ "SET name = #{name}, symphogear_name = #{symphogear_name} "
			+ "WHERE id = #{id}")
	void edit(UserSearchRequest edit);	

	
	/*
	 * レコード削除
	 */
	@Delete("DELETE FROM symphogear_players WHERE id = #{id}")
	void deleteOne(UserSearchRequest delete);
	
}

DTOクラス(画面からのリクエストデータを格納するクラス)

package io.spring.gungnir.dto;

import java.io.Serializable;

import lombok.Data;



	@Data //セッター、ゲッターを記述しなくても使用できるようになる
	public class UserSearchRequest implements Serializable{
		
		private String id;
		private String name;
		private String symphogear_name;
	}

エンティティクラス(データベースから取得したデータを格納するクラス)

package io.spring.gungnir.entity;

import lombok.Data;

@Data
public class User {

	/*
	 * ユーザー情報 entity
	 */
	private String id;
	private String name;
	private String symphogear_name;

}

感想・気づいたこと

  • 一通りまとめたことで、処理の流れがつかめた。
  • 途中で、実際には不要なコードがわかりより簡潔なコードにできた。
  • ここから入力チェックや例外処理など機能を増やしていく。

← Go home
;