SSMP integration case: addition, deletion, search and modification based on book information

Integration case based on SSMP

I Implementation case scheme analysis

  • Case making process
    Basic CRUD function
    Call the page and make all functions after confirming asynchronous submission
    Add paging function and query function

II Create backend project environment

2.1 creating modules

  • Create module
    First, add web - "Spring Web" and SQL - "MySql Driver
    Refresh maven after each module is created
  • Modify pom:
    Delete name and description
    Add pom dependencies: mybatis plus, druid
		<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency> <groupId>com.alibaba</groupId>
            <artifactId>druid-plus-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
  • Set port to 80: add application YML file: server: port: 80

2.2 physical layer

  • Add table:

  • Add entity class: domian Book. class
    • Simplify pojo development with lombok
      • lombok: an entity class library that provides annotations to simplify pojo development
      • lombok uses:
        1. Import lombok dependent coordinates
        <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
        2. Add annotation on entity class
        @Getter, @ Setter, @ AllArgsConstructor (parametric construction), @ NoConstructor (nonparametric construction)
        @Data (provides all methods except construction methods, such as get/set, toString, hashCode, quals, etc.)
        3. bug1: (you need to add lombok plug-in for idea to work)
    • Book.class
@Data
public class Book {
    private Integer id;
    private String name;
    private String type;
    private String description;
    
}

2.3 data layer

Data layer development: (technical implementation scheme: mp, druid)

1. Configure application yml

  • yaml configuration information:
    bug1: when the file is garbled with comments, the project will not run and needs to be set to utf-8
    bug2: put jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC wrote it wrong
# Server port number
server:
  port: 80
# Data source information
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/ssm_db
      username: root
      password: 123456

# Configuration information of mp
mybatis-plus:
  global-config:
    db-config:
      # Automatically match database table TBL for BookMapper_ book.  That is, xxmapper - > TBL_ xxx
      table-prefix: tbl_
      # When the primary key id in the table increases automatically, it needs to be set
      id-type: auto
  # Load log
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2. Data layer interface: mapper BookMapper

  • 1. Inherit BaseMapper and add generic
  • 2. Add the annotation @ Mapper for the modified class, which can be loaded into the spring container
  • 3. Table connecting database for entity
    • Method 1: the table prefix: tbl_5;specified in the yml file: Automatically match database table TBL for BookMapper_ Class name: xxx (lowercase)
    • Method 2: add annotation * * @ TableName("tbl_book") on the Book entity class**

code:

package com.fairy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fairy.domian.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookMapper extends BaseMapper<Book> {
}

3. Test: add a test class BookMapperTest to test the data layer method

  • Location: under the package and its sub packages of ssmpapplication
  • Note: the annotation @ SpringBootTest needs to be added so that the method can be executed when the project runs
    • Small bug: there is a red wavy line under the member variable bookMapper of the test class in idea, but it works normally-
Function: print log
  • Add yml configuration information
Function: paging function
  • a. Encapsulating paging data with IPage

  • b. Add mybatisplus paging interceptor to realize the function

  • c. Execute sql statements with mp log lookup

code:
@SpringBootTest
public class BookMapperTestCase {

    @Autowired
    private BookMapper bookMapper;

    @Test
    //Add: the id cannot be specified because it is a self incrementing primary key
    void testInser(){
        Book book = new Book();
        //book.setId(19);
        book.setName("sleep");
        book.setType("shenghuo");
        book.setDescription("I'm going to bed");
        bookMapper.insert(book);
    }

    @Test
    //Delete: delete according to id
    void testDelete(){
        bookMapper.deleteById(3);
    }

    @Test
        //Change: modify the book with id 1
    void testUpdate(){
        Book book= new Book();
        book.setId(1);
        book.setName("Sadness");
        book.setType("BUg ah");
        book.setDescription("All night bug five five five five");
        bookMapper.updateById(book);

    }

    @Test
    //Query: find the book with id=1
    void testGetById(){
        bookMapper.selectById(1);
        System.out.println("nihao");
    }

    @Test
    //Query: selectList: query all book s
    //  You need to fill in the parameter, null is enough
    void testGetAll(){
        List<Book> books = bookMapper.selectList(null);
    }

    @Test
    void testGetPage(){
        //Define page object
        IPage page = new Page(1,4);
        //Execute sql statement
        bookMapper.selectPage(page,null);
        System.out.println(page.getCurrent());		//Current page number value
        System.out.println(page.getSize());			//Number of displays per page
        System.out.println(page.getTotal());		//Total data
        System.out.println(page.getPages());		//PageCount 
        System.out.println(page.getRecords());		//Detailed data
    }

    @Test
    //Query by criteria
    void testGetByCondition(){
//        Using QueryWrapper method: (not recommended)
//        QueryWrapper<Book> qw = new QueryWrapper<>();
//        qw.like("name","Spring");
//        bookMapper.selectList(qw);

        //LambdaQueryWrapper: (recommended)
        String name =null;
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
        lqw.like(name != null,Book::getName,name);	 //condition: name cannot be empty. If it is blank, all book s will be queried
        bookMapper.selectList(lqw);

    }
}

2.4 business layer

1. Business layer interface BookService

public interface BookService {
    Boolean save(Book book);
    Boolean update(Book book);
    Boolean delete(Integer id);
    Book getById(Integer id);
    List<Book> getAll();
    IPage<Book> getPage(int currentPage,int pageSize);
}

2. Business layer implementation class BookServiceImpl

  • Add this class to the container: @ Service
  • The reason why XXX > 0 is returned is to observe whether the operation layer is completed
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Override
    public Boolean save(Book book) {

        return bookDao.insert(book) > 0;
    }

    @Override
    public Boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public Boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page = new Page(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }
}

3. Test: test the business layer method

@SpringBootTest
public class BookServiceTest {
    @Autowired
    private IBookService bookService;

    @Test
    void testGetById(){
        System.out.println(bookService.getById(4));
    }
    @Test
    void testSave(){
        Book book = new Book();
        book.setType("Test data 123");
        book.setName("Test data 123");
        book.setDescription("Test data 123");
        bookService.save(book);
    }
    @Test
    void testUpdate(){
        Book book = new Book();
        book.setId(17);
        book.setType("-----------------");
        book.setName("Test data 123");
        book.setDescription("Test data 123");
        bookService.updateById(book);
    }
    @Test
    void testDelete(){
        bookService.removeById(18);
    }

    @Test
    void testGetAll(){
        bookService.list();
    }

    @Test
    void testGetPage(){
        IPage<Book> page = new Page<Book>(2,5);
        bookService.page(page);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());
        System.out.println(page.getTotal());
        System.out.println(page.getPages());
        System.out.println(page.getRecords());
    }

}

4. Use MP to quickly develop business layer

  • 1.IBookService interface inherits IService interface
public interface IBookService extends IService<Book> {
    //Add non general operation API interface
}
  • 2.serviceImpl inherits ServiceImpl and implements IBookService
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;
	//Add non generic operation API
}
  • Basic addition, deletion, modification and query have been realized. If you feel that the functions provided by MP are not enough to support your use needs, you can define a new API interface on the basis of the original interface. If you want to override, add @ override

  • 3. Testing
@SpringBootTest
public class BookServiceTest {
    @Autowired
    private IBookService bookService;

    @Test
        //Add: the id cannot be specified because it is a self incrementing primary key
    void testInser(){
        Book book = new Book();
        //book.setId(19);
        book.setName("sleep");
        book.setType("shenghuo");
        book.setDescription("I'm going to bed");
        bookService.save(book);
    }

    @Test
        //Delete: delete according to id
    void testDelete(){
        bookService.removeById(3);
    }

    @Test
        //Modified id: book 1
    void testUpdate(){
        Book book= new Book();
        book.setId(1);
        book.setName("Sadness");
        book.setType("BUg ah");
        book.setDescription("All night bug five five five five");
        bookService.update(book,null);

    }

    @Test
        //Query: find the book with id=1
    void testGetById(){
        bookService.getById(1);
        System.out.println("nihao");
    }

    @Test
    void testGetAll(){
        List<Book> books = bookService.list();
    }

    @Test
    void testGetPage(){
        IPage<Book> page = new Page<Book>(2,2);
        bookService.page(page);
    }

}

2.5 presentation layer

Development of presentation layer interface based on Restful

When using Postman test

  • Submission type
typeannotationWith referenceRequest address
query@GetMapping@GetMapping("{id}"),@GetMapping("{currentPage}/{pageSize}")GET http://localhost/books/2/3
add to@PostMapping@PostMappingPOST http://localhost/books
modify@PutMapping@PutMappingPUT http://localhost/books
delete@DeleteMapping@DeleteMapping("{id}")DELETE http://localhost/books
  • Implementation layer method parameters
    • Transfer path variable: public Boolean delete(@PathVariable Integer id)
    • Transfer json data: public Boolean save (@ requestbody book)
@RestController
@RequestMapping("/books")
public class BookController2 {

    @Autowired
    private IBookService bookService;

    @GetMapping
    public List<Book> getAll(){
        return bookService.list();
    }

    @PostMapping
    public Boolean save(@RequestBody Book book){
        return bookService.save(book);
    }

    @PutMapping
    public Boolean update(@RequestBody Book book){
        return bookService.modify(book);
    }

    @DeleteMapping("{id}")
    public Boolean delete(@PathVariable Integer id){
        return bookService.delete(id);
    }

    @GetMapping("{id}")
    public Book getById(@PathVariable Integer id){
        return bookService.getById(id);
    }

    @GetMapping("{currentPage}/{pageSize}")
    public IPage<Book> getPage(@PathVariable int currentPage,@PathVariable int pageSize){
        return bookService.getPage(currentPage,pageSize, null);
    }
}
  • New: add json object data to the body without adding id

  • Delete: Add / id directly

  • Modify: add id attribute in json

  • Paging query

Presentation layer message consistency processing

  • Design the model class of the results returned by the presentation layer, which is used to unify the data format between the back-end and the front-end, also known as the front-end and back-end data protocol
  • Define the model class (in the controller.utils package)
@Data
public class R {
    private Boolean flag;//Indicates whether the test was successful
    private Object data;//Represents the encapsulated operation data after the test
    
 	public R(List<Book> list) {
    }
	//The single parameter construction method is applicable to the service method with the return value of boolean. Such as removeById, save
    public R(boolean flag) {
        this.flag = flag;
    }
	//The two parameter construction method is applicable to service methods with return values of other types, such as list and getById. The last one is always true
    public R(boolean flag, Object data) {
        this.flag = flag;
        this.data = data;
    }
    //get/set method
}
  • Modify the return values of all methods in the controller to R-type
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private IBookService bookService;

    @GetMapping
    public R getAll(){
        return new R(true,bookService.list());
    }

    @PostMapping
    public R save(@RequestBody Book book){
        return new R(bookService.save(book));
    }

    @PutMapping
    public R update(@RequestBody Book book){
        return new R(bookService.update(book,null));
    }

    @DeleteMapping("{id}")
    public R delete(@PathVariable Integer id){
        return new R(bookService.removeById(id));
    }

    @GetMapping("{id}")
    public R getById(@PathVariable Integer id){
        return new R(true,bookService.getById(id));
    }

    @GetMapping("{currentPage}/{pageSize}")
    public R getPage(@PathVariable int currentPage, @PathVariable int pageSize){
        return new R(true,bookService.getPage(currentPage,pageSize));
    }
}
  • The data format returned after the request becomes new json data
{
    "flag": true,
    "data":{
        "id": 1,
        "type": "Computer theory",
        "name": "Spring Actual combat version 5",
        "description": "Spring Classic tutorial for getting started"
    }
}

III Combine the front and rear ends

3.1 preparation

  • Static resources are placed in the static directory under resources (it is recommended to clean the project's LifeCycle to avoid cache problems.)

  • Before the specific function development, test the connectivity first, send asynchronous submission (axios) through the page, and then carry out further function development after passing the debugging

3.2 realize the function of html page

1. Display main page data

  • Display data on the main page: http://localhost/pages/books.html
    • 1. Hook function: created() {}
    • 2.axios sends asynchronous request
      • axios.get("/books"): that is, access localhost/books, that is, execute the controller method corresponding to @ GetMapping, that is, getAll()
      • axios.get("/books").then(): execute the inner parenthesis of then after sending the request
      • res.data: the return value of the controller method, that is, R-type data. Here corresponds to the return value of getAll()
        res.data.data: the return value of the service method, which corresponds to bookservice List() return value
    • 3.vue's two-way data binding can load data into html pages: this dataList=res.data. data;
        //1. Hook function, which is automatically executed after VUE object initialization
        created() {
            this.getAll();
        },

        methods: {
            //Display list
            getAll() {
                //axios sends asynchronous requests and then executes them in parentheses
                axios.get("/books").then((res)=>{
                	//vue's two-way data binding can load data into html pages
                    this.dataList=res.data.data;
                })
            },

2. Add new functions

1. Display the newly added elastic layer

            //Reset Form 
            resetForm() {
                this.formData = {};
            },
            //The add window pops up
            handleCreate() {
                //The form should be reset before each window is displayed, otherwise the last added data will be retained
                this.resetForm();
                //Display window
                this.dialogFormVisible = true;
            },

2. Add the submit function in the new bomb layer

            //Submit the form of the new window
            handleAdd () {
                //Send asynchronous request
                axios.post("/books",this.formData).then((res)=>{
                    //Display page
                    if(res.data.flag){
                        //If the addition is successful, 1 Close bomb layer 2 Display successful
                        this.dialogFormVisible = false;
                        this.$message.success("Added successfully");
                    }else {
                        //Add failed
                        this.$message.error("Add failed");
                    }
                }).finally(()=>{
                    //Data must be reloaded regardless of success or failure
                    this.getAll();
                })
            },

            //cancel
            cancel(){
                this.dialogFormVisible = false;
                this.$message.info("Cancel operation");
            },

3. Add delete function

  1. In the request mode, Delete is used to call the corresponding operation in the background
  2. The deletion operation needs to pass the ID value corresponding to the current row data to the background, that is, row id
  3. After the deletion operation, the page loading data is refreshed dynamically
  4. Display corresponding prompt information according to different operation results
  5. Pop up a prompt box before deleting to avoid misoperation
			 // delete
            handleDelete(row) {
                //1. Pop up prompt box
                this.$confirm("This operation will permanently delete the current data. Do you want to continue?","Tips",{
                    type:'info'
                }).then(()=>{
                    //2. Delete business
                    axios.delete("/books/"+row.id).then((res)=>{
                        if(res.data.flag){
                            this.$message.success("Deleted successfully");
                        }else{
                            this.$message.error("Delete failed");
                        }
                    }).finally(()=>{
                    	//Overload list
                        this.getAll();
                    });
                }).catch(()=>{
                    //3. Cancel deletion
                    this.$message.info("Cancel delete operation");
                });
            },

Note: when there is only one piece of data on the last page, a BUG will appear in the deletion operation. The last page has no data but is displayed independently. The background function maintenance of the paging query function is carried out. If the current page number value is greater than the maximum page number value, the query will be executed again. In fact, there are many solutions to this problem. Here is a relatively simple solution

@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
    IPage<Book> page = bookService.getPage(currentPage, pageSize);
    //If the current page number value is greater than the total page number value, re execute the query operation and use the maximum page number value as the current page number value
    if( currentPage > page.getPages()){
        page = bookService.getPage((int)page.getPages(), pageSize);
    }
    return new R(true, page);
}

4. Modify function

1. The edit page pops up

           //The edit window pops up
            handleUpdate(row) {
                axios.get("/books/"+row.id).then((res)=>{
                    if(res.data.flag){
                        //Display the bomb layer and load data
                        this.formData = res.data.data;
                        this.dialogFormVisible4Edit = true;
                    }else{
                        this.$message.error("Data synchronization failed, automatic refresh");
                    }
                });

            },

2. Modification
formData is bound in the model property

//modify
handleEdit() {
    axios.put("/books",this.formData).then((res)=>{
        //If the operation is successful, close the elastic layer and refresh the page
        if(res.data.flag){
            this.dialogFormVisible4Edit = false;
            this.$message.success("Modified successfully");
        }else {
            this.$message.error("Modification failed, please try again");
        }
    }).finally(()=>{
        this.getAll();
    });
},

5. Exception handling function

First, add a message field to the current data result to be compatible with the operation messages appearing in the background

@Data
public class R{
    private Boolean flag;
    private Object data;
    private String msg;		//Used to encapsulate messages

	//The controller method with the return value of boolean is used
    public R(boolean flag) {
        this.flag = flag;
    }
    
    //The return value is used by the contoller method of entity object or other data
    public R(boolean flag, Object data) {
        this.flag = flag;
        this.data = data;
    }
   
    public R(boolean flag,Obiect data,String msg) {
        this.flag = flag;
        this.data = data;
        this.msg = msg;
    }
}

The background code should also be processed according to the situation. At present, it is a simulated error

@PostMapping
public R save(@RequestBody Book book) throws IOException {
    Boolean flag = bookService.insert(book);
    return new R(flag , flag ? "Added successfully^_^" : "Add failed-_-!");
}

Then do unified exception handling in the presentation layer, and use the exception handler provided by spring MVC to do unified exception handling. In the controller Utils package

@RestControllerAdvice
public class ProjectExceptionAdvice {
    @ExceptionHandler(Exception.class)
    public R doOtherException(Exception ex){
        //Log
        //Send message to O & M
        //Send e-mail to developers and ex objects to developers
        ex.printStackTrace();
        return new R(false,null,"System error, please try again later!");
    }
}

After getting the data on the page, first determine whether there is a message delivered from the background. The flag is whether the current operation is successful. If the operation result is false, read the message delivered from the background

//add to
handleAdd () {
	//Send ajax request
    axios.post("/books",this.formData).then((res)=>{
        //If the operation is successful, close the bomb layer and display the data
        if(res.data.flag){
            this.dialogFormVisible = false;
            this.$message.success(res.data.msg);
        }else {
        	//msg messages are delivered from the background, not fixed content
            this.$message.error(res.data.msg);			
        }
    }).finally(()=>{
        this.getAll();
    });
},

6. Paging function

1. Display paging function

  • 1.1 encapsulate request data: encapsulate the data model corresponding to paging in order to cooperate with paging components
<!--Paging component-->
<div class="pagination-container">
    <el-pagination
		class="pagiantion"
		@current-change="handleCurrentChange"
		:current-page="pagination.currentPage"
		:page-size="pagination.pageSize"
		layout="total, prev, pager, next, jumper"
		:total="pagination.total">
    </el-pagination>
</div>
data:{
	pagination: {	
		//Paging related model data. initial condition 
		currentPage: 1,	//Current page number
		pageSize:10,	//Number of records displayed per page
		total:0,		//Total records
	}
},
  • 1.2 send request: modify all functions of query to page query, and transfer page information parameters through path variables
getAll() {
    axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize).then((res) => {
    });
},
  • 1.3 execution: the corresponding paging function is provided in the background
@GetMapping("/{currentPage}/{pageSize}")
public R getAll(@PathVariable Integer currentPage,@PathVariable Integer pageSize){
    IPage<Book> pageBook = bookService.getPage(currentPage, pageSize);
    return new R(null != pageBook ,pageBook);
}
  • 4.1 data binding: read the data according to the model and return to the corresponding page
getAll() {
    axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize).then((res) => {
        this.pagination.total = res.data.data.total;
        this.pagination.currentPage = res.data.data.current;
        this.pagination.pagesize = res.data.data.size;
        this.dataList = res.data.data.records;
    });
},

2. Call the current paging operation for the operation button setting of switching page number

//Switch page number
handleCurrentChange(currentPage) {
    this.pagination.currentPage = currentPage;
    this.getAll();
},

7. Condition query

Conditional query can be understood as: when paging query, in addition to carrying paging data, query with several more data. These multi band data are query criteria.

  • Background query function: the query is changed from no conditions to conditions. Anyway, when there are no conditions, the query condition object uses null. Now replace it with specific conditions, which makes little difference

  • Query results: with or without conditions, there are only differences in the quantity of data, and others are different. This can be ignored

  • When the page sends the request, the two paging data still use the path variable, and other conditions are passed in the form of dynamic assembly url parameters

1. Page encapsulation query criteria field

pagination: {		
//Paging related model data
 currentPage: 1,		//Current page number
 pageSize:10,		//Number of records displayed per page
 total:0,			//Total records
 name: "",
 type: "",
 description: ""
},

Add the data model binding name corresponding to the query criteria field on the page

<div class="filter-container">
    <el-input placeholder="Book category" v-model="pagination.type" class="filter-item"/>
    <el-input placeholder="Book name" v-model="pagination.name" class="filter-item"/>
    <el-input placeholder="Book description" v-model="pagination.description" class="filter-item"/>
    <el-button @click="getAll()" class="dalfBut">query</el-button>
    <el-button type="primary" class="butT" @click="handleCreate()">newly build</el-button>
</div>

2. Send request: organize the query conditions into url parameters and add them to the request url address: splice the conditions into param.

getAll() {
    //1. Obtain query conditions and splice query conditions
    param = "?name="+this.pagination.name;
    param += "&type="+this.pagination.type;
    param += "&description="+this.pagination.description;
    console.log("-----------------"+ param);
    axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res) => {
        this.dataList = res.data.data.records;
    });
},

3. Execution: define entity class encapsulation query conditions in the background code: the param in the url address is automatically encapsulated into a book instance object and passed into the formal parameter

@GetMapping("{currentPage}/{pageSize}")
public R getAll(@PathVariable int currentPage,@PathVariable int pageSize,Book book) {
    System.out.println("parameter=====>"+book);
    IPage<Book> pageBook = bookService.getPage(currentPage,pageSize);
    return new R(null != pageBook ,pageBook);
}

Modify the corresponding business layer interface and implementation class

public interface IBookService extends IService<Book> {
    IPage<Book> getPage(Integer currentPage,Integer pageSize,Book queryBook);
}
@Service
public class BookServiceImpl2 extends ServiceImpl<BookDao,Book> implements IBookService {
    public IPage<Book> getPage(Integer currentPage,Integer pageSize,Book queryBook){
        IPage page = new Page(currentPage,pageSize);
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
        lqw.like(Strings.isNotEmpty(queryBook.getName()),Book::getName,queryBook.getName());
        lqw.like(Strings.isNotEmpty(queryBook.getType()),Book::getType,queryBook.getType());
        lqw.like(Strings.isNotEmpty(queryBook.getDescription()),Book::getDescription,queryBook.getDescription());
        return bookDao.selectPage(page,lqw);
    }
}

4. Page echo data

getAll() {
    //1. Obtain query conditions and splice query conditions
    param = "?name="+this.pagination.name;
    param += "&type="+this.pagination.type;
    param += "&description="+this.pagination.description;
    console.log("-----------------"+ param);
    axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res) => {
        this.pagination.total = res.data.data.total;
        this.pagination.currentPage = res.data.data.current;
        this.pagination.pagesize = res.data.data.size;
        this.dataList = res.data.data.records;
    });
},

Keywords: Java Spring Boot intellij-idea

Added by stevepatd on Sat, 12 Feb 2022 10:34:41 +0200