Ich habe nur JdbcTemplate verwendet und MyBatis nie verwendet, daher habe ich versucht, SpringBoot + MyBatis + MySQL zu verwenden.
Dieses Mal werden die Informationen des Buches in der Datenbank registriert, und wir werden eine erhalten und alle anzeigen.
■ Bildschirm beim ersten Zugriff
■ 1 Suche (ID in das Formular eingeben und Suche drücken)
■ Alle Elemente anzeigen (Listenanzeige drücken)
Aus irgendeinem Grund kann BookDao aus der BookService-Klasse verwendet werden, ohne eine Schnittstelle zu implementieren. Es scheint, dass es hinter den Kulissen implementiert ist und von der Service-Klasse verwendet werden kann.
└── 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'
}
Erstellen Sie zunächst eine Datenbank mit MySQL. In diesem Beispiel Bibliothek.
CREATE DATABASE library;
Wenn Sie die folgende Datei vorbereiten, werden die Testdaten bei jedem Start von Spring Boot vorbereitet.
schema.sql
--Löschen, wenn ein Booktable vorhanden ist
DROP TABLE IF EXISTS booktable;
--Wenn es keinen Booktable gibt, erstellen Sie einen neuen
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 der Bücher Anfangsdaten
--Die ID-Spalte wird automatisch inkrementiert, sodass sie nicht erforderlich ist
INSERT INTO booktable
(book_name, volume_num,author_name,published_date)
VALUES
( 'HUNTER X HUNTER',36,'Yoshihiro Togashi','2018-10-04'),
( 'Berserker',40,'Kentaro Miura','2018-09-28'),
( 'Drifter',6,'Kota Hirano','2018-11-30'),
( 'Rashomon',1,'Ryunosuke Akutagawa','1915-11-01')
;
Es funktioniert nur, wenn Sie dem Verbindungsziel "ServerTimezone = JST" hinzufügen. Auch mit "mybatis.configuration.map-underscore-to-camel-case = true" wird der DB-Spaltenname, selbst wenn es sich um einen Schlangenfall handelt, auf der Java-Seite als Kamelfall erkannt.
###Einstellungen für die Datenbankverbindung
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
###Der DB-Spaltenname des Schlangenfalls wird als Kamelfall auf der Entitätsseite von Spring zugeordnet.
mybatis.configuration.map-underscore-to-camel-case=true
###Geben Sie an, ob initialisiert werden soll.
spring.datasource.initialization-mode=always
Dieses Mal wird nur die ID vom Bildschirm empfangen, sodass nur ein Feld vorhanden ist. Ordnen Sie das Namensattribut im Eingabe-Tag auf der HTML-Seite dem Feldnamen zu. Aufgrund der Funktion von lombok ist es nicht erforderlich, einen Setter Getter mit @Data hinzuzufügen. Es scheint, dass der Feldtyp der Referenztyp (Wrapper-Klasse) "Integer" anstelle des primitiven Typs "int" sein sollte. Weil es durch Null und Null unterschieden werden kann.
BookForm.java
package com.example.demo.form;
import lombok.Data;
@Data
public class BookForm {
private Integer id;
}
Ein Objekt, das die aus der Datenbank erfassten Daten vorübergehend speichert. Wie ich in der Form-Klasse geschrieben habe, sollte der Typ ein Referenztyp sein.
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;
}
Im Fall von MyBatis wird es zu einer Repository-Klasse, indem eine Schnittstelle erstellt und die Annotation @Mapper hinzugefügt wird. Bei der Ein-Element-Suchmethode ist es möglich, flexibel auf jedes Feld der Entitätsklasse in der Zuordnungsdatei zu verweisen, indem die Entitätsklasse (Buchklasse) verwendet wird, anstatt nur den numerischen Wert zu übergeben.
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 Suche
Book findById(Book book);
//Nimm alle
List<Book> findAll();
}
[Über XML-Datei]
select-Element
.id-Attribut
.parameterType attribute
wird diesmal weggelassen. Es scheint den Typ des Arguments der Methode zu schreiben. Wenn nicht angegeben, wird der tatsächliche Argumenttyp automatisch ermittelt.findById
wird auf das ID-Feld der Entity-Klasse (Book-Klasse) in der WHERE-Klausel verwiesen.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>
Wie ich in der Dao-Klasse geschrieben habe, legt die einzelne Suchmethode einen Wert im ID-Feld der Entity-Klasse fest. Alle Datensätze abrufen gibt eine Liste mit der Entity-Klasse als Element zurück.
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 Suche
public Book findById(Integer id) {
Book book = new Book();
book.setId(id);
return this.bookDao.findById(book);
}
//Nimm alle
public List<Book> getBookList(){
return this.bookDao.findAll();
}
}
Im Folgenden werden @GetMapping und @PostMapping nicht ordnungsgemäß verwendet.
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) {
//Titel
model.addAttribute("title", "Buchhandlung");
//Suchen Sie 1, wenn die Buchform (Formularklasse) nicht null ist
if(bookForm.getId() != null) {
Book book = bookService.findById(bookForm.getId());
model.addAttribute("book", book);
}
//Wenn die Listenanzeigetaste gedrückt wird, wird diese Liste im Modell registriert.
if(showList != null) {
List<Book> bookList = bookService.getBookList();
model.addAttribute("bookList", bookList);
}
return "index";
}
}
Der angezeigte Inhalt ändert sich abhängig davon, ob das im Controller-Modell mit th: if
registrierte Objekt null ist.
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>Buchhandlung</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="Suche"/></div>
</form>
<form action="/book/search" method="post">
<div><input class="list" type="submit" name="showList" value="Listenanzeige"/></div>
</form>
<div th:if="${book} !=null" th:object="${book}">
<table>
<tr>
<th>ID</th>
<th>Buchtitel</th>
<th>rollen</th>
<th>Autorenname</th>
<th>Veröffentlichungsdatum</th>
</tr>
<tr>
<td th:text="*{id}">id</td>
<td th:text="*{bookName}">Buchtitel</td>
<td th:text="*{volumeNum}">rollen</td>
<td th:text="*{authorName}">Autorenname</td>
<td th:text="*{publishedDate}">Veröffentlichungsdatum</td>
</tr>
</table>
</div>
<div th:if="${bookList} !=null">
<table>
<tr>
<th>ID</th>
<th>Buchtitel</th>
<th>rollen</th>
<th>Autorenname</th>
<th>Veröffentlichungsdatum</th>
</tr>
<tr th:each="book:${bookList}" th:object="${book}">
<td th:text="*{id}">id</td>
<td th:text="*{bookName}">Buchtitel</td>
<td th:text="*{volumeNum}">rollen</td>
<td th:text="*{authorName}">Autorenname</td>
<td th:text="*{publishedDate}">Veröffentlichungsdatum</td>
</tr>
</table>
</div>
</body>
</html>
Bei CSS bin ich mir nicht sicher. Ich habe festgestellt, dass Tags durch [type = ""] unterschieden werden können und untergeordnete Elemente mit Tabellen- und Leerzeichen angegeben werden können. .. ..
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