Spring Boot

Spring Boot + Thymeleafで一覧画面を作成する

はじめに

Javaのフレームワーク「Spring Boot」とテンプレートエンジン「Thymeleaf」を使用して、一覧画面を作成する手順を紹介します。

本記事で作成する「一覧画面」のイメージとテーブル定義は以下の通り。

一覧画面のイメージ

※「新規登録はこちら」ボタンと「詳細」ボタンを押下するとダミーの画面に遷移するようになっています。

[テーブル定義]

物理名論理名データ型NOT NULL説明
idIDBIGINT主キー(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人気の開発言語
開発ツールEclipseJavaでの定番開発ツール
フレームワークSpring Boot人気のSpringフレームワークをベースとしたフレームワーク
テンプレートエンジンThymeleafSpring 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で詳細画面を作成する

helpful