-Continued from Last time --Create a simple CRUD app with Spring Boot ――This time, create the following 4 screens and go through the processing --List screen --New screen
--If you are using SpringBoot and JPA, creating an Entity class will automatically generate a table, so you don't have to hit SQL.
--Create Player.java
to save player information in src / main / java / com / example / baseball / domain
src/main/java/com/example/baseball/domain/Player.java
package com.example.baseball.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity // ①
public class Player {
@Id // ②
@GeneratedValue(strategy = GenerationType.IDENTITY) // ③
private Long id;
private String name;
private Integer age;
private String team;
private String position;
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;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getTeam() {
return team;
}
public void setTeam(String team) {
this.team = team;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
@Override
public String toString() {
return "Player [id=" + id + ", name=" + name + ", age=" + age + ", team=" + team + ", position=" + position + "]";
}
}
-①: Link with DB table by adding @ Entity
--②: The variable with @Id
becomes the primer key of the table.
--③: If you add @GeneratedValue
, serial numbers will be assigned automatically.
--JPA provides the basic processing for accessing the table, so you don't have to write SQL.
--Can be used by creating an interface that inherits JPA's JpaRepository
--If you want to do something other than the typical operations such as findAll and save, you will need to add it to the repository.
--Create PlayerRepository.java
in src / main / java / com / example / baseball / repository
src/main/java/com/example/baseball/repository/PlayerRepository.java
package com.example.baseball.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.baseball.domain.Player;
@Repository
public interface PlayerRepository extends JpaRepository<Player, Long> {
}
--Create a service that calls the repository process
--The business logic is written in service, and the repository is only DB access.
--Call the service method when you want to perform processing that accesses the DB
--Since there is no business logic at this stage, write only the process to call the repository method.
--Create PlayerService.java
in src / main / java / com / example / baseball / service
src/main/java/com/example/baseball/service/PlayerService.java
package com.example.baseball.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.baseball.domain.Player;
import com.example.baseball.repository.PlayerRepository;
@Service
public class PlayerService {
// ①
@Autowired
private PlayerRepository playerRepository;
public List<Player> findAll() {
return playerRepository.findAll();
}
public Player findOne(Long id) {
return playerRepository.findOne(id);
}
public Player save(Player player) {
return playerRepository.save(player);
}
public void delete(Long id) {
playerRepository.delete(id);
}
}
--①: If you declare it with @Autowired
, it will inject the bean, so you can use it without new
.
--Create a method associated with the URL accessed by the user --The following 6 types of endpoints are created
HTTP method | URL | Controller method | Overview |
---|---|---|---|
GET | /players | index() | Display of list screen |
POST | /players | create() | Data storage |
GET | /players/new | newPlayer() | Display of new creation screen |
GET | /players/1/edit | edit() | Display of edit screen |
GET | /players/1 | show() | Display of reference screen |
PUT | /players/1 | update() | Data update |
DELETE | /players/1 | destroy() | Delete data |
--Create PlayerController.java
in src / main / java / com / example / baseball / controller
src/main/java/com/example/baseball/controller/PlayerController.java
package com.example.baseball.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.DeleteMapping;
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 org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.baseball.domain.Player;
import com.example.baseball.service.PlayerService;
@Controller
@RequestMapping("/players") // ①
public class PlayerController {
@Autowired
private PlayerService playerService;
@GetMapping
public String index(Model model) { // ②
List<Player> players = playerService.findAll();
model.addAttribute("players", players); // ③
return "players/index"; // ④
}
@GetMapping("new")
public String newPlayer(Model model) {
return "players/new";
}
@GetMapping("{id}/edit")
public String edit(@PathVariable Long id, Model model) { // ⑤
Player player = playerService.findOne(id);
model.addAttribute("player", player);
return "players/edit";
}
@GetMapping("{id}")
public String show(@PathVariable Long id, Model model) {
Player player = playerService.findOne(id);
model.addAttribute("player", player);
return "players/show";
}
@PostMapping
public String create(@ModelAttribute Player player) { // ⑥
playerService.save(player);
return "redirect:/players"; // ⑦
}
@PutMapping("{id}")
public String update(@PathVariable Long id, @ModelAttribute Player player) {
player.setId(id);
playerService.save(player);
return "redirect:/players";
}
@DeleteMapping("{id}")
public String destroy(@PathVariable Long id) {
playerService.delete(id);
return "redirect:/players";
}
}
--①: If you add @RequestMapping
to the class, it will be applied to all the methods in the class.
--That is, all the methods of this class are mapped to URLs starting with http: // localhost: 8080 / players
--②: If you set a value of type Model
in the argument of the method, an instance of Model will be passed automatically.
--③: You can pass the value to the template by filling the model received in ② with the value.
--Here, the list of players is set with the key name players
.
--④: Based on the returning character string, find the file under src / main / resources / templates /
and return it to the user.
--Here, src / main / resources / templates / players / index.html
is returned.
-⑤: You can get the value on the URL by setting @PathVariable
in the method argument.
--Here, when http: // localhost / players / 1
is accessed, 1 is entered in ʻid. --⑥: If you add
@ModelAttributeto the method argument, you can get the body information of the sent request. --⑦: "redirect: / players" redirects to
/ players --It feels like the
http: // localhost: 8080 / players` is accessed without permission after the process of the create method is finished.
--Since this time we will create a template for player, we will create it under src / main / resources / templates / players
--Create the following 4 screen files
--index.html (list screen)
--new.html (new creation screen)
--edit.html (edit screen)
--show.html (reference screen)
--Prepare css and javascript files before creating a template
--This time, use Bootstrap
--The latest version is 4 series, but this time we will use 3 series
-Download from here and place the following files
--Copy bootstrap.css
in the css folder to the src / main / resources / static / css
folder
--Copy bootstrap.js
in the js folder to the src / main / resources / static / js
folder
--Download and deploy jQuery on which Bootstrap depends
--Download jQuery from here
--If the source comes out directly, right-click and save it as a name
--Place in the src / main / resources / static / js
folder with the name jquery.js
index.html
--Display a list of players in a table
--Create ʻindex.html in
src / main / resources / templates / players`
src/main/resources/templates/players/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>Listing Players - baseball</title>
<!-- ① -->
<link rel="stylesheet" href="/css/bootstrap.css" />
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<h1>Listing Players</h1>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>age</th>
<th>Team name</th>
<th>Defensive position</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<!-- ② -->
<tr th:each="player:${players}" th:object="${player}">
<!-- ③ -->
<td th:text="*{id}"></td>
<td th:text="*{name}"></td>
<td th:text="*{age}"></td>
<td th:text="*{team}"></td>
<td th:text="*{position}"></td>
<!-- ④ -->
<td><a class="btn btn-default btn-xs" th:href="@{/players/{id}(id=*{id})}">reference</a></td>
<td><a class="btn btn-default btn-xs" th:href="@{/players/{id}/edit(id=*{id})}">Edit</a></td>
<td>
<!-- ⑤ -->
<form th:action="@{/players/{id}(id=*{id})}" th:method="delete">
<input class="btn btn-default btn-xs" type="submit" value="Delete" />
</form>
</td>
</tr>
</tbody>
</table>
<a class="btn btn-default" href="/players/new">Create New</a>
</div>
</body>
</html>
--①: Read css and javascript files
--②: Loop processing is performed for the players
passed from the Controller.
--Loop processing can be described by doing something like th: each =" player: $ {players} "
--In this example, the loop is looped by the number of players who are List, and each element in List is treated with the variable name player.
--③: By setting th: object =" $ {player} "
, you can abbreviate $ {player.xxx}
as * {xxx}
in the child element from this tag. Become
--④: By setting th: href =" xxx "
, the value set in the href attribute can be made dynamic.
--The value where / players / {id}
is set in the href attribute. Variables can be embedded in the {id}
part, and the value is set by the subsequent (id = * {id})
.
--⑤: Since I want to access the delete process by setting the HTTP method to DELETE, I added th: method =" delete "
to the form tag.
new.html
--Player new creation screen
--Create new.html
in src / main / resources / templates / players
src/main/resources/templates/players/new.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>New Player - baseball</title>
<link rel="stylesheet" href="/css/bootstrap.css" />
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<h1>New Player</h1>
<form th:action="@{/players}" th:method="post">
<div class="form-group">
<label class="control-label">name</label>
<input class="form-control" type="text" name="name" />
</div>
<div class="form-group">
<label class="control-label">age</label>
<input class="form-control" type="number" name="age" />
</div>
<div class="form-group">
<label class="control-label">Team name</label>
<input class="form-control" type="text" name="team" />
</div>
<div class="form-group">
<label class="control-label">Defensive position</label>
<input class="form-control" type="text" name="position" />
</div>
<button class="btn btn-default" type="submit">Create</button>
</form>
<div class="pull-right">
<a class="btn btn-link" href="/players">To the list screen</a>
</div>
</div>
</body>
</html>
edit.html
--Screen to edit the player whose id matches the value contained in the URL
--Create ʻedit.html in
src / main / resources / templates / players`
src/main/resources/templates/players/edit.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>Editing Player - baseball</title>
<link rel="stylesheet" href="/css/bootstrap.css" />
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<h1>Editing Player</h1>
<form th:action="@{/players/{id}(id=*{id})}" th:method="put" th:object="${player}">
<div class="form-group">
<label class="control-label">name</label>
<!-- ① -->
<input class="form-control" type="text" th:field="*{name}" />
</div>
<div class="form-group">
<label class="control-label">age</label>
<input class="form-control" type="number" th:field="*{age}" />
</div>
<div class="form-group">
<label class="control-label">Team name</label>
<input class="form-control" type="text" th:field="*{team}" />
</div>
<div class="form-group">
<label class="control-label">Defensive position</label>
<input class="form-control" type="text" th:field="*{position}" />
</div>
<button class="btn btn-default" type="submit">update</button>
</form>
<div class="pull-right">
<a class="btn btn-link" href="/players">To the list screen</a>
</div>
</div>
</body>
</html>
--①: For the value set in th: field
, the variable name is set in the name attribute id attribute and the value is set in the value attribute.
--If the value of * {age}
is 20 as th: field =" * {age} "
, name =" age "id =" age "value =" 20 "
is automatically set. ing
show.html
--Screen to refer to player information whose id matches the value contained in the URL
--Create show.html
in src / main / resources / templates / players
src/main/resources/templates/players/show.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>Show Player - baseball</title>
<link rel="stylesheet" href="/css/bootstrap.css" />
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<h1>Show Player</h1>
<div th:object="${player}">
<div>
<label>ID</label>
<p th:text="*{id}"></p>
</div>
<div>
<label>name</label>
<p th:text="*{name}"></p>
</div>
<div>
<label>age</label>
<p th:text="*{age}"></p>
</div>
<div>
<label>Team name</label>
<p th:text="*{team}"></p>
</div>
<div>
<label>Defensive position</label>
<p th:text="*{position}"></p>
</div>
</div>
<div>
<a class="btn btn-default" th:href="@{/players/{id}/edit(id=*{id})}">Edit</a>
</div>
<div class="pull-right">
<a class="btn btn-link" href="/players">To the list screen</a>
</div>
</div>
</body>
</html>
--So far, when you access http: // localhost: 8080 / players, the following functions are available.
--Continued here
Recommended Posts