Vue + Spring Boot project combat (VIII): Database Design and CRUD

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/Neuf_Soleil/article/details/92413933

Foreword

This article explains the additions and deletions to change search the database, talked about before installation and use of the database, no impression can review the students ' Vue + Spring Boot project combat (D): Database introduction 」 .

It can be said almost all of the Web project to be involved in this set of CRUD stuff. There are many newly recruited young people complain about "a bomb, interview, job tighten the screws" on how tall the thought content of the work will result in the company every day, only to learn the CRUD. In fact there are a lot of doorways, large areas such as technology selection under different scenarios, such as a small aspect of how to write a SQL statement that may seem subtle differences, on the Internet at high concurrency environments will bring to different results.

Taking into account the actual situation (Author thief lazy), this tutorial does not explore these issues in depth, the goal is to achieve the function myself, and then let everybody do what I do can be achieved if you have a better idea, please share to me I'll keep this reconstruction project, made for a some meaningful things. I put this pit filled out, and then think about the problem of how to optimize the performance of the class to write.

First, the database design

The field of racking our brains process known as database design is thick skinned enough, but anyway, you can not follow the network cable to hit me. Speaking places really need nothing serious pondering, can manage user rights on that whole set of things to do when the background until after the management, now Well, our needs as follows:

  • Present information book, including the cover, title, author, publication date, publisher, summary and classification.
  • Maintenance category.

So the temporary table structure looks like this:
Here Insert Picture Description
build tables and complete data sql file in my gayhub on github:

https://github.com/Antabot/White-Jotter/tree/master/wj

Here I only posted it built table statement:

user 表:

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` char(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

book table:

DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cover` varchar(255) DEFAULT '',
  `title` varchar(255) NOT NULL DEFAULT '',
  `author` varchar(255) DEFAULT '',
  `date` varchar(20) DEFAULT '',
  `press` varchar(255) DEFAULT '',
  `abs` varchar(255) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_book_category_on_cid` (`cid`),
  CONSTRAINT `fk_book_category_on_cid` FOREIGN KEY (`cid`) REFERENCES `category` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=utf8;

category table:

DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Note here that the book table has a foreign key in cid.

Second, CRUD

Or look at the needs of:

  • Information inquiry book (check)
  • Upload book information (increase)
  • Modify the book information (change)
  • Delete book information (deleted)

Involving a query by keyword query (retrieve books), books upload picture upload information involved in, I'm going to write a separate, not much to say here first.

1.pojo

We need to create two pojo, namely Category and Book.

Category:

package com.evan.wj.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "category")
@JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })

public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    int id;

    String name;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Book:

package com.evan.wj.pojo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;

@Entity
@Table(name = "book")
@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    int id;

    @ManyToOne
    @JoinColumn(name="cid")
    private Category category;

    String cover;
    String title;
    String author;
    String date;
    String press;
    String abs;

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

    public String getAbs() {
        return abs;
    }

    public void setAbs(String abs) {
        this.abs = abs;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCover() {
        return cover;
    }

    public void setCover(String cover) {
        this.cover = cover;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}


2.dao layer

We need to add a BookDAO, a CategoryDAO.

BookDAO:

package com.evan.wj.dao;

import com.evan.wj.pojo.Book;
import com.evan.wj.pojo.Category;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface BookDAO extends JpaRepository<Book,Integer> {
    List<Book> findAllByCategory(Category category);
    List<Book> findAllByTitleLikeOrAuthorLike(String keyword1, String keyword2);
}

Here continuation of the previous JPA wording, findAllByCategory()has been able to achieve, because the following note in the Book class:

    @ManyToOne
    @JoinColumn(name="cid")
    private Category category;

It is actually the id attribute category object as cid conducted inquiries.

CategoryDAO:

package com.evan.wj.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.evan.wj.pojo.Category;

public interface CategoryDAO extends JpaRepository<Category, Integer> {

}

This method does not require additional construction of DAO, JPA default method provides sufficient.

3.Service layer

CategoryService:

package com.evan.wj.service;

import com.evan.wj.dao.CategoryDAO;
import com.evan.wj.pojo.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CategoryService {
    @Autowired
    CategoryDAO categoryDAO;

    public List<Category> list() {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return categoryDAO.findAll(sort);
    }

    public Category get(int id) {
        Category c= categoryDAO.findById(id).orElse(null);
        return c;
    }
}

Here to do a sort and conditional on the results of the query.

BookService:

package com.evan.wj.service;

import com.evan.wj.dao.BookDAO;
import com.evan.wj.pojo.Book;
import com.evan.wj.pojo.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {
    @Autowired
    BookDAO bookDAO;
    @Autowired
    CategoryService categoryService;

    public List<Book> list() {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return bookDAO.findAll(sort);
    }

    public void addOrUpdate(Book book) {
        bookDAO.save(book);
    }

    public void deleteById(int id) {
        bookDAO.deleteById(id);
    }

    public List<Book> listByCategory(int cid) {
        Category category = categoryService.get(cid);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return bookDAO.findAllByCategory(category);
    }
}

The Service provides four functions, which are found all the books, add or update books, remove books by id and detected by the classification of books.

Here note save()method role is, when the main key update data exists, the data is inserted when no primary key exists.

This is the core business logic.

4.Controller layer

In the Controller layer where we need to continue to write the API.

package com.evan.wj.controller;

import com.evan.wj.pojo.Book;
import com.evan.wj.service.BookService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class LibraryController {
    @Autowired
    BookService bookService;

    @GetMapping("/api/books")
    public List<Book> list() throws Exception {
        return bookService.list();
    }

    @PostMapping("/api/books")
    public Book addOrUpdate(@RequestBody Book book) throws Exception {
        bookService.addOrUpdate(book);
        return book;
    }

    @PostMapping("/api/delete")
    public void delete(@RequestBody Book book) throws Exception {
        bookService.deleteById(book.getId());
    }
    

    @GetMapping("/api/categories/{cid}/books")
    public List<Book> listByCategory(@PathVariable("cid") int cid) throws Exception {
        if (0 != cid) {
            return bookService.listByCategory(cid);
        } else {
            return list();
        }
    }
}

5. The test interface

Run the project to test the function.

The first is a query for all books, visit http://localhost:8443/api/booksthe following results:
Here Insert Picture Description
Nima good intensive, these are all one by one I recorded. . .

Then test classification, access http://localhost:8443/api/categories/1/books, view all categories id is 1, that is classified as a book, "Literature", the results are as follows:
Here Insert Picture Description
increase or modify the test in conjunction with the front, where I did not speak, would let us look at the effect:
Here Insert Picture Description
my design is to click cover is modified, click the plus icon to increase. In the lower right corner of the card book has a recycling bin icon to delete. I will not delete a test, recorded a long time to delete a pity.

Haha I used to always put the lower right corner of the picture automatically add watermark to be deleted, and now have a custom domain name put up a feeling also, really really fragrant incense. Welcome everyone by https://learner.blog.csdn.net visit my blog domain name, and although there is no use.

Third, the next step

Next plans to explain the realization by keyword query and author of books and picture upload interface, then the front page perfect sound, this tutorial can almost ending it.

Write off for so long, I did not expect, when develop their own sense of writing a tutorial is to copy and paste to write a comment, but truly engage them in particular, consumption of energy, and I'm from a good developer there is a great distance, to make things will be a lot of shortcomings, but fortunately this process, I have a lot of harvest. There are big brother said, you look at the past feel very sucker, just shows your progress.

Prior also said that recently doing backstage management system, which is a common thing in the future Vue3.0 I put out that's rewrite of the front end and then added to the project inside. But I'm going to write an article only to introduce the core features and ideas to achieve, do not dare to stand flag tutorial. . . The project will still complete uploaded on GitHub, that time can be downloaded from interested students.

Guess you like

Origin blog.csdn.net/Neuf_Soleil/article/details/92413933
Recommended