[JAVA] [Avec un exemple de code] Les bases de Spring JDBC apprises avec l'application Blog

Même si j'ai imité l'exemple de code du livre et écrit le code, je ne savais pas si je comprenais JDBC, donc j'ai en fait créé une application de blog super simple en utilisant Spring JDBC. (Aucune sécurité ni transaction n'est implémentée. Il s'agit simplement d'une confirmation de l'opération CRUD)

Nous publions le référentiel sur GitHub. Cliquez ici pour le référentiel Spring-BlogApp

Environnement de développement

Tous les outils sont gratuits. Si vous pouvez travailler avec SQL dans le terminal, vous n'avez pas besoin d'outils SQL.

1. À propos des cours obligatoires

A. Qu'est-ce qu'une classe de domaine?

Objets passés entre la classe de référentiel et la classe de service

B. Qu'est-ce qu'une classe de référentiel?

Effectuer une opération CRUD sur la base de données et renvoyer le résultat = Exécuter une instruction SQL depuis la classe du référentiel pour obtenir les résultats de la recherche

C. Qu'est-ce qu'une classe de service?

Appelez la classe de référentiel qui effectue les opérations DB

D. Qu'est-ce qu'une classe de contrôleur?

Recevoir le fonctionnement frontal et donner des instructions à la classe de service appropriée

2. Hiérarchie du projet

src/main/java java.png

src/main/resource resource.png

3. HTML et chaque formulaire

Je vais l'omettre ici. Consultez le référentiel GitHub.

4. Création d'une classe de domaine

Créez-le dans com.example.demo.domain.model avec le nom 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. Création d'une classe de référentiel

A. Créer une interface

Spring JDBC a JdbcTemplate et NamedParameterJdbcTemplate, en supposant qu'ils sont utilisés correctement. Créez une interface qui peut être écrasée et réutilisée.

Créez-le dans com.example.demo.domain.model.repository avec le nom 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 {
  //En créant une interface, elle peut être remplacée et réutilisée.
  //Dao signifie Data Access Object

  //Obtenir le nombre de table Blog
  public int count() throws DataAccessException;

  //Obtenir plusieurs données dans une table de blog
  public List<Blog> selectMany() throws DataAccessException;

  //Obtenir 1 élément de données de table Blog
  public Blog selectOne(Integer articleId) throws DataAccessException;

  //Insérer 1 données dans le tableau Blog
  public int insertOne(Blog blog) throws DataAccessException;

  //Mettre à jour 1 élément des données du tableau Blog
  public int updateOne(Blog blog) throws DataAccessException;

  //Supprimer 1 élément des données du tableau Blog
  public int deleteOne(Integer articleId) throws DataAccessException;
}

B. Mise en œuvre du référentiel

Ecrivez le processus d'écrasement de l'interface et d'exécution réelle de l'opération DB. Créez-le dans com.example.demo.domain.model.repository.jdbc avec le nom 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;

  //Obtenir le nombre de table Blog
  @Override
  public int count() throws DataAccessException {

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

    return count;
  }

  //Obtenir toutes les données du tableau Blog
  @Override
  public List<Blog> selectMany() throws DataAccessException {

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

    //Variables pour renvoyer les résultats
    List<Blog>  blogList = new ArrayList<>();

    //Stocker les données acquises dans la liste
    for (Map<String, Object> map : getList) {

      //Créer une instance de blog
      Blog blog = new Blog();
 
      //Stocker les données acquises dans l'instance 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("updated_date"));

      //Stocker dans la liste de retour
      blogList.add(blog);
    }

    return blogList;
  }

  //Obtenir 1 élément de données de table Blog
  @Override
  public Blog selectOne(Integer articleId) throws DataAccessException {

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

    //Créer une instance de blog
    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;
  }

  //Insérer 1 données dans le tableau Blog
  @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;
  }

  //Mettre à jour 1 élément des données du tableau Blog
  @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;
  }

  //Supprimer 1 élément des données du tableau Blog
  @Override
  public int deleteOne(Integer articleId) throws DataAccessException {

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

    return rowNumber;
 }
}

6. Création d'une classe de service

Créez-le dans com.example.demo.domain.service avec le nom 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;

  //Obtenir le nombre de table Blog
  public int count() {
    return dao.count();
  }

  //Obtenir toutes les données du tableau Blog
  public List<Blog> selectMany() {
    return dao.selectMany();
  }

  //Obtenir 1 élément de données de table Blog
  public Blog selectOne(Integer articleId) {
    return dao.selectOne(articleId);
  }

  //Insérer 1 données dans le tableau Blog
  public boolean insertOne(Blog blog) {
  
    int rowNumber = dao.insertOne(blog);

    //Variable de retour de résultat
    boolean result = false;

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

    return result;
  }

  //Mettre à jour 1 élément des données du tableau Blog
  public boolean updateOne(Blog blog) {

    int rowNumber = dao.updateOne(blog);

    //Variable de retour de résultat
    boolean result = false;

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

    return result;
  }

  //Supprimer 1 élément des données du tableau Blog
  public boolean deleteOne(Integer articleId) {
    
    int rowNumber = dao.deleteOne(articleId);

    //Variable de retour de résultat
    boolean result = false;

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

    return result;
  }
}

7. Création d'une classe de contrôleur

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) {

    //Enregistrer une chaîne de caractères pour afficher la liste d'articles dans la partie contenu de l'article
    model.addAttribute("main" , "topContent :: main_content");

    //Récupérez toutes les données du tableau Blog
    List<Blog> blogList = blogService.selectMany();

    //modèle Enregistrer un article de blog
    model.addAttribute("blogList", blogList);

    return "top";
  }

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

    //Enregistrez la chaîne de caractères pour afficher le formulaire dans la partie contenu
    model.addAttribute("main" , "form/postFormContent :: main_content");

    return "top";
  }

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

    //Si vous êtes bloqué dans le contrôle d'entrée, revenez au nouvel écran d'enregistrement
    if (bindingResult.hasErrors()) {

      //Appelez la méthode pour la demande GET et revenez au nouvel écran d'enregistrement
      return getForm(form, model);
    }

    //Vérifiez le contenu du formulaire sur la console
    System.out.println(form);

    //Variable pour insert
    Blog blog = new Blog();

    // created_Instance pour la date
    GetDate getDate = new GetDate();

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

    //processus d'inscription
    boolean result = blogService.insertOne(blog);

    //Jugement du résultat de l'enregistrement de l'utilisateur
    if(result == true) {
      System.out.println("succès incrusté");
    }else {
      System.out.println("insérer l'échec");
    }

    //Rediriger vers la première page
    return "redirect:/";
  }

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

    //Enregistrer la chaîne de caractères pour afficher le contenu de l'article dans la partie contenu
    model.addAttribute("main" , "detail :: main_content");

    Blog blog = blogService.selectOne(articleId);

    //Enregistrer les données du blog
    model.addAttribute("blog", blog);

    return "top";
  }
	
  @GetMapping("/update/{id}")
  public String getUpdate(@ModelAttribute ArticleForm form,
    @PathVariable("id")Integer articleId,
    Model model) {
 
    //Enregistrez la chaîne de caractères pour afficher le formulaire dans la partie contenu
    model.addAttribute("main" , "form/updateFormContent :: main_content");

    //1 processus d'acquisition
    Blog blog = blogService.selectOne(articleId);

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

    model.addAttribute("articleForm", form);

    return "top";
  }

  //params spécifie la chaîne de caractères de la balise de nom du bouton d'envoi
  //Pour distinguer si la page comporte plusieurs boutons
  @PostMapping(value = "/update", params = "update")
  public String postUpdate(@ModelAttribute @Validated ArticleForm form,
    BindingResult bindingResult,
    Model model) {

    //Si vous êtes bloqué dans la vérification d'entrée, revenez au retour d'image nouvellement enregistré
    if (bindingResult.hasErrors()) {

      //Appelez la méthode pour la demande GET et revenez au nouvel écran d'enregistrement
      return getForm(form, model);
    }

    //Vérifiez le contenu du formulaire sur la console
    System.out.println(form);

    //Variable pour insert
    Blog blog = new Blog();

    // created_Instance pour la date
    GetDate getDate = new GetDate();

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

    //Processus de mise à jour
    boolean result = blogService.updateOne(blog);

    //Jugement du résultat de l'enregistrement
    if(result == true) {
      System.out.println("insérer le succès");
    }else {
      System.out.println("insérer l'échec");
    }

    //Rediriger vers la première page
    return "redirect:/";
  }

  //params spécifie la chaîne de caractères de la balise de nom du bouton d'envoi
  //Pour distinguer si la page comporte plusieurs boutons
  @PostMapping(value = "/update", params = "delete")
  public String postDelete(@ModelAttribute ArticleForm form, Model model) {

     //Supprimer l'exécution
    boolean result = blogService.deleteOne(form.getArticleId());

    if (result == true) {
      System.out.println("supprimer le succès");
    }else {
      System.out.println("supprimer l'échec");
    }

    //Rediriger vers la première page
    return "redirect:/";
  }
}

8. Explication

Lorsque vous utilisez redirect:, c'est ** lors du déplacement de pages **.

@PostMapping(value = "/update", params = "delete")
public String hogehoge(...) {
  ...
  
  //Aller à la première page de la mise à jour
  return "redirect:/";

  // top.J'obtiens une erreur lorsque j'utilise html
  return "top";
}

Lors de l'utilisation de return getForm ()

//Lorsqu'une erreur survient lors de la validation
//Utilisé pour conserver les valeurs enregistrées dans la forme et le modèle et afficher la page d'origine
if (bindingResult.hasErrors()) {

  //Revenir à la page du formulaire
  return getForm(form, model);
}

Si vous n'avez pas de paramètres, vous n'avez pas à saisir de valeur.

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

9. Chemin de la page

/ post => Page du formulaire d'inscription / update / {id} => Mettre à jour la page du formulaire / detail / {id} => Page d'article

10. Capture d'écran de l'application

Veuillez noter que toutes les photos sont des chats

haut de page

トップページ

formulaire de saisie

/ post et / update / {id} Ajoutez la barre d'adresse de votre navigateur / post au nouveau formulaire de saisie.

入力フォーム

Page d'article

/detail/{id} 記事ページ

Tâche

Créez un classement basé sur le téléchargeur de fichier image et le nombre d'accès et affichez-le sur le côté.

Supplément

Qu'est-ce que JDBC

Java Database Connectivity (JDBC) est une API permettant de connecter Java et les bases de données associées. Source: Wikipédia

Qu'est-ce que Spring JDBC

Dans JDBC, vous devez écrire une connexion à la base de données et fermer le traitement, mais avec Spring JDBC, vous pouvez l'écrire dans un code simple. Il fait également correspondre le code d'erreur unique de la base de données à Spring et lève une exception appropriée.

Recommended Posts

[Avec un exemple de code] Les bases de Spring JDBC apprises avec l'application Blog
Exemple de code pour le test unitaire d'un contrôleur Spring Boot avec MockMvc
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Compatibilité de Spring JDBC et My Batis avec Spring Data JDBC (provisoire)
Créer Restapi avec Spring Boot (jusqu'à l'exécution de l'application)
Comment démarrer par environnement avec Spring Boot de Maven
Code du port C avec de nombreux typecasts vers Swift
Une histoire remplie des bases de Spring Boot (résolu)
Exemple de code pour analyser la date et l'heure avec SimpleDateFormat de Java
Utiliser Spring JDBC avec Spring Boot
J'ai essayé de me connecter à MySQL en utilisant le modèle JDBC avec Spring MVC
Comment réaliser un téléchargement de fichiers volumineux avec Rest Template of Spring
Java pour apprendre avec les ramen [Partie 1]
Créez une application avec Spring Boot 2
Remarques sur l'utilisation de Spring Data JDBC
Programmation Spring Boot avec VS Code
Créez une application avec Spring Boot
Être conscient du code facile à lire
Développement d'applications Web Spring5 MVC avec Visual Studio Code Hello World Creation
Exemple de code pour obtenir les valeurs de type JDBC clés dans la base de données Java + H2
Comment lire le corps de la requête plusieurs fois avec Spring Boot + Spring Security
Je veux afficher des images avec REST Controller de Java et Spring!
Comment accéder directement à Socket avec la fonction TCP de Spring Integration
Exemple de configuration minimale pour publier automatiquement Lambda par Java avec un pipeline de code
[swift5] Comment changer la couleur de TabBar ou la couleur de l'élément de TabBar avec le code