前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结

作者头像
不愿意做鱼的小鲸鱼
发布2022-09-26 18:10:11
3450
发布2022-09-26 18:10:11
举报
文章被收录于专栏:web全栈

什么是MyBatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 mybatis plus 官网:https://baomidou.com/ 使用前可以安装 MybatisX 插件提升开发效率。

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

MyBatis-Plus基本特性

自动配置 * MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对mybatis-plus的定制 * SqlSessionFactory 自动配置好。底层是容器中默认的数据源 * mapperLocations 自动配置好的。有默认值。classpath*:/mapper/**/*.xml;任意包的类路径下的所有* mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件,放在 mapper下 * 容器中也自动配置好了 SqlSessionTemplate * @Mapper 标注的接口也会被自动扫描;建议直接 @MapperScan("cn.kt.xxxx.mapper")批量扫描就行

优点:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

缺点:

  • 只支持单表的CRUD构造器操作,如果业务复杂,涉及多表联合查询,级联等操作,还是需要像MyBatis一样手动配置。
  • 只能算是Mybatis的升级版,很多其他工具的整合都是默认使用Spring Data JPA,看公司的使用习惯吧。

框架结构

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

整合和使用MyBatis-Plus

1. 建测试表

现有在 ceshi 的数据库下建一张 User 表,其表结构如下:

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

数据库脚本如下:

代码语言:javascript
复制
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(11) NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `createtime` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP,
  `updatetime` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'Jone', 18, 'test1@baomidou.com', '2021-08-17 09:45:31', '2021-08-17 09:45:31');
INSERT INTO `user` VALUES (2, 'Jack', 20, 'test2@baomidou.com', '2021-08-17 09:45:31', '2021-08-17 09:45:31');
INSERT INTO `user` VALUES (3, 'Tom', 28, 'test3@baomidou.com', '2021-08-17 09:45:31', '2021-08-17 09:45:31');
INSERT INTO `user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com', '2021-08-17 09:45:31', '2021-08-17 09:45:31');
INSERT INTO `user` VALUES (5, 'Billie', 24, 'test5@qq.com', '2021-08-17 09:45:31', '2021-08-17 10:32:03');
INSERT INTO `user` VALUES (13, '如我西沉', 36, '2222222@qq.com', '2021-08-17 10:04:54', '2021-08-17 11:24:48');

2. 新建springboot项目、导入相关依赖

测试项目目录结构如下

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

相关依赖

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.kt</groupId>
    <artifactId>mybatisplus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisplus</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

说明:我们使用mybatis-plus可以节省我们大量的代码,尽量不要同时导入mybatis和mybatis-plus! 版本的差异!

3. 配置文件application.yml

代码语言:javascript
复制
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

#配置日志,我们所用的sql现在是不可见的,我们希望知道他是怎么执行的,所以我们必须要查看日志!
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4. 配置分页插件和自动化填充时间

MybatisPlusInterceptor:配置mybatis-plus的分页插件 新建 /config/MyBatisConfig.java

代码语言:javascript
复制
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;
/**
 * @author tao
 * @date 2021-08-16 23:11
 * 概要: 配置mybatis-plus的分页插件
 */
@Configuration
public class MyBatisConfig {
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join

        //这是分页拦截器
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOverflow(true);
        paginationInnerInterceptor.setMaxLimit(500L);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);

        return mybatisPlusInterceptor;
    }
}

MetaObjectHandler:自动化填充创建时间、修改时间 创建时间、修改时间!这些个操作一般都是自动化完成,我们不希望手动更新!

方式一:数据库级别 (工作中不允许)

​在表中新增字段 create_time 、update_time,设为默认CURRENT_TIMESIAMP

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

方式二:代码级别 ​在表中新增字段 createtime 、updatetime: 新建 /config/MyMetaObjectHandler.java

代码语言:javascript
复制
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * Created by tao.
 * Date: 2021/8/17 9:53
 * 描述: 自动化填充创建时间、修改时间
 */
@Configuration
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createtime",new Date(),metaObject);
        this.setFieldValByName("updatetime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updatetime",new Date(),metaObject);
    }
}

5. 新建实体类

新建 /domain/User.java

代码语言:javascript
复制
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

import java.util.Date;

/**
 * @author tao
 * @date 2021-08-16 22:03
 * 概要:
 */
@Data
@TableName("user")
public class User {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    //创建时间,插入数据时操作
    @TableField(fill = FieldFill.INSERT)
    private Date createtime;
    //更新时间,插入和更新是操作
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updatetime;

    public User(String name, Integer age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public User() {
    }
}

说明: 主键生成策略:数据库插入的id为全局默认的id(ID_WORKER),我们需要配置主键自增,在实体类字段上添加注解: @TableId(type =IdType.AUTO),数据库字段一定要是自增的。

代码语言:javascript
复制
AUTO(0),   //数据可id自增
NONE(1),   //未设置主键
INPUT(2),   //手动输入
ID_WORKER(3), //默认的全局唯一id
UUID(4),  //全局唯一id uuid
ID_WORKER_STR(5); // ID_WORKEK 字符串表示法
 ```
 如果主键没有设置Id自增,则mybatis-plus默认使用雪花算法生成Id.
 >雪花算法:
SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的。
这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。

### 6. 编写dao层
使用mybatis-plus后,只需要编写一个接口继承 BaseMapper,就可以实现基本的CRUD操作。
新建 /mapper/UserMapper.java
```java
import cn.kt.mybatisplus.domain.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * @author tao
 * @date 2021-08-16 22:04
 * 概要:
 */
public interface UserMapper extends BaseMapper<User> {
}

7. 编写测试方法

主要测试

代码语言:javascript
复制
* 根据Id查询
* 查询全部
* 增加一条数据
* 修改一条数据
* 根据Id删除一条数据
* 分页查询
* 根据某个字段条件查询
* 查询name不为null的用户,并且邮箱不为null的永不,年龄大于等于35的用户
* 查询年龄在10~30岁之间的用户
* 模糊查询
* 子sql查询
* 询排序:通过id进行排序

测试代码如下

代码语言:javascript
复制
import cn.kt.mybatisplus.domain.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

/**
 * @author tao
 * @date 2021-08-16 22:14
 * 概要:
 */
@SpringBootTest
class UserMapperTest {
    @Autowired
    UserMapper userMapper;

    //根据Id查询
    @Test
    void findById() {
        User user = userMapper.selectById(1L);
        System.out.println(user.getName() + "---" + user.getEmail());

    }

    //查询全部
    @Test
    void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }

    //增加一条数据
    @Test
    void testSave() {
        User nick = new User("Nick", 21, "12055@qq.com");
        userMapper.insert(nick);
    }

    //修改一条数据
    @Test
    void testUpdate() {
        User nick = new User("如我西沉", 21, "12055@qq.com");
        nick.setId(13L);
        userMapper.updateById(nick);
    }

    //根据Id删除一条数据
    @Test
    void testDelete() {
        userMapper.deleteById(1L);
    }

    //分页查询
    @Test
    void findByPage() {
        Page<User> page = new Page<>(1, 3);
        Page<User> userListPage = userMapper.selectPage(page, null);
        System.out.println("当前页号:" + userListPage.getCurrent());
        System.out.println("每页多少条数据:" + userListPage.getSize());
        System.out.println("有多少页:" + userListPage.getPages());
        System.out.println("有多少条记录:" + userListPage.getTotal());
        System.out.println("=========当前页的数据=========");
        userListPage.getRecords().forEach(System.out::println);
    }

    //根据某个字段条件查询
    @Test
    void findByName() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "Jack");
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }

    // 查询name不为null的用户,并且邮箱不为null的永不,年龄大于等于35的用户
    @Test
    void findByAgeLessThan() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("name");
        wrapper.isNotNull("email");
        wrapper.ge("age", 35);
        userMapper.selectList(wrapper).forEach(System.out::println);
    }


        // 查询年龄在10~30岁之间的用户
    @Test
    void findByAgeBetween() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age", 20, 30);
        Integer count = userMapper.selectCount(wrapper);//查询结果数
        System.out.println(count);
    }

    //模糊查询
    @Test
    void findByLink() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        wrapper.notLike("name", "ll");//相当于NOT LIKE '%Z%'
        wrapper.likeLeft("email", "@qq.com");//相当于LIKE '%@qq.com'
        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);//查询结果数
        maps.forEach(System.out::println);
    }

    //子查询
    @Test
    void findByWrapperId() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.inSql("id", "select id from user where id<4");
        List<User> users = userMapper.selectList(wrapper);
        System.out.println("===================================");
        users.forEach(System.out::println);
        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
        System.out.println("===================================");

    }

    //查询排序:通过id进行排序
    @Test
    void findByIdOrderByIdAsc() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("age");
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

}

全部测试成功,测试结果如下:

Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客
Spring学习笔记(二十七)——springboot集成MyBatis-Plus学习总结-左眼会陪右眼哭の博客

8. Service层的简化操作

mybatis-plus在service层也做了相应的简化操作:自动化配置单表的CRUD,在service层也可以不写代码,但是如果需要逻辑操作,则需要自己重写接口。 * UserService接口继承 mybatis-plus的IService接口 * 在UserServiceImpl实现类中继承ServiceImpl,并且配置相应的mapper和实体类则可以让Service也具有相应的CRUD功能。

UserService.java

代码语言:javascript
复制
import cn.kt.mybatisplus.domain.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 *  Service 的CRUD也不用写了
 */
public interface UserService extends IService<User> {
}

UserServiceImpl.java

代码语言:javascript
复制
import cn.kt.mybatisplus.domain.User;
import cn.kt.mybatisplus.mapper.UserMapper;
import cn.kt.mybatisplus.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * @author tao
 * @date 2021-08-16 22:33
 * 概要:
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

测试代码如下

代码语言:javascript
复制
import cn.kt.mybatisplus.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * Created by tao.
 * Date: 2021/8/17 11:10
 * 描述:
 */
@SpringBootTest
class UserServiceTest {

    @Autowired
    UserService userService;

    @Test
    void findAll() {
        List<User> list = userService.list();
        list.forEach(System.out::println);
    }

    @Test
    void findOne() {
        User user = userService.getById(13L);
        System.out.println(user);
    }

    @Test
    void save() {
        User nick = new User("Nick", 33, "111111@qq.com");
        userService.save(nick);
    }

    @Test
    void update() {
        User user = userService.getById(13L);
        user.setEmail("2222222@qq.com");
        userService.updateById(user);
    }

    @Test
    void delete() {
        boolean isDelete = userService.removeById(14L);
        System.out.println(isDelete);
    }
}

总结

mybatis plus极大的增强了开发效率,在某些复杂的SQL操作中,也可以和mybatis一样,灵活的使用配置xml或者使用注解。具体详情可以参考我之前的文章:MyBatis多表查询详解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是MyBatis-Plus
  • MyBatis-Plus基本特性
  • 整合和使用MyBatis-Plus
    • 1. 建测试表
      • 2. 新建springboot项目、导入相关依赖
        • 3. 配置文件application.yml
          • 4. 配置分页插件和自动化填充时间
            • 5. 新建实体类
              • 7. 编写测试方法
                • 8. Service层的简化操作
                • 总结
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档