目次
はじめに
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で詳細画面を作成する