学習のためのCRUDの基本実装をしました。備忘録としてまとめました。
画面上にHelloWorld実装まではできるものとして書いてます。
MySQLにはあらかじめテーブルを用意しています。
開発環境
- eclipse IDE
- Java 11
- maven
- Tymeleaf
- Mybatis
- MySQL
設定ファイルの編集
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_searchが呼ばれたとき動く。フォームに入力された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を表示
}
}
``######サービスクラス(画面からのリクエストを実行するクラス)
```java
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;
}
以上
長くなったので
画面周りのhtmlは次の記事→https://qiita.com/dende-h/items/9501d07c0e4088a0018c
感想・気づいたこと
- 一通りまとめたことで、処理の流れがつかめた。
- 途中で、実際には不要なコードがわかりより簡潔なコードにできた。
- ここから入力チェックや例外処理など機能を増やしていく。