目次
はじめに
Javaのフレームワーク「Spring Boot」とテンプレートエンジン「Thymeleaf」を使用して、一覧画面を作成する手順を紹介します。
本記事で作成する「一覧画面」のイメージとテーブル定義は以下の通り。
[画面イメージ]
※「新規登録はこちら」ボタンと「詳細」ボタンを押下するとダミーの画面に遷移するようになっています。
[テーブル定義]
物理名 | 論理名 | データ型 | NOT NULL | 説明 |
id | ID | BIGINT | 〇 | 主キー(AUTO_INCREMENT) |
name | 名前 | VARCHAR(100) | 〇 | ユーザーの名前 |
address | 住所 | VARCHAR(255) | ユーザーの住所 | |
phone | 電話番号 | VARCHAR(50) | ユーザーの電話番号 | |
update_date | 更新日時 | DATETIME | 〇 | 最終更新日時 |
create_date | 作成日時 | DATETIME | 〇 | 登録日時 |
delete_date | 削除日時 | DATETIME | 論理削除した日時 |
■CREATE文
CREATE TABLE `sampledb`.`user` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `address` VARCHAR(255) NULL, `phone` VARCHAR(50) NULL, `update_date` DATETIME NOT NULL, `create_date` DATETIME NOT NULL, `delete_date` DATETIME NULL, PRIMARY KEY (`id`));
■INSERT文
INSERT INTO `sampledb`.`user` (`id`, `name`, `address`, `phone`, `update_date`, `create_date`) VALUES ('1', 'テスト太郎', '東京都品川区1-1', '090-0000-0000', '2021/06/30', '2021/06/30'); INSERT INTO `sampledb`.`user` (`id`, `name`, `address`, `phone`, `update_date`, `create_date`) VALUES ('2', 'テスト次郎', '東京都渋谷区1-1', '080-0000-0000', '2021/06/30', '2021/06/30');
スポンサーリンク
開発環境
開発環境は以下の通り。
開発環境 | 名称 | 説明 |
開発言語 | Java | 人気の開発言語 |
開発ツール | Eclipse | Javaでの定番開発ツール |
フレームワーク | Spring Boot | 人気のSpringフレームワークをベースとしたフレームワーク |
テンプレートエンジン | Thymeleaf | Spring Bootと相性が良いテンプレートエンジン |
データベース | MySQL | フリーで利用できる人気データベース |
その他 データベースへの接続は「Spring Data JPA」、画面のデザインには「Bootstrap」を使用しています。
ディレクトリ構成
ディレクトリ構成は次の通り。
springSample | |___src.main.java | |___com.example.demo | | | |___controller | | | | | |__UserController.java | | | |___entity | | | | | |___User.java | | | |___repository | | | | | |___UserRepository.java | | | |___service | | | |___UserService.java | |___src.main.resources | |___templates | | | |___common | | | | | |___head.html | | | |___user | | | |___add.html | | | |___list.html | | | |___view.html | |___application.properties
バックエンド(サーバー)側のソースコード
スポンサーリンク
コントローラークラス(UserController.java)
コントローラクラスの内容は以下の通り。
package com.example.demo.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.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import com.example.demo.entity.User; import com.example.demo.service.UserService; /** * ユーザー情報 Controller */ @Controller public class UserController { /** * ユーザー情報 Service */ @Autowired private UserService userService; /** * ユーザー情報一覧画面を表示 * @param model Model * @return ユーザー情報一覧画面 */ @GetMapping(value = "/user/list") public String displayList(Model model) { List<User> userlist = userService.searchAll(); model.addAttribute("userlist", userlist); return "user/list"; } /** * ユーザー新規登録画面を表示 * @param model Model * @return ユーザー情報一覧画面 */ @GetMapping(value = "/user/add") public String displayAdd(Model model) { return "user/add"; } /** * ユーザー情報詳細画面を表示 * @param id 表示するユーザーID * @param model Model * @return ユーザー情報詳細画面 */ @GetMapping("/user/{id}") public String displayView(@PathVariable Long id, Model model) { return "user/view"; } }
サービスクラス(UserService.java)
サービスクラスの内容は以下の通り。データベースとの接続は「Spring Data JPA」を使用しています。
package com.example.demo.service; import java.util.List; import org.springframework.transaction.annotation.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; /** * ユーザー情報 Service */ @Service public class UserService { /** * ユーザー情報 Repository */ @Autowired private UserRepository userRepository; /** * ユーザー情報 全検索 * @return 検索結果 */ public List<User> searchAll() { return userRepository.findAll(); } }
エンティティクラス(User.java)
データベースから取得したデータを格納するエンティティクラスの内容は以下の通り。@Dataアノテーションを使用して、getter、setterの定義を省略しています。
package com.example.demo.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; /** * ユーザー情報 Entity */ @Entity @Data @Table(name = "user") public class User implements Serializable { /** * ID */ @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * 名前 */ @Column(name = "name") private String name; /** * 住所 */ @Column(name = "address") private String address; /** * 電話番号 */ @Column(name = "phone") private String phone; /** * 更新日時 */ @Column(name = "update_date") private Date updateDate; /** * 登録日時 */ @Column(name = "create_date") private Date createDate; /** * 削除日時 */ @Column(name = "delete_date") private Date deleteDate; }
リポジトリクラス(UserRepository.java)
データベースにアクセスするためのリポジトリクラスは以下の通り。
package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.example.demo.entity.User; /** * ユーザー情報 Repository */ @Repository public interface UserRepository extends JpaRepository<User, Long> {}
フロントエンド(クライアント)側のソースコード
スポンサーリンク
共通ヘッダ(head.html)
共通のヘッダは次の通り。ヘッダ情報は同じなので共通で管理しています。
画面ごとに変わる「title」だけ動的に変えられるようにしています。また、画面デザインにはBootstrapを使っているので、Bootstrapのcssとjsを読み込んでいます。
<head th:fragment="head_fragment(title, scripts, links)"> <title th:text="${title}"></title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <meta charset="utf-8" /> </head>
ユーザー情報一覧画面(list.html)
ユーザー情報一覧画面のHTMLは以下の通り。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head th:replace="common/head :: head_fragment(title = 'ユーザー情報一覧', scripts = ~{::script}, links = ~{::link})"></head> <body> <div class="container"> <h1>ユーザー情報一覧</h1> <div class="float-end"> <a th:href="@{/user/add}" class="btn btn-primary">新規登録はこちら</a> </div> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>名前</th> <th>住所</th> <th>電話番号</th> <th>更新日時</th> <th>登録日時</th> <th>削除日時</th> <th></th> </tr> </thead> <tbody> <tr th:each="user : ${userlist}" th:object="${user}" class="align-middle"> <td th:text="*{id}"></td> <td th:text="*{name}"></td> <td th:text="*{address}"></td> <td th:text="*{phone}"></td> <td th:text="${#dates.format(user.updateDate, 'yyyy/MM/dd')}"></td> <td th:text="${#dates.format(user.createDate, 'yyyy/MM/dd')}"></td> <td th:text="${#dates.format(user.deleteDate, 'yyyy/MM/dd')}"></td> <td><a th:href="@{/user/{id}(id=*{id})}" class="btn btn-secondary">詳細</a></td> </tr> </tbody> </table> </div> </body> </html>
新規登録画面(add.html)
新規登録画面のHTMLは以下の通り。
画面遷移を確認するためのダミーHTMLです。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head th:replace="common/head :: head_fragment(title = 'ユーザー新規登録', scripts = ~{::script}, links = ~{::link})"></head> <body> <div class="container"> <h1>新規登録画面ダミー</h1> <a href="/user/list">一覧に戻る</a> </div> </body> </html>
ユーザー情報詳細画面(view.html)
ユーザー情報詳細画面のHTMLは以下の通り。
画面遷移を確認するためのダミーHTMLです。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head th:replace="common/head :: head_fragment(title = 'ユーザー情報詳細', scripts = ~{::script}, links = ~{::link})"></head> <body> <div class="container"> <h1>ユーザー情報詳細画面ダミー</h1> <a href="/user/list">一覧に戻る</a> </div> </body> </html>
動作確認
Spring Bootプロジェクトを実行して http://localhost:8080/user/list へアクセスします。
一覧画面が表示され、デーベースから取得した値が一覧に表示されていれば完了です。
「新規登録はこちら」ボタン押下 → Spring Boot + Thymeleafで新規登録画面を作成する
「詳細」ボタン押下 → Spring Boot + Thymeleafで詳細画面を作成する