Springboot integrates the use of mybatis-plus and mybatis-plus paging plugins

1. mybatis-plus?

MyBatis-Plus (opens new window) (MP for short) is an enhancement tool for MyBatis (opens new window). On the basis of MyBatis, only enhancements are made without changes, and it was born to simplify development and improve efficiency.

insert image description here

mybatis-plus official website: https://baomidou.com/pages/24112f/

2. Introduce dependencies

Introduce the third-party stater and data source of mybatis-plus:

        <!--    mybatis-plus stater    -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--   druid数据源     -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
        <!--     mysql驱动   -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>

3. Write the configuration file

Configure the relevant configuration of the data source in application.yaml:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/phpdemo?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

4. Write sql table

Write the sql table of the test case:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(0) NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'Jone', 18, '[email protected]');
INSERT INTO `user` VALUES (2, 'Jack', 20, '[email protected]');
INSERT INTO `user` VALUES (3, 'Tom', 28, '[email protected]');
INSERT INTO `user` VALUES (5, 'Billie', 24, '[email protected]');
INSERT INTO `user` VALUES (6, '叶秋', 18, '[email protected]');
INSERT INTO `user` VALUES (7, '张三', 49, '[email protected]');

SET FOREIGN_KEY_CHECKS = 1;

5. mapper layer

5.1 What does mybatis-plus do? And create a mapper interface

Use mybatis-plus to create a mapper interface in springboot, and you can quickly generate common sql by inheriting the baseMapper class (the baseMapper class provides us with very convenient sql, a must for lazy people hahaha)

mapper interface:

package com.robin.boot.mapper;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.robin.boot.bean.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * 使用mapper接口继承BaseMapper的方式,可以快速获得常用的sql
 * 无须编写mapper.xml文件
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    

}

Note that mybatis-plus automatically configures the following for us:

  • MybatisPlusAutoConfiguration configuration class, MybatisPlusProperties configuration item binding. mybatis-plus: xxx is the customization of mybatis-plus
  • SqlSessionFactory is configured automatically. The bottom layer is the default data source in the container
  • mapperLocations is automatically configured. There are default values. classpath*:/mapper/**/*.xml; all xml in any path under all mapper folders under the classpath of any package
    are sql mapping files. It is recommended to put the sql mapping file under the mapper in the future
  • The SqlSessionTemplate is also automatically configured in the container
  • Interfaces marked with @Mapper will also be scanned automatically;

Compared with the integration of mybatis, this time we don't even need to create xml, it has been automatically defaulted.

5.2 baseMapper source code

baseMapper source code:

/*
 * Copyright (c) 2011-2020, baomidou ([email protected]).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.core.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * <p>这个 Mapper 支持 id 泛型</p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> extends Mapper<T> {
    
    

    /**
     * 插入一条记录
     *
     * @param entity 实体对象
     */
    int insert(T entity);

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    int deleteById(Serializable id);

    /**
     * 根据 columnMap 条件,删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,删除记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 删除(根据ID 批量删除)
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * 根据 whereEntity 条件,更新记录
     *
     * @param entity        实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T selectById(Serializable id);

    /**
     * 查询(根据ID 批量查询)
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,查询一条记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>注意: 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

baseMapper provides us with many commonly used sql methods, as long as the interface is inherited through the mapper interface, it can be used "out of the box".

6. service layer and controller layer

6.1 service layer

service layer interface:

package com.robin.boot.service;


import com.baomidou.mybatisplus.extension.service.IService;
import com.robin.boot.bean.User;

public interface UserService extends IService<User> {
    
    

}

serviceImpl implementation class:

package com.robin.boot.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.robin.boot.bean.User;
import com.robin.boot.mapper.UserMapper;
import com.robin.boot.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    

}

6.2 controller layer

Write controller and request mapping processing:

package com.robin.boot.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.robin.boot.bean.User;
import com.robin.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserController {
    
    

    @Autowired
    UserService userService;


    // 分页查询用户
    @GetMapping("/showUser")
    public String dynamic_table(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){
    
    
        // 分页查询
        Page<User> userPage = new Page<>(pn,3);
        // 分页查询结果
        IPage<User> page = userService.page(userPage,null);
        model.addAttribute("users",page);
        return "show";
    }

    // 单个用户删除
    @GetMapping("/user/delete/{id}")
    public String deleteUser(@PathVariable("id") Long id,
                             @RequestParam(value = "pn",defaultValue = "1") Integer pn){
    
    
        userService.removeById(id);
        return "redirect:/showUser?pn="+pn;
    }
}

6.2.1 page object

insert image description here

7. Use of pagination plug-ins

Let's check its official website introduction: https://baomidou.com/pages/2976a3/#mybatisplusinterceptor

MybatisPlusInterceptor is the core plug-in, which currently proxies Executor#query, Executor#update and StatementHandler#prepare methods.

All plug-ins in mybatis-plus are based on the InnerInterceptor interface to implement plug-in functions.
insert image description here
The official pagination plug-in reference configuration file is as follows:

@Configuration
@MapperScan("scan.your.mapper.package")
public class MybatisPlusConfig {
    
    

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
    
    
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

Create a config package for our custom configuration class, using the mybatis-plus plug-in:

package com.robin.boot.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisConfig {
    
    

    /**
     * mybatis-plus 分页插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor paginationInnerInterceptor(){
    
    
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }

}

8. Data display html page

Use thymeleaf template engine to get data and data traversal, and view rendering:

show.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户数据显示页面</title>
    <style>
        table,tr,td{
      
      
            border: 1px solid deepskyblue;
        }
        table{
      
      
            margin: 0 auto;
        }
        h3{
      
      
            text-align: center;
        }
        .recordsBar{
      
      
            text-align: center;
        }
        a{
      
      
            color: black;
        }
        .active>a{
      
      
            color: red;
        }
    </style>
</head>
<body>
    <h3>用户信息</h3>
    <hr>
    <table>
       <tr>
           <td>id</td>
           <td>姓名</td>
           <td>年龄</td>
           <td>邮箱</td>
           <td>操作</td>
       </tr>
        <tr th:each="user:${users.records}">
           <td th:text="${user.id}">xxxx</td>
           <td th:text="${user.name}">xxxx</td>
           <td th:text="${user.age}">xxxx</td>
           <td th:text="${user.email}">xxxx</td>
           <td><a th:href="@{/user/delete/{id}(id=${user.id},pn=${users.current})}">删除</a></td>
        </tr>
    </table>
    <hr>
    <div class="recordsBar">
        <span>当前第 [[${users.current}]] 页</span>
        <span>共 [[${users.pages}]] 页</span>
        <span>总记录数 [[${users.total}]] 条</span>
        <span th:class="${num == users.current ?'active':''}" th:each="num : ${#numbers.sequence(1,users.pages)}">
            <a th:href="@{/showUser(pn=${num})}" th:text="${num}">1</a>
        </span>
    </div>
</body>
</html>

9. Project structure and integration testing

9.1 Project structure

insert image description here

9.2 Running the tests

Access localhost:8080/showUser, page query user home page

insert image description here

Click the page number to jump

insert image description here

Test delete:

insert image description here
After deleting, it is still on the same page

insert image description here

Summarize

mybatis-plus is an enhanced version of the mybatis function. If we use it, we can also introduce the corresponding state. Compared with mybatis, it is more convenient and does not need to specify the configuration of mapper.xml (provided that the mapper interface uses the method of inheriting the baseMapper interface), mybatis- plus provides the baseMapper interface class, we can use our own mapper interface to inherit, and we can quickly write the sql method by ourselves, and the baseMapper interface provides a wealth of methods.

mybatis-plus provides many plug-ins, you can go to its official website to see how to use them.

Guess you like

Origin blog.csdn.net/m0_63622279/article/details/128786711