ホーム画面からユーザー一覧画面に遷移し、ユーザーの詳細を表示するアプリケーションを作成して、Spring JDBCの使い方について学びます⭐️
前回はユーザー一覧画面を作ったので、今回はユーザー詳細画面を作ります^^
構成は前回の記事を参考にしてください
⭐️前回の記事
【Java・SpringBoot】Spring JDBC でユーザー一覧画面(SpringBootアプリケーション実践編11)
#リポジトリークラスに1件検索するメソッドを実装
###queryForMapメソッドで1件取得
- 戻り値はMap型
- 第1引数:SQL文、第2引数以降にPreparedStatementを指定
Map<String, Object> map = jdbc.queryForMap("SELECT * FROM m_user" + " WHERE user_id = ?", userId);
- 戻り値のMapのgetメソッドにカラム名を指定することで、値を取得する
UserDaoJdbcImpl.java
package com.example.demo.login.domain.repository.jdbc;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;
@Repository("UserDaoJdbcImpl")
public class UserDaoJdbcImpl implements UserDao {
@Autowired
JdbcTemplate jdbc;
// Userテーブルの件数を取得.
@Override
public int count() throws DataAccessException {
//全件取得してカウント
int count = jdbc.queryForObject("SELECT COUNT(*) FROM m_user", Integer.class);
return count;
}
// Userテーブルにデータを1件insert.
@Override
public int insertOne(User user) throws DataAccessException {
//1件登録
int rowNumber = jdbc.update("INSERT INTO m_user(user_id,"
+ " password,"
+ " user_name,"
+ " birthday,"
+ " age,"
+ " marriage,"
+ " role)"
+ " VALUES(?, ?, ?, ?, ?, ?, ?)",
user.getUserId(),
user.getPassword(),
user.getUserName(),
user.getBirthday(),
user.getAge(),
user.isMarriage(),
user.getRole());
return rowNumber;
}
// Userテーブルのデータを1件取得
@Override
public User selectOne(String userId) throws DataAccessException {
// 1件取得
Map<String, Object> map = jdbc.queryForMap("SELECT * FROM m_user"
+ " WHERE user_id = ?", userId);
// 結果返却用の変数
User user = new User();
// 取得したデータを結果返却用の変数にセットしていく
user.setUserId((String) map.get("user_id")); //ユーザーID
user.setPassword((String) map.get("password")); //パスワード
user.setUserName((String) map.get("user_name")); //ユーザー名
user.setBirthday((Date) map.get("birthday")); //誕生日
user.setAge((Integer) map.get("age")); //年齢
user.setMarriage((Boolean) map.get("marriage")); //結婚ステータス
user.setRole((String) map.get("role")); //ロール
return user;
}
// Userテーブルの全データを取得.
@Override
public List<User> selectMany() throws DataAccessException {
// M_USERテーブルのデータを全件取得
List<Map<String, Object>> getList = jdbc.queryForList("SELECT * FROM m_user");
// 結果返却用の変数
List<User> userList = new ArrayList<>();
// 取得したデータを結果返却用のListに格納していく
for (Map<String, Object> map : getList) {
//Userインスタンスの生成
User user = new User();
// Userインスタンスに取得したデータをセットする
user.setUserId((String) map.get("user_id")); //ユーザーID
user.setPassword((String) map.get("password")); //パスワード
user.setUserName((String) map.get("user_name")); //ユーザー名
user.setBirthday((Date) map.get("birthday")); //誕生日
user.setAge((Integer) map.get("age")); //年齢
user.setMarriage((Boolean) map.get("marriage")); //結婚ステータス
user.setRole((String) map.get("role")); //ロール
//結果返却用のListに追加
userList.add(user);
}
return userList;
}
// Userテーブルを1件更新.
@Override
public int updateOne(User user) throws DataAccessException {
return 0;
}
// Userテーブルを1件削除.
@Override
public int deleteOne(String userId) throws DataAccessException {
return 0;
}
//SQL取得結果をサーバーにCSVで保存する
@Override
public void userCsvOut() throws DataAccessException {
}
}
#サービスクラスに1件取得用のメソッド追加
UserService.java
package com.example.demo.login.domain.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;
@Service
public class UserService {
@Autowired
UserDao dao;
public boolean insert(User user) {
// insert実行
int rowNumber = dao.insertOne(user);
// 判定用変数
boolean result = false;
if (rowNumber > 0) {
// insert成功
result = true;
}
return result;
}
public int count() {
return dao.count();
}
public List<User> selectMany() {
// 全件取得
return dao.selectMany();
}
/**
* 1件取得用メソッド.
*/
public User selectOne(String userId) {
// selectOne実行
return dao.selectOne(userId);
}
}
#ホーム画面用のコントローラークラスを修正
###動的なURLに対応したメソッドを作る
-
@GetMappingや@PostMappingの値に**
/{<変数名>}
を付ける**- ユーザーIDを受け取る場合は、
@GetMapping(/userDetail/{id})
- 通常は
/userDetail/{id}
とすればいいが。。。 -
ユーザーIDがメールアドレス形式の場合、
sample@xxx.co.jp
というユーザーIDが渡されてくると、sample@xxx.co
しか受け取れない- →正規表現を使用して**
@GetMapping("/userDetail/{id:.+}")
**とする
- →正規表現を使用して**
- ユーザーIDを受け取る場合は、
-
@PathVariableアノテーションを付けると、渡されてきたパス(URL)の値を引数の変数に入れることができる
- 例:
@PathVariable("id") String userId) {...}
-
http://localhost:8080/userDetail/sample@xxx.co.jp
というURLでリクエストが来た場合、sample@xxx.co.jp
という値が引数のuserIdという変数に入れられる
- 例:
HomeController.java
package com.example.demo.login.controller;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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 com.example.demo.login.domain.model.SignupForm;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.service.UserService;
@Controller
public class HomeController {
@Autowired
UserService userService;
//結婚ステータスのラジオボタン用変数
private Map<String, String> radioMarriage;
/**
* ラジオボタンの初期化メソッド
*/
private Map<String, String> initRadioMarrige() {
Map<String, String> radio = new LinkedHashMap<>();
// 既婚、未婚をMapに格納
radio.put("既婚", "true");
radio.put("未婚", "false");
return radio;
}
@GetMapping("/home")
public String getHome(Model model) {
//コンテンツ部分にユーザー詳細を表示するための文字列を登録
model.addAttribute("contents", "login/home :: home_contents");
return "login/homeLayout";
}
@GetMapping("/userList")
public String getUserList(Model model) {
//コンテンツ部分にユーザー一覧を表示するための文字列を登録
model.addAttribute("contents", "login/userList :: userList_contents");
//ユーザー一覧の生成
List<User> userList = userService.selectMany();
//Modelにユーザーリストを登録
model.addAttribute("userList", userList);
//データ件数を取得
int count = userService.count();
model.addAttribute("userListCount", count);
return "login/homeLayout";
}
/**
* ユーザー詳細画面のGETメソッド用処理.
*/
@GetMapping("/userDetail/{id:.+}")
public String getUserDetail(@ModelAttribute SignupForm form,
Model model,
@PathVariable("id") String userId) {
// ユーザーID確認
System.out.println("userId = " + userId);
// コンテンツ部分にユーザー詳細を表示するための文字列を登録
model.addAttribute("contents", "login/userDetail :: userDetail_contents");
// 結婚ステータス用ラジオボタンの初期化
radioMarriage = initRadioMarrige();
// ラジオボタン用のMapをModelに登録
model.addAttribute("radioMarriage", radioMarriage);
// ユーザーIDのチェック
if (userId != null && userId.length() > 0) {
// ユーザー情報を取得
User user = userService.selectOne(userId);
// Userクラスをフォームクラスに変換
form.setUserId(user.getUserId()); //ユーザーID
form.setUserName(user.getUserName()); //ユーザー名
form.setBirthday(user.getBirthday()); //誕生日
form.setAge(user.getAge()); //年齢
form.setMarriage(user.isMarriage()); //結婚ステータス
// Modelに登録
model.addAttribute("signupForm", form);
}
return "login/homeLayout";
}
@PostMapping("/logout")
public String postLogout() {
return "redirect:/login";
}
@GetMapping("/userList/csv")
public String getUserListCsv(Model model) {
return getUserList(model);
}
}
#ユーザー詳細画面作成
userDetail.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"></meta>
</head>
<body>
<div th:fragment="userDetail_contents">
<div class="row">
<div class="col-sm-5">
<div class="page-header">
<h1>ユーザー詳細</h1>
</div>
<form method="post" th:action="@{/userDetail}" th:object="${signupForm}">
<table class="table table-bordered table-hover">
<tr>
<!-- ユーザーID(入力不可) -->
<th class="active col-sm-2">ユーザID</th>
<td class="col-sm-3">
<div class="form-group">
<input type="text" class="form-control"
th:field="*{userId}"
readonly="readonly" />
</div>
</td>
</tr>
<tr>
<!-- パスワード -->
<th class="active">パスワード</th>
<td>
<div class="form-group"
th:classappend="${#fields.hasErrors('password')} ? 'has-error'">
<input type="text" class="form-control"
th:field="*{password}" />
<span class="text-danger"
th:if="${#fields.hasErrors('password')}"
th:errors="*{password}">
password error
</span>
</div>
</td>
</tr>
<tr>
<!-- ユーザー名 -->
<th class="active">ユーザ名</th>
<td>
<div class="form-group"
th:classappend="${#fields.hasErrors('userName')} ? 'has-error'">
<input type="text" class="form-control"
th:field="*{userName}" />
<span class="text-danger"
th:if="${#fields.hasErrors('userName')}"
th:errors="*{userName}">
userName error
</span>
</div>
</td>
</tr>
<tr>
<!-- 誕生日 -->
<th class="active">誕生日</th>
<td>
<div class="form-group"
th:classappend="${#fields.hasErrors('birthday')} ? 'has-error'">
<input type="text" class="form-control"
placeholder="yyyy/MM/dd"
th:field="*{birthday}" />
<span class="text-danger"
th:if="${#fields.hasErrors('birthday')}"
th:errors="*{birthday}">
birthday error
</span>
</div>
</td>
</tr>
<tr>
<!-- 年齢 -->
<th class="active">年齢</th>
<td>
<div class="form-group"
th:classappend="${#fields.hasErrors('age')} ? 'has-error'">
<input type="text" class="form-control"
th:field="*{age}" />
<span class="text-danger"
th:if="${#fields.hasErrors('age')}"
th:errors="*{age}">
age error
</span>
</div>
</td>
</tr>
<tr>
<!-- 結婚 -->
<th class="active">結婚</th>
<td>
<div class="form-group">
<div th:each="item : ${radioMarriage}">
<input type="radio" name="radioMarrige"
th:value="${item.value}"
th:text="${item.key}"
th:field="*{marriage}">
</input>
</div>
<span class="text-danger"
th:if="${#fields.hasErrors('marriage')}"
th:errors="*{marriage}">
marriage error
</span>
</div>
</td>
</tr>
</table>
<!-- 更新ボタン -->
<button class="btn btn-primary btn-lg pull-right"
type="submit"
name="update">
更新
</button>
<!-- 削除ボタン -->
<button class="btn btn-danger btn-lg" type="submit" name="delete">
削除
</button>
</form>
</div>
</div>
</div>
</body>
</html>
#SpringBootを起動してユーザ一覧画面確認!
- http://localhost:8080/userList
- ユーザ一覧から、ユーザ詳細画面に遷移します
- パスワード以外の情報が反映されました〜^^