Je n'ai utilisé que JdbcTemplate et n'ai jamais utilisé MyBatis, j'ai donc essayé d'utiliser SpringBoot + MyBatis + MySQL.
Cette fois, les informations du livre sont enregistrées dans la base de données, et nous en obtiendrons une et les afficherons toutes.
■ Écran lors du premier accès
■ 1 recherche (entrez l'identifiant dans le formulaire et appuyez sur rechercher)
■ Afficher tous les éléments (appuyez sur l'affichage de la liste)
Pour une raison quelconque, BookDao peut être utilisé à partir de la classe BookService sans implémenter d'interface. Il semble qu'il est implémenté dans les coulisses et peut être utilisé à partir de la classe Service.
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ ├── ServletInitializer.java
│ │ ├── SpringTestApplication.java
│ │ ├── controller
│ │ │ └── BookController.java
│ │ ├── dao
│ │ │ └── BookDao.java
│ │ ├── entity
│ │ │ └── Book.java
│ │ ├── form
│ │ │ └── BookForm.java
│ │ └── service
│ │ └── BookService.java
│ └── resources
│ ├── application.properties
│ ├── com
│ │ └── example
│ │ └── demo
│ │ └── dao
│ │ └── BookDao.xml
│ ├── data.sql
│ ├── schema.sql
│ ├── static
│ │ └── css
│ │ └── style.css
│ └── templates
│ └── index.html
└── test
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
Tout d'abord, créez une base de données avec MySQL. Dans cet exemple, library.
CREATE DATABASE library;
Si vous préparez le fichier suivant, les données de test seront préparées à chaque démarrage de Spring Boot.
schema.sql
--Supprimer s'il y a une table de lecture
DROP TABLE IF EXISTS booktable;
--S'il n'y a pas de table de lecture, créez-en une nouvelle
CREATE TABLE IF NOT EXISTS booktable(
id INT AUTO_INCREMENT,
book_name VARCHAR(50) NOT NULL,
volume_num INT NOT NULL,
author_name VARCHAR(50) NOT NULL,
published_date DATE NOT NULL,
PRIMARY KEY(id)
);
data.sql
--Liste des livres Données initiales
--La colonne id est auto-incrémentée, donc inutile
INSERT INTO booktable
(book_name, volume_num,author_name,published_date)
VALUES
( 'HUNTER X HUNTER',36,'Yoshihiro Togashi','2018-10-04'),
( 'Fou furieux',40,'Kentaro Miura','2018-09-28'),
( 'Drifters',6,'Kota Hirano','2018-11-30'),
( 'Rashomon',1,'Ryunosuke Akutagawa','1915-11-01')
;
Cela ne fonctionnera que si vous ajoutez ? ServerTimezone = JST
à la destination de la connexion. De plus, avec mybatis.configuration.map-underscore-to-camel-case = true
, même si le nom de la colonne DB est un cas de serpent, il sera reconnu comme un cas de chameau du côté Java.
###Paramètres de connexion à la base de données
spring.datasource.url=jdbc:mysql://localhost:3306/library?serverTimezone=JST
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
###Le nom de la colonne DB du cas de serpent est associé en tant que cas de chameau du côté Entité de Spring.
mybatis.configuration.map-underscore-to-camel-case=true
###Spécifiez s'il faut effectuer l'initialisation.
spring.datasource.initialization-mode=always
Cette fois, seul l'identifiant est reçu de l'écran, il n'y a donc qu'un seul champ. Faites correspondre l'attribut de nom dans la balise d'entrée du côté HTML avec le nom du champ. En raison de la fonction lombok, il n'est pas nécessaire d'ajouter un getter setter avec @Data. Il semble que le type de champ devrait être le type de référence (classe wrapper) ʻInteger au lieu du type primitif ʻint
. Parce qu'il peut être distingué par zéro et nul.
BookForm.java
package com.example.demo.form;
import lombok.Data;
@Data
public class BookForm {
private Integer id;
}
Un objet qui stocke temporairement les données acquises à partir de la base de données. Comme je l'ai écrit dans la classe Form, le type doit être un type de référence.
Book.java
package com.example.demo.entity;
import java.time.LocalDate;
import lombok.Data;
@Data
public class Book {
private Integer id;
private String bookName;
private Integer volumeNum;
private String authorName;
private LocalDate publishedDate;
}
Dans le cas de MyBatis, il devient une classe Repository en créant une interface et en ajoutant l'annotation @Mapper. Dans la méthode de recherche à un élément, il est possible de faire référence de manière flexible à chaque champ de la classe Entity dans le fichier de mappage en utilisant la classe Entity (classe Book) plutôt qu'en passant simplement la valeur numérique.
BookDao
package com.example.demo.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.example.demo.entity.Book;
@Mapper
public interface BookDao {
//1 recherche
Book findById(Book book);
//Avoir tout
List<Book> findAll();
}
[À propos du fichier XML]
select
Dans l'attribut + ʻid`, écrivez le nom de méthode correspondant de l'interface Dao.findById
ci-dessous, le champ id de la classe Entity (classe Book) est référencé dans la clause WHERE.BookDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.BookDao">
<select id="findById" resultType="com.example.demo.entity.Book">
SELECT
id,
book_name,
volume_num,
author_name,
published_date
FROM
booktable
WHERE
id = #{id}
</select>
<select id="findAll" resultType="com.example.demo.entity.Book">
SELECT
id,
book_name,
volume_num,
author_name,
published_date
FROM
booktable
</select>
</mapper>
Comme je l'ai écrit dans la classe Dao, la méthode de recherche unique définit une valeur dans le champ id de la classe Entity. Obtenir tous les enregistrements renvoie une liste avec la classe Entity comme élément.
package com.example.demo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.dao.BookDao;
import com.example.demo.entity.Book;
@Service
public class BookService {
@Autowired
BookDao bookDao;
//1 recherche
public Book findById(Integer id) {
Book book = new Book();
book.setId(id);
return this.bookDao.findById(book);
}
//Avoir tout
public List<Book> getBookList(){
return this.bookDao.findAll();
}
}
Dans ce qui suit, @GetMapping et @PostMapping ne sont pas utilisés correctement.
BookController.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.RequestMapping;
import com.example.demo.entity.Book;
import com.example.demo.form.BookForm;
import com.example.demo.service.BookService;
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
BookService bookService;
@RequestMapping("/search")
public String index(BookForm bookForm, String showList, Model model) {
//Titre
model.addAttribute("title", "Librairie");
//Recherche 1 si bookform (classe de formulaire) n'est pas nul
if(bookForm.getId() != null) {
Book book = bookService.findById(bookForm.getId());
model.addAttribute("book", book);
}
//Lorsque vous appuyez sur le bouton d'affichage de la liste, cette liste est enregistrée dans le modèle.
if(showList != null) {
List<Book> bookList = bookService.getBookList();
model.addAttribute("bookList", bookList);
}
return "index";
}
}
Le contenu affiché change selon que l'objet enregistré dans le modèle de contrôleur avec th: if
est nul.
index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}">title</title>
<link href="/css/style.css" rel="stylesheet">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>Librairie</p>
<form action="/book/search" method="post">
<label>ID:<input class="input" type="text" name="id"></label><br>
<div><input class="search" type="submit" value="Chercher"/></div>
</form>
<form action="/book/search" method="post">
<div><input class="list" type="submit" name="showList" value="Affichage de la liste"/></div>
</form>
<div th:if="${book} !=null" th:object="${book}">
<table>
<tr>
<th>ID</th>
<th>Titre de livre</th>
<th>rouleau</th>
<th>Nom de l'auteur</th>
<th>Date de publication</th>
</tr>
<tr>
<td th:text="*{id}">id</td>
<td th:text="*{bookName}">Titre de livre</td>
<td th:text="*{volumeNum}">rouleau</td>
<td th:text="*{authorName}">Nom de l'auteur</td>
<td th:text="*{publishedDate}">Date de publication</td>
</tr>
</table>
</div>
<div th:if="${bookList} !=null">
<table>
<tr>
<th>ID</th>
<th>Titre de livre</th>
<th>rouleau</th>
<th>Nom de l'auteur</th>
<th>Date de publication</th>
</tr>
<tr th:each="book:${bookList}" th:object="${book}">
<td th:text="*{id}">id</td>
<td th:text="*{bookName}">Titre de livre</td>
<td th:text="*{volumeNum}">rouleau</td>
<td th:text="*{authorName}">Nom de l'auteur</td>
<td th:text="*{publishedDate}">Date de publication</td>
</tr>
</table>
</div>
</body>
</html>
Je ne suis pas sûr de CSS. J'ai trouvé que les balises peuvent être distinguées par [type = ""], et que les éléments enfants peuvent être spécifiés avec des délimiteurs de table et d'espace. .. ..
style.css
@charset "UTF-8";
input[type="text"]{
width:70%;
border-radius: 5px;
padding: 10px;
}
input[type="submit"].search{
border-radius: 5px;
padding: 5px;
margin-top: 10px;
background-color:#99CCCC;
}
input[type="submit"].list{
border-radius: 5px;
padding: 5px;
margin-top: 10px;
background-color: #008BBB;
color:#FFFFFF
}
table{
width: 100%;
margin-top: 10px;
border-collapse: collapse;
}
table th, table td {
border: 1px solid #ddd;
padding: 6px;
}
table th {
background-color: #6699FF;
}
Recommended Posts