[JAVA] Les bases de SpringBoot + MyBatis + MySQL

Aperçu

Je n'ai utilisé que JdbcTemplate et n'ai jamais utilisé MyBatis, j'ai donc essayé d'utiliser SpringBoot + MyBatis + MySQL.

environnement

Ce que j'ai essayé

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 初期画面.png

■ 1 recherche (entrez l'identifiant dans le formulaire et appuyez sur rechercher) 検索結果.png

■ Afficher tous les éléments (appuyez sur l'affichage de la liste) 一覧表示.png

Divers cours et fichiers de paramétrage à préparer

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.

Structure du répertoire

└── 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

Dépendances


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'
	}

Définition de la base de données

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')
;

Fichier de configuration (application.properties)

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

Divers cours

Classe de formulaire

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;
}

Classe d'entité

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;
}

Interface Dao et fichier de mappage

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]

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>

Classe de service

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();
	}
}

Classe de contrôleur

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";

	}

}

écran

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

Les bases de SpringBoot + MyBatis + MySQL
Surveillance Docker-expliquant les bases des bases-
À propos des bases du développement Android
[Challenge CircleCI from 0] Apprenez les bases de CircleCI
Comprendre les bases de l'enregistrement audio Android
[jour: 5] J'ai résumé les bases de Java
Exemple de configuration d'IntellijIDEA + SpringBoot + Gradle + MyBatis
Retour sur les bases de Java
Bases de Ruby
Qu'est-ce que JSP? ~ Connaissons les bases de JSP !! ~
[Ruby] Résumé des définitions de classe. Maîtrisez les bases.
J'ai compris les bases de la saisie de caractères
Écraser le contenu de la configuration avec Spring-boot + JUnit5
Le monde de Clara-Rules (2)
[Pour les débutants] DI ~ Les bases de DI et DI au printemps ~
[Pour les débutants] Comprendre rapidement les bases de Java 8 lambda
Jugement du calendrier
Le monde de Clara-Rules (4)
Le monde de Clara-Rules (1)
Le monde de Clara-Rules (3)
Principes de base de l'instruction try-with-resources
Le monde de Clara-Rules (5)
J'ai résumé les types et les bases des exceptions Java
L'idée du tri rapide
[Ruby] Imbrication de classes, héritage et principes de base de soi
L'idée de jQuery
J'ai essayé de résumer les bases de kotlin et java
Une histoire remplie des bases de Spring Boot (résolu)
Comment modifier la valeur de réglage de Springboot Hikari CP
[Résumé des livres techniques] Résumé de la lecture "Apprendre Docker à partir des bases"
À propos de la gestion de Null
[GCD] Principes de base de la classe DispatchQueue
Changer de port avec SpringBoot
Le jeu d'instancier java.lang.Void
Résumé des bases du langage Java
Valeur médiane de trois valeurs
L'illusion de l'orientation objet
Erreur SpringBoot + Mybatis lors du démarrage
Essayez HelloWorld avec la configuration minimale de Heroku Java spring-boot
[Rails / Heroku / MySQL] Comment réinitialiser la base de données de l'application Rails sur Heroku
Comment obtenir l'identifiant de la clé PRIMAY incrémentée automatiquement dans MyBatis