環境
| プロジェクト | Maven |
| データベース | MariaDB |
| データベース名 | java |
| テーブル名 | users |
# データベースの作成
CREATE DATABASE java;
# テーブルの作成
CREATE TABLE users (id INT AUTO_INCREMENT, name VARCHAR(255) NOT NULL PRIMARY KEY (id)); - myapp
- src/main/java
- com.example
- MyappApplication.java
- com.example.controller
- UserController.java
- com.example.entity
- User.java
- com.example.exception
- UserNotFoundException.java
- com.example.repository
- UserRepository.java
- com.example
- src/main/resources
- static
- templates
- error
- 404.html
- users
- create.html
- edit.html
- index.html
- show.html
- error
- application.properties
- ~ 中略 ~
- pom.xml
- src/main/java
ファイル
UserController.java
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.example.entity.User;
import com.example.repository.UserRepository;
import com.example.exception.UserNotFoundException;
@Controller
@RequestMapping("/users")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping
public String indexUser(Model model) {
model.addAttribute("users", userRepository.findAll());
return "users/index"; // templates/users.html を表示
}
// ユーザー詳細ページ
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
User user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
model.addAttribute("user", user);
return "users/show";
}
@GetMapping("/new")
public String newUserForm(Model model) {
model.addAttribute("user", new User());
return "users/create"; // templates/user_form.html を表示
}
// フォームからのPOST
@PostMapping
public String createUser(@ModelAttribute User user) {
userRepository.save(user);
return "redirect:/users"; // 一覧ページにリダイレクト
}
// ユーザー編集フォーム
@GetMapping("/{id}/edit")
public String editUserForm(@PathVariable Long id, Model model) {
try {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
model.addAttribute("user", user);
return "users/edit";
} catch (UserNotFoundException ex) {
System.err.println(ex.getMessage()); // "User not found with id: 10" が出力される
ex.printStackTrace(); // スタックトレース付きで出力
return "error/404";
}
}
// 編集内容の保存
@PostMapping("/{id}")
public String updateUser(@PathVariable Long id, @ModelAttribute User user) {
user.setId(id); // idをセットしないと新規作成になってしまう
userRepository.save(user);
return "redirect:/users";
}
// ユーザー削除
@PostMapping("/{id}/delete")
public String deleteUser(@PathVariable Long id) {
userRepository.deleteById(id);
return "redirect:/users"; // 削除後は一覧ページへ
}
} User.java
package com.example.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
} UserNotFoundException.java
package com.example.exception;
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(Long id) {
super("User not found with id: " + id);
}
} UserRepository.java
package com.example.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.entity.User;
public interface UserRepository extends JpaRepository<User, Long> {
} HTML ファイル
404.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<h1>404</h1>
</body>
</html> create.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Create User</title>
</head>
<body>
<h1>Create User</h1>
<form th:action="@{/users}" method="post">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" th:value="${user.name}" required>
</div>
<div>
<button type="submit">Save</button>
</div>
</form>
<a th:href="@{/users}">Back to list</a>
</body>
</html> edit.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>User Form</title>
</head>
<body>
<h1>Edit User</h1>
<form th:action="@{'/users/' + ${user.id}}" method="post">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" th:value="${user.name}" required>
</div>
<div>
<button type="submit">Save</button>
</div>
</form>
<a th:href="@{/users}">Back to list</a>
</body>
</html> index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<h1>User Index</h1>
<table>
<tr>
<th>ID</th><th>Name</th><th>Actions</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td><a th:href="@{'/users/' + ${user.id}}" th:text="${user.name}"></a></td>
<td>
<a th:href="@{'/users/' + ${user.id} + '/edit'}">Edit</a>
<form th:action="@{'/users/' + ${user.id} + '/delete'}" method="post" style="display:inline;">
<button type="submit" onclick="return confirm('Are you sure you want to delete this user?');">Delete</button>
</form>
</td>
</tr>
</table>
<p><a th:href="@{/users/new}">New User</a></p>
</body>
</html> show.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>User Detail</title>
</head>
<body>
<h1>User Detail</h1>
<p><strong>ID:</strong> <span th:text="${user.id}"></span></p>
<p><strong>Name:</strong> <span th:text="${user.name}"></span></p>
<a th:href="@{/users}">Back to list</a>
<a th:href="@{'/users/' + ${user.id} + '/edit'}">Edit</a>
</body>
</html> その他ファイル
application.properties
spring.application.name=myapp
spring.datasource.url=jdbc:mariadb://localhost:3306/java?useUnicode=true&characterEncoding=utf8mb4
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.thymeleaf.cache=false
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.entity pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>myapp</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>