[JAVA] [Mit Beispielcode] Grundlagen von Spring JDBC mit der Blog-App gelernt

Selbst wenn ich den Beispielcode des Buches imitierte und den Code schrieb, wusste ich nicht, ob ich JDBC verstand, also habe ich tatsächlich eine supereinfache Blog-Anwendung mit Spring JDBC erstellt. (Sicherheit und Transaktionen sind nicht implementiert. Dies ist nur eine Bestätigung des CRUD-Betriebs.)

Wir veröffentlichen das Repository auf GitHub. Klicken Sie hier, um das Spring-BlogApp-Repository aufzurufen

Entwicklungsumgebung

Alle Tools können kostenlos verwendet werden. Wenn Sie im Terminal mit SQL arbeiten können, benötigen Sie keine SQL-Tools.

1. Über erforderliche Klassen

A. Was ist eine Domainklasse?

Objekte, die zwischen der Repository-Klasse und der Service-Klasse übergeben werden

B. Was ist eine Repository-Klasse?

Führen Sie eine CRUD-Operation für die Datenbank durch und geben Sie das Ergebnis zurück = SQL-Anweisung aus der Repository-Klasse ausführen, um Suchergebnisse zu erhalten

C. Was ist eine Serviceklasse?

Rufen Sie die Repository-Klasse auf, die DB-Operationen ausführt

D. Was ist eine Controller-Klasse?

Erhalten Sie den Betrieb auf der Vorderseite und geben Sie Anweisungen an die entsprechende Serviceklasse

2. Projekthierarchie

src/main/java java.png

src/main/resource resource.png

3. HTML und jedes Formular

Ich werde es hier weglassen. Überprüfen Sie das GitHub-Repository.

4. Erstellen einer Domänenklasse

Erstellen Sie es in com.example.demo.domain.model mit dem Namen Blog.java.

Blog.java


package com.example.demo.domain.model;

import java.io.Serial;
import java.util.Date;

import lombok.Data;

@Data
public class Blog {

  private Integer articleId;
  private String articleTitle;
  private String articleBody;
  private Date createdDate;
  private Date updatedDate;
}

5. Erstellen einer Repository-Klasse

A. Erstellen einer Schnittstelle

Spring JDBC verfügt über "JdbcTemplate" und "NamedParameterJdbcTemplate", sofern sie ordnungsgemäß verwendet werden. Erstellen Sie eine Schnittstelle, die überschrieben und wiederverwendet werden kann.

Erstellen Sie es in com.example.demo.domain.model.repository mit dem Namen BlgDao.java.

java.BlogDao.java


package com.example.demo.domain.model.repository;

import java.io.Serial;
import java.util.List;

import org.springframework.dao.DataAccessException;

import com.example.demo.domain.model.Blog;

public interface BlogDao {
  //Durch das Erstellen einer Schnittstelle kann diese überschrieben und wiederverwendet werden.
  //Dao steht für Data Access Object

  //Holen Sie sich die Nummer der Blog-Tabelle
  public int count() throws DataAccessException;

  //Holen Sie sich mehrere Daten in eine Blog-Tabelle
  public List<Blog> selectMany() throws DataAccessException;

  //Holen Sie sich 1 Element der Blog-Tabellendaten
  public Blog selectOne(Integer articleId) throws DataAccessException;

  //Fügen Sie 1 Daten in die Blog-Tabelle ein
  public int insertOne(Blog blog) throws DataAccessException;

  //Aktualisieren Sie 1 Element der Blog-Tabellendaten
  public int updateOne(Blog blog) throws DataAccessException;

  //Löschen Sie 1 Element der Blog-Tabellendaten
  public int deleteOne(Integer articleId) throws DataAccessException;
}

B. Repository-Implementierung

Schreiben Sie den Prozess des Überschreibens der Schnittstelle und des tatsächlichen Ausführens der DB-Operation. Erstellen Sie es in com.example.demo.domain.model.repository.jdbc mit dem Namen BlogDaoJdbcImpl.

BlogDaoJdbcImpl.java


package com.example.demo.domain.model.repository.jdbc;

import java.io.Serial;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.demo.domain.model.Blog;
import com.example.demo.domain.model.repository.BlogDao;

@Repository
public class BlogDaoJdbcImpl implements BlogDao {

  @Autowired
  JdbcTemplate jdbc;

  //Holen Sie sich die Nummer der Blog-Tabelle
  @Override
  public int count() throws DataAccessException {

    int count = jdbc.queryForObject(
      "SELECT COUNT(*) FROM article",
      Integer.class
    );

    return count;
  }

  //Holen Sie sich alle Daten in der Blog-Tabelle
  @Override
  public List<Blog> selectMany() throws DataAccessException {

    List<Map<String, Object>> getList = jdbc.queryForList(
      "SELECT * FROM article ORDER BY article_id DESC"
    );

    //Variablen für die Rückgabe von Ergebnissen
    List<Blog>  blogList = new ArrayList<>();

    //Speichern Sie die erfassten Daten in Liste
    for (Map<String, Object> map : getList) {

      //Erstellen Sie eine Blog-Instanz
      Blog blog = new Blog();
 
      //Speichern Sie die erfassten Daten in der Blog-Instanz
      blog.setArticleId((Integer)map.get("article_id"));
      blog.setArticleTitle((String)map.get("article_title"));
      blog.setArticleBody((String)map.get("article_body"));
      blog.setCreatedDate((Date)map.get("created_date"));
      blog.setUpdatedDate((Date)map.get("updated_date"));

      //In Rückgabeliste speichern
      blogList.add(blog);
    }

    return blogList;
  }

  //Holen Sie sich 1 Element der Blog-Tabellendaten
  @Override
  public Blog selectOne(Integer articleId) throws DataAccessException {

    Map<String, Object> map = jdbc.queryForMap(
      "SELECT * FROM article WHERE article_id = ?", articleId
    );

    //Erstellen Sie eine Blog-Instanz
    Blog blog = new Blog();

    blog.setArticleId((Integer)map.get("article_id"));
    blog.setArticleTitle((String)map.get("article_title"));
    blog.setArticleBody((String)map.get("article_Body"));
    blog.setCreatedDate((Date)map.get("created_date"));
    blog.setUpdatedDate((Date)map.get("update_date"));

    return blog;
  }

  //Fügen Sie 1 Daten in die Blog-Tabelle ein
  @Override
  public int insertOne(Blog blog) throws DataAccessException {

    int rowNumber = jdbc.update(
      "INSERT INTO article("
      + " article_title,"
      + " article_body,"
      + " created_date"
      + ") VALUES (?, ?, ?)"
      , blog.getArticleTitle()
      , blog.getArticleBody()
      , blog.getCreatedDate()
    );

    return rowNumber;
  }

  //Aktualisieren Sie 1 Element der Blog-Tabellendaten
  @Override
  public int updateOne(Blog blog) throws DataAccessException {

    int rowNumber = jdbc.update(
      "UPDATE Blog SET"
      + " article_title = ?,"
      + " article_body = ?,"
      + " updated_date = ?"
      + " WHERE article_id = ?"
      , blog.getArticleTitle()
      , blog.getArticleBody()
      , blog.getUpdatedDate()
      , blog.getArticleId()
    );

    return rowNumber;
  }

  //Löschen Sie 1 Element der Blog-Tabellendaten
  @Override
  public int deleteOne(Integer articleId) throws DataAccessException {

    int rowNumber = jdbc.update(
      "DELETE FROM article WHERE article_id = ?", articleId
    );

    return rowNumber;
 }
}

6. Erstellen einer Serviceklasse

Erstellen Sie es in "com.example.demo.domain.service" mit dem Namen "BlogService".

BlogService.java


package com.example.demo.domain.service;

import java.io.Serial;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.domain.model.Blog;
import com.example.demo.domain.model.repository.BlogDao;

@Service
public class BlogService {

  @Autowired
  BlogDao dao;

  //Holen Sie sich die Nummer der Blog-Tabelle
  public int count() {
    return dao.count();
  }

  //Holen Sie sich alle Daten in der Blog-Tabelle
  public List<Blog> selectMany() {
    return dao.selectMany();
  }

  //Holen Sie sich 1 Element der Blog-Tabellendaten
  public Blog selectOne(Integer articleId) {
    return dao.selectOne(articleId);
  }

  //Fügen Sie 1 Daten in die Blog-Tabelle ein
  public boolean insertOne(Blog blog) {
  
    int rowNumber = dao.insertOne(blog);

    //Ergebnis Rückgabevariable
    boolean result = false;

    if (rowNumber > 0) {
      result = true;
    }

    return result;
  }

  //Aktualisieren Sie 1 Element der Blog-Tabellendaten
  public boolean updateOne(Blog blog) {

    int rowNumber = dao.updateOne(blog);

    //Ergebnis Rückgabevariable
    boolean result = false;

    if (rowNumber > 0) {
      result = true;
    }

    return result;
  }

  //Löschen Sie 1 Element der Blog-Tabellendaten
  public boolean deleteOne(Integer articleId) {
    
    int rowNumber = dao.deleteOne(articleId);

    //Ergebnis Rückgabevariable
    boolean result = false;

    if (rowNumber > 0) {
      result = true;
    }

    return result;
  }
}

7. Erstellen einer Controller-Klasse

HomeController.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.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
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 com.example.demo.domain.model.ArticleForm;
import com.example.demo.domain.model.Blog;
import com.example.demo.domain.model.GetDate;
import com.example.demo.domain.service.BlogService;

@Controller
public class HomeControler {

  @Autowired
  BlogService blogService;

  @GetMapping("/")
  public String getHome(Model model) {

    //Registrieren Sie eine Zeichenfolge, um die Artikelliste im Artikelinhaltsteil anzuzeigen
    model.addAttribute("main" , "topContent :: main_content");

    //Holen Sie sich alle Daten in der Blog-Tabelle
    List<Blog> blogList = blogService.selectMany();

    //Modell Registrieren Sie einen Blog-Beitrag
    model.addAttribute("blogList", blogList);

    return "top";
  }

  @GetMapping("/post")
  public String getForm(@ModelAttribute ArticleForm form, Model model) {

    //Registrieren Sie die Zeichenfolge, um das Formular im Inhaltsteil anzuzeigen
    model.addAttribute("main" , "form/postFormContent :: main_content");

    return "top";
  }

  @PostMapping("/post")
  public String postForm(@ModelAttribute @Validated ArticleForm form,
    BindingResult bindingResult,
    Model model) {

    //Wenn Sie bei der Eingabeprüfung nicht weiterkommen, kehren Sie zum neuen Registrierungsbildschirm zurück
    if (bindingResult.hasErrors()) {

      //Rufen Sie die Methode für die GET-Anforderung auf und kehren Sie zum neuen Registrierungsbildschirm zurück
      return getForm(form, model);
    }

    //Überprüfen Sie den Inhalt des Formulars auf der Konsole
    System.out.println(form);

    //Variable zum Einfügen
    Blog blog = new Blog();

    // created_Instanz für Datum
    GetDate getDate = new GetDate();

    blog.setArticleTitle(form.getArticleTitle());
    blog.setArticleBody(form.getArticleBody());
    blog.setCreatedDate(getDate.getDate());

    //Registrierungsprozess
    boolean result = blogService.insertOne(blog);

    //Beurteilung des Benutzerregistrierungsergebnisses
    if(result == true) {
      System.out.println("Inset Erfolg");
    }else {
      System.out.println("Fehler einfügen");
    }

    //Zur obersten Seite umleiten
    return "redirect:/";
  }

  @GetMapping("/detail/{id}")
  public String postDetail(@PathVariable("id")Integer articleId, Model model) {

    //Registrieren Sie die Zeichenfolge für die Anzeige des Artikelinhalts im Inhaltsteil
    model.addAttribute("main" , "detail :: main_content");

    Blog blog = blogService.selectOne(articleId);

    //Registrieren Sie Blog-Daten
    model.addAttribute("blog", blog);

    return "top";
  }
	
  @GetMapping("/update/{id}")
  public String getUpdate(@ModelAttribute ArticleForm form,
    @PathVariable("id")Integer articleId,
    Model model) {
 
    //Registrieren Sie die Zeichenfolge, um das Formular im Inhaltsteil anzuzeigen
    model.addAttribute("main" , "form/updateFormContent :: main_content");

    //1 Akquisitionsprozess
    Blog blog = blogService.selectOne(articleId);

    form.setArticleId(blog.getArticleId());
    form.setArticleTitle(blog.getArticleTitle());
    form.setArticleBody(blog.getArticleBody());

    model.addAttribute("articleForm", form);

    return "top";
  }

  //params gibt die Zeichenfolge des Namensschilds der Senden-Schaltfläche an
  //Unterscheiden, ob die Seite mehrere Schaltflächen hat
  @PostMapping(value = "/update", params = "update")
  public String postUpdate(@ModelAttribute @Validated ArticleForm form,
    BindingResult bindingResult,
    Model model) {

    //Wenn Sie bei der Eingabeprüfung nicht weiterkommen, kehren Sie zur neu registrierten Bildrückgabe zurück
    if (bindingResult.hasErrors()) {

      //Rufen Sie die Methode für die GET-Anforderung auf und kehren Sie zum neuen Registrierungsbildschirm zurück
      return getForm(form, model);
    }

    //Überprüfen Sie den Inhalt des Formulars auf der Konsole
    System.out.println(form);

    //Variable zum Einfügen
    Blog blog = new Blog();

    // created_Instanz für Datum
    GetDate getDate = new GetDate();

    blog.setArticleId(form.getArticleId());
    blog.setArticleTitle(form.getArticleTitle());
    blog.setArticleBody(form.getArticleBody());
    blog.setUpdatedDate(getDate.getDate());

    //Aktualisierungsprozess
    boolean result = blogService.updateOne(blog);

    //Beurteilung des Registrierungsergebnisses
    if(result == true) {
      System.out.println("Erfolg einfügen");
    }else {
      System.out.println("Fehler einfügen");
    }

    //Zur obersten Seite umleiten
    return "redirect:/";
  }

  //params gibt die Zeichenfolge des Namensschilds der Senden-Schaltfläche an
  //Unterscheiden, ob die Seite mehrere Schaltflächen hat
  @PostMapping(value = "/update", params = "delete")
  public String postDelete(@ModelAttribute ArticleForm form, Model model) {

     //Ausführung löschen
    boolean result = blogService.deleteOne(form.getArticleId());

    if (result == true) {
      System.out.println("Erfolg löschen");
    }else {
      System.out.println("Fehler beim Löschen");
    }

    //Zur obersten Seite umleiten
    return "redirect:/";
  }
}

8. Erklärung

Bei Verwendung von redirect: ist dies ** beim Verschieben von Seiten **.

@PostMapping(value = "/update", params = "delete")
public String hogehoge(...) {
  ...
  
  //Gehen Sie vom Update zur obersten Seite
  return "redirect:/";

  // top.Ich erhalte eine Fehlermeldung, wenn ich HTML verwende
  return "top";
}

Bei Verwendung von return getForm ()

//Wenn bei der Validierung ein Fehler auftritt
//Wird verwendet, um die Werte in Form und Modell registriert zu halten und die Originalseite anzuzeigen
if (bindingResult.hasErrors()) {

  //Zurück zur Formularseite
  return getForm(form, model);
}

Wenn Sie keine Parameter haben, müssen Sie keinen Wert eingeben.

@PostMapping("/post")
@PostMapping(value = "/update", params = "delete")

9. Seitenpfad

/ post => Anmeldeformular Seite / update / {id} => Formularseite aktualisieren / detail / {id} => Artikelseite

10. App-Screenshot

Bitte beachten Sie, dass alle Fotos Katzen sind

oberste Seite

トップページ

Eingabeformular

/ post und / update / {id} Fügen Sie die Adressleiste / post Ihres Browsers zum neuen Eingabeformular hinzu.

入力フォーム

Artikelseite

/detail/{id} 記事ページ

Aufgabe

Erstellen Sie ein Ranking basierend auf dem Uploader der Bilddatei und der Anzahl der Zugriffe und zeigen Sie es auf der Seite an.

Ergänzung

Was ist JDBC?

Java Database Connectivity (JDBC) ist eine API zum Verbinden von Java und verwandten Datenbanken. Quelle: Wikipedia

Was ist Spring JDBC?

In JDBC müssen Sie eine DB-Verbindung schreiben und die Verarbeitung schließen, aber mit Spring JDBC können Sie sie in einfachem Code schreiben. Es vergleicht auch den eindeutigen Fehlercode der Datenbank mit Spring und löst eine entsprechende Ausnahme aus.

Recommended Posts

[Mit Beispielcode] Grundlagen von Spring JDBC mit der Blog-App gelernt
Beispielcode zum Testen eines Spring Boot-Controllers mit MockMvc
Einstellungen für die Verbindung zu MySQL mit Spring Boot + Spring JDBC
Kompatibilität von Spring JDBC und My Batis mit Spring Data JDBC (vorläufig)
Erstellen Sie Restapi mit Spring Boot (bis zum Ausführen der App)
Booten nach Umgebung mit Spring Boot of Maven
Port C-Code mit vielen Typecasts zu Swift
Eine Geschichte voller Grundlagen von Spring Boot (gelöst)
Beispielcode zum Parsen von Datum und Uhrzeit mit Java SimpleDateFormat
Verwenden Sie Spring JDBC mit Spring Boot
Ich habe versucht, mithilfe von JDBC Template mit Spring MVC eine Verbindung zu MySQL herzustellen
So erzielen Sie mit Rest Template of Spring einen großen Datei-Upload
Java mit Ramen lernen [Teil 1]
Erstellen Sie eine App mit Spring Boot 2
Hinweise zur Verwendung von Spring Data JDBC
Spring Boot Programmierung mit VS Code
Erstellen Sie eine App mit Spring Boot
Um auf einfach zu lesenden Code zu achten
Spring5 MVC-Webanwendungsentwicklung mit Visual Studio-Code Hello World Creation
Beispielcode zum Abrufen der wichtigsten JDBC-Typwerte in der Java + H2-Datenbank
So lesen Sie Request Body mit Spring Boot + Spring Security mehrmals
Ich möchte Bilder mit REST Controller von Java und Spring anzeigen!
So greifen Sie mit der TCP-Funktion von Spring Integration direkt auf Socket zu
Mindestkonfigurationsbeispiel für die automatische Freigabe von Lambda durch Java mit Code-Pipeline
[swift5] So ändern Sie die Farbe der TabBar oder die Farbe des TabBar-Elements mit Code