はじめに
前回の記事では、ユーザー情報をデータベースに登録し、ユーザー情報テーブルから、ログインできるように実装をしていきました。今回はユーザー情報を一覧で表示し、ユーザーと思います。ファイル構成
.
├── .gradle
├── .idea
├── build
├── gradle
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── practice
│ │ ├── config
│ │ │ └── SecurityConfig.java
│ │ ├── web
│ │ │ ├── user
│ │ │ │ ├── UserController.java
│ │ │ │ └── userForm.java
│ │ │ ├── order
│ │ │ │ ├── OrderController.java
│ │ │ │ └── OrderForm.java
│ │ │ └── IndexController.java
│ │ └── domain
│ │ ├── authentication
│ │ │ ├── CustomUserDetails.java
│ │ │ ├── CustomUserDetailsService.java
│ │ │ ├── User.java
│ │ │ ├── UserService.java
│ │ │ └── UserRepository
│ │ └── order
│ │ ├── OrderEntity.java
│ │ ├── OrderService.java
│ │ └── OrderRepository.java
│ │
│ └── resources
│ ├── static
│ ├── templates
│ │ ├── users
│ │ │ ├── creationForm.html
│ │ │ └── list.html
│ │ ├── order
│ │ │ ├── delete_confirmation.html
│ │ │ ├── detail.html
│ │ │ ├── form.html
│ │ │ └── list.html
│ │ ├── login.html
│ │ └── index.html
│ ├── schema.sql
│ ├── data.sql
│ └── application.properties
└── test
.gitignore
build.gradle
gradlew.bat
HELP.md
settings.gradle
UserRepository
まずは、ユーザー情報を一覧で表示するために、ユーザー情報をSELECT文で取得します。UserRepository
package com.example.practice.domain.authentication;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Optional;
@Mapper
public interface UserRepository {
@Select("select * from users where username = #{username}")
Optional<User> findByUsername(String username);
@Select("select * from users")
List<User> findAll();
}
UserService
次に、ビジネスロジックの部分であるUserServiceを記載していきます。UserService
package com.example.practice.domain.authentication;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class UserService {
// UserRepositoryのインスタンスを注入
private final UserRepository userRepository;
// ユーザー一覧を取得するメソッド
public List<User> findAll() {
// userRepositoryを使ってデータベースからユーザー一覧を取得し、返す
return userRepository.findAll();
}
}
VIEWの作成
次に、ユーザー一覧を表示するためのVIEWを作成していきます。 以下がその実装になります。list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>トップページ | 業務用アプリケーション</title>
<!-- Bootstrap CSS link -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<!-- ヘッダー部分 -->
<header class="mb-4 bg-light p-3 rounded">
<div class="d-flex justify-content-between align-items-center">
<h1 class="mb-0"><a href="../index.html" th:href="@{/}" class="text-dark text-decoration-none">業務管理アプリケーション</a></h1>
<a href="#" th:href="@{/logout}" th:attr="data-method='post'" class="btn btn-dark" style="font-size: 18px;">ログアウト</a>
</div>
</header>
<div class="d-flex justify-content-center align-items-center flex-column">
<h1 class="mt-3">ユーザー一覧</h1>
<table class="table table-striped">
<thead>
<tr>
<th>ユーザー名</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${userList}">
<td th:text="${user.username}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
UserController
最後に、Controllerの実装をしていきます。UserController
package com.example.practice.web.user;
import com.example.practice.domain.authentication.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Collections;
@Controller
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping
public String showList(Model model) {
model.addAttribute("userList", userService.findAll());
return "users/list";
}
}
ユーザー作成
次に、ユーザー情報をデータベースに追加する処理を追加していきたいと思います。 こちらもMVCモデルに従って作成していきましょう。UserForm
ユーザー情報をフォームとして受け取るために、データベースの定義をしていきます。UserForm
package com.example.practice.web.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@AllArgsConstructor
public class UserForm {
@NotBlank
private String username;
@NotBlank
private String password;
}
UserRepository
ユーザー情報を追加するINSERT文の処理を追加していきます。
UserRepository
package com.example.practice.domain.authentication;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Optional;
@Mapper
public interface UserRepository {
// ユーザー名を指定してユーザー情報を取得するクエリ
@Select("select * from users where username = #{username}")
Optional<User> findByUsername(String username);
// ユーザー一覧を取得するクエリ
@Select("select * from users")
List<User> findAll();
// ユーザー情報を挿入するクエリ。#{param1} と #{param2} は引数の順番にバインドされるプレースホルダー
@Insert("insert into users (username, password) values (#{param1}, #{param2})")
void insert(String username, String password);
}
UserRepositoryでは、上記のコメントを含むように、データベースからユーザー情報を取得したり、新しいユーザー情報を挿入するクエリ処理を定義しています。
UserService
次にUserServiceに先ほど追加したINSERT文の処理を説明していきます。
UserService
package com.example.practice.domain.authentication;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class UserService {
// UserRepositoryのインスタンスを注入
private final UserRepository userRepository;
// ユーザー一覧を取得するメソッド
public List<User> findAll() {
// userRepositoryを使ってデータベースからユーザー一覧を取得し、返す
return userRepository.findAll();
}
// ユーザーを作成するメソッド
public void create(String username, String password) {
// ユーザー名とパスワードを引数としてuserRepositoryのinsertメソッドを呼び出し、新しいユーザー情報を挿入する
userRepository.insert(username, password);
}
}
VIEW
次に、VIEWの作成をしていきます。
以下がユーザー作成画面になります。
creationForm.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ユーザー作成 | 業務用アプリケーション</title>
<!-- Bootstrap CSS link -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<!-- ヘッダー部分 -->
<header class="mb-4 bg-light p-3 rounded">
<div class="d-flex justify-content-between align-items-center">
<h1 class="mb-0"><a href="../index.html" th:href="@{/}" class="text-dark text-decoration-none">業務管理アプリケーション</a></h1>
<a href="#" th:href="@{/logout}" th:attr="data-method='post'" class="btn btn-dark" style="font-size: 18px;">ログアウト</a>
</div>
</header>
<form action="#" th:action="@{/users}" method="post" th:object="${userForm}">
<div class="mt-3">
<label for="usernameInput" class="form-label">ユーザー名</label>
<input type="text" id="usernameInput" class="form-control" th:field="*{username}">
</div>
<div class="mt-3">
<label for="passwordInput" class="form-label">パスワード</label>
<input type="password" id="passwordInput" class="form-control" th:field="*{password}">
</div>
<div class="mt-3">
<button type="submit" class="btn btn-primary">作成</button>
<a href="./list.html" th:href="@{/users}" class="btn btn-secondary">取消</a>
</div>
</form>
</div>
</body>
</html>
ユーザー一覧画面に遷移リンクを追加します。
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>トップページ | 業務用アプリケーション</title>
<!-- Bootstrap CSS link -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<!-- ヘッダー部分 -->
<header class="mb-4 bg-light p-3 rounded">
<div class="d-flex justify-content-between align-items-center">
<h1 class="mb-0"><a href="../index.html" th:href="@{/}" class="text-dark text-decoration-none">業務管理アプリケーション</a></h1>
<a href="#" th:href="@{/logout}" th:attr="data-method='post'" class="btn btn-dark" style="font-size: 18px;">ログアウト</a>
</div>
</header>
<!-- ヘッダー部分の最後 -->
<h2 class="text-center">ユーザー一覧</h2>
<a href="../index.html" th:href="@{/}" class="btn btn-primary">トップページ</a>
<a href="../creationForm.html" th:href="@{/users/creationForm}"class="btn btn-success">作成</a>
<table class="table table-striped">
<thead>
<tr>
<th>ユーザー名</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${userList}">
<td th:text="${user.username}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
UserController
最後にControllerの設定をしていきます。
UserController
package com.example.practice.web.user;
import com.example.practice.domain.authentication.UserService;
import com.example.practice.web.order.OrderForm;
import lombok.RequiredArgsConstructor;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Collections;
@Controller
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
// UserServiceのインスタンスを注入
private final UserService userService;
// ユーザーリストを表示するGETリクエスト
@GetMapping
public String showList(Model model) {
// UserServiceを使って全てのユーザー情報を取得し、"userList"という名前でモデルに追加
model.addAttribute("userList", userService.findAll());
return "users/list"; // "users/list" テンプレートを返す
}
// ユーザー作成フォームを表示するGETリクエスト
@GetMapping("/creationForm")
public String showCreationForm(@ModelAttribute UserForm form) {
return "users/creationForm"; // "users/creationForm" テンプレートを返す
}
// ユーザーを作成するPOSTリクエスト
@PostMapping
public String create(@Validated UserForm form, BindingResult bindingResult) {
// 入力の検証エラーがある場合
if (bindingResult.hasErrors()) {
// ユーザー作成フォームを再表示
return showCreationForm(form);
}
// UserServiceを使って新しいユーザー情報を作成
userService.create(form.getUsername(), form.getPassword());
// ユーザーリストを表示するページにリダイレクト
return "redirect:/users";
}
}