mybatisplus快速入门保姆级教程

MyBatis-Plus(简称 MP)是一个MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。其突出的特性如下:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,提供了大量的通用的CRUD方法,因此可以省去大量手写sql的语句的工作。

  • 条件构造器:提供了强大的条件构造器,可以构造各种复杂的查询条件,以应对各种复杂查询。

  • 内置分页插件:配置好插件之后,写分页等同于普通 List 查询,无需关注分页逻辑。

下面通过一个简单案例快速熟悉MyBatis Plus的基本使用  

一.首先在数据库中准备一张表

  1. 创建数据库

    在MySQL中创建一个数据库hello_mp

    CREATE DATABASE hello_mp CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

  2. 创建表

    hello-mp库中创建一个表user

    DROP TABLE IF EXISTS user;
    CREATE TABLE user
    (
        id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
        name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
        age INT(11) NULL DEFAULT NULL COMMENT '年龄',
        email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
        PRIMARY KEY (id)
    );

  3. 插入数据

    INSERT INTO user (id, name, age, email) VALUES
    (1, 'Jone', 18, 'test1@baomidou.com'),
    (2, 'Jack', 20, 'test2@baomidou.com'),
    (3, 'Tom', 28, 'test3@baomidou.com'),
    (4, 'Sandy', 21, 'test4@baomidou.com'),
    (5, 'Billie', 24, 'test5@baomidou.com');

二.与SpringBoot集成

Mybatis Plus与SpringBoot的集成十分简单,具体操作如下

  1. 引入Maven 依赖

    提前创建好一个SpringBoot项目,然后在项目中引入MyBatis Plus依赖

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.2</version>
    </dependency>

引入后点击Maven下方的刷新按钮,idea就会自动导入依赖

配置application.yml文件

application配置文件重命名为application.yml

删除文件原有内容,添加以下代码配置数据库连接

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://192.168.10.101:3306/hello_mp?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8v
创建实体类

创建与user表相对应的实体类,如下

@Data
@TableName("user")
public class User {
​
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
​
    @TableField("name")
    private String name;
​
    @TableField("age")
    private Integer age;
​
    @TableField("email")
    private String email;
}

知识点

mybatisplus默认有一套从类名到表名的映射规则

  1. 具体映射方式:
    • 将类名的大写字母转换为小写,并在前面添加下划线。
    • 例如:UserInfo 类会映射到 user_info 表。

但是写上 @TableName会更清晰

实体类中的三个注解的含义如下

  • @TableName:表名注解,用于标识实体类所对应的表

    • value:用于声明表名

  • @TableId:主键注解,用于标识主键字段

    • value:用于声明主键的字段名

    • type:用于声明主键的生成策略,常用的策略有AUTOASSIGN_UUIDINPUT等等

    • AUTO(自动增长):插入新记录时,数据库自动为主键分配一个递增的整数值。适合需要连续、递增ID的场景。

    • ASSIGN_UUID(UUID分配):MyBatis-Plus自动生成一个32位的UUID字符串(不含连字符),适合分布式系统或需要全局唯一ID的场景。

    • INPUT(手动输入):在插入数据时,需要程序自行设置主键的值。

  • @TableField:普通字段注解,用于标识属性所对应的表字段

    • value:用于声明普通字段的字段名

三.通用Mapper

通用Mapper提供了通用的CRUD方法,使用它可以省去大量编写简单重复的SQL语句的工作,具体用法如下

  1. 创建Mapper接口

    创建UserMapper接口,并继承由Mybatis Plus提供的BaseMapper<T>接口,如下

    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }

知识点

若Mapper接口过多,可不用逐一配置@Mapper注解,而使用@MapperScan注解指定包扫描路径进行统一管理,例如

@SpringBootApplication
@MapperScan("com.atguigu.hellomp.mapper")
public class HelloMpApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloMpApplication.class, args);
    }
}

通过下图方式可以快捷创建一个测试类

 

测试通用Mapper

创建userMapperTest测试类型,内容如下

package edu.glut.hello_mp.mapper;

import edu.glut.hello_mp.entity.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;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectList() {
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

    @Test
    public void testSelectById() {
        User user = userMapper.selectById(1);
        System.out.println(user);
    }

    @Test
    public void testInsert() {
        User user = new User();
        user.setName("zhangsan");
        user.setAge(11);
        user.setEmail("test@test.com");
        userMapper.insert(user);
    }

    @Test
    public void testUpdateById() {
        User user = userMapper.selectById(1);
        user.setName("xiaoming");
        userMapper.updateById(user);
    }

    @Test
    public void testDeleteById() {
        userMapper.deleteById(1);
    }
}

知识点:

@SpringBootTest表示这是一个Spring Boot的集成测试类。它会加载完整的应用程序上下文。@Autowired注解自动注入UserMapper接口的实现。 
每个@Test注解标记的方法都是一个独立的测试用例。

Mybatisplus相比起Mybatis要方便许多,只需要调用接口中提供的方法就可以实现CRUD,几乎不需要手动编写SQL语句。

需要确认默认的SQL语句是否正确的时候只需要在application.yml中添加就会在执行方法前打印sql语句

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

四.通用Service

通用Service进一步封装了通用Mapper的CRUD方法,并提供了例如saveOrUpdatesaveBatch等高级方法。Service的方法名和业务名类似,不同于Mapper方法名和mysql查询语句类似。但service就是对BaseMapper中的方法的进一步封装。

  1. 创建Service接口

    创建UserService,内容如下

public interface UserService extends IService<User> {
}

2.创建Service实现类

创建UserServiceImpl,内容如下

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

3.测试通用Service

创建UserServiceImplTest测试类,内容如下

@SpringBootTest
class UserServiceImplTest {


    @Autowired
    private UserService userService;

    @Test
    public void testSaveOrUpdate() {
        User user1 = userService.getById(2);
        user1.setName("xiaohu");

        User user2 = new User();
        user2.setName("lisi");
        user2.setAge(27);
        user2.setEmail("lisi@email.com");
        userService.saveOrUpdate(user1);
        userService.saveOrUpdate(user2);
    }


    @Test
    public void testSaveBatch() {
        User user1 = new User();
        user1.setName("dongdong");
        user1.setAge(49);
        user1.setEmail("dongdong@email.com");

        User user2 = new User();
        user2.setName("nannan");
        user2.setAge(29);
        user2.setEmail("nannan@email.com");

        List<User> users = List.of(user1, user2);
        userService.saveBatch(users);
    }
}
条件构造器

条件构造器用于构造复杂的查询条件,例如获取name='zhangsan'的用户。MyBatis Plus共提供了两类构造器,分别是QueryWrapperUpdateWrapper。其中QueryWrapper主要用于查询、删除操作,UpdateWrapper主要用于更新操作,下面通过几个案例学习条件构造器的基础用法。

  1. 创建WrapperTest测试类,内容如下

    package edu.glut.hello_mp.wrapper;
    
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
    import edu.glut.hello_mp.entity.User;
    import edu.glut.hello_mp.service.UserService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.util.List;
    
    @SpringBootTest
    public class WrapperTest {
    
        @Autowired
        private UserService userService;
    
        @Test
        public void testQueryWrapper() {
    
            //查询name=Tom的所有用户
            QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("name", "Tom");
    
            //查询邮箱域名为baomidou.com的所有用户
            QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.like("email", "baomidou.com");
    
            //查询所有用户信息并按照age字段降序排序
            QueryWrapper<User> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.orderByDesc("age");
            
            //查询age介于[20,30]的所有用户
            QueryWrapper<User> queryWrapper4 = new QueryWrapper<>();
            queryWrapper4.between("age", 20, 30);
            
            //查询age小于20或大于30的用户
            QueryWrapper<User> queryWrapper5 = new QueryWrapper<>();
            queryWrapper5.lt("age", 20).or().gt("age", 30);
    
            //邮箱域名为baomidou.com且年龄小于30或大于40且的用户
            QueryWrapper<User> queryWrapper6 = new QueryWrapper<>();
            queryWrapper6.like("email", "baomidou.com").and(wrapper -> wrapper.lt("age", 30).or().gt("age", 40));
            
            List<User> list = userService.list(queryWrapper6);
            list.forEach(System.out::println);
        }
    
        @Test
        public void testUpdateWrapper() {
    
            //将name=Tom的用户的email改为Tom@baobidou.com
            UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("name", "Tom");
            updateWrapper.set("email", "Tom@baobidou.com");
    
            userService.update(updateWrapper);
        }
    }

    创建LambdaWrapperTest测试类,内容如下

    上述的QueryWrapperUpdateWrapper均有一个Lambda版本,也就是LambdaQueryWrapperLambdaUpdateWrapperLambda版本的优势在于,可以省去字段名的硬编码

    @SpringBootTest
    public class LambdaWrapperTest {
    
        @Autowired
        private UserService userService;
    
        @Test
        public void testLambdaQueryWrapper() {
            //查询name=Tom的所有用户
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getName, "Tom");
    
            List<User> list = userService.list(lambdaQueryWrapper);
            list.forEach(System.out::println);
    
        }
    
        @Test
        public void testLambdaUpdateWrapper() {
            //将name=Tom的用户的邮箱改为Tom@tom.com
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getName, "Tom");
            lambdaUpdateWrapper.set(User::getEmail, "Tom@Tom.com");
    
            userService.update(lambdaUpdateWrapper);
        }
    }

    创建LambdaWrapperTest测试类,内容如下

    上述的QueryWrapperUpdateWrapper均有一个Lambda版本,也就是LambdaQueryWrapperLambdaUpdateWrapperLambda版本的优势在于,可以省去字段名的硬编码,具体案例如下:

    @SpringBootTest
    public class LambdaWrapperTest {
    
        @Autowired
        private UserService userService;
    
        @Test
        public void testLambdaQueryWrapper() {
            //查询name=Tom的所有用户
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getName, "Tom");
    
            List<User> list = userService.list(lambdaQueryWrapper);
            list.forEach(System.out::println);
    
        }
    
        @Test
        public void testLambdaUpdateWrapper() {
            //将name=Tom的用户的邮箱改为Tom@tom.com
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getName, "Tom");
            lambdaUpdateWrapper.set(User::getEmail, "Tom@Tom.com");
    
            userService.update(lambdaUpdateWrapper);
        }
    }

    五.分页插件

    分页查询是一个很常见的需求,故Mybatis-Plus提供了一个分页插件,使用它可以十分方便的完成分页查询。下面介绍Mybatis-Plus分页插件的用法
     

    配置分页插件

    创建edu.glut.hellomp.config.MPConfiguration配置类,增加如下内容

    @Configuration
    public class MPConfiguration {
    
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }

分页插件使用说明

构造分页对象

分页对象包含了分页的各项信息,其核心属性如下:

 

分页对象既作为分页查询的参数,也作为分页查询的返回结果,当作为查询参数时,通常只需提供currentsize属性,如下

IPage<T> page = new Page<>(current, size);
  • 注:IPage为分页接口,PageIPage接口的一个实现类。

  • 分页查询

    Mybatis Plus的BaseMapperServiceImpl均提供了常用的分页查询的方法,例如:

    • BaseMapper的分页查询:

IPage<T> selectPage(IPage<T> page,Wrapper<T> queryWrapper);

ServiceImpl的分页查询:

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);

自定义Mapper

对于自定义SQL,也可以十分方便的完成分页查询,如下

Mapper接口:

IPage<UserVo> selectPageVo(IPage<?> page, Integer state);

Mapper.xml

<select id="selectPageVo" resultType="xxx.xxx.xxx.UserVo">
    SELECT id,name FROM user WHERE state=#{state}
</select>
      • 注意Mapper.xml中的SQL只需实现查询list的逻辑即可,无需关注分页的逻辑。

  • 案例实操

    分页查询案例如下:

    创建PageTest测试类,内容如下

    @SpringBootTest
    public class PageTest {
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private UserMapper userMapper;
    
        //通用Service分页查询
        @Test
        public void testPageService() {
            Page<User> page = new Page<>(2, 3);
            Page<User> userPage = userService.page(page);
            userPage.getRecords().forEach(System.out::println);
        }
    
        //通用Mapper分页查询
        @Test
        public void testPageMapper() {
            IPage<User> page = new Page<>(2, 3);
            IPage<User> userPage = userMapper.selectPage(page, null);
            userPage.getRecords().forEach(System.out::println);
        }
    
        //自定义SQL分页查询
        @Test
        public void testCustomMapper() {
            IPage<User> page = new Page<>(2, 3);
            IPage<User> userPage = userMapper.selectUserPage(page);
            userPage.getRecords().forEach(System.out::println);
        }
    }

    在UserMapper中声明分页查询方法如下

  • IPage<User> selectUserPage(IPage<User> page);

    创建resources/mapper/UserMapper.xml文件,内容如下

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.atguigu.hellomp.mapper.UserMapper">    <select id="selectUserPage" resultType="com.atguigu.hellomp.entity.User">        select *        from user    </select></mapper>

    注意

    Mybatis-Plus中Mapper.xml文件路径默认为:classpath*:/mapper/**/*.xml,可在application.yml中配置以下参数进行修改

    mybatis-plus:
      mapper-locations: classpath*:/mapper/**/*.xml

    六.MyBatisX插件

    MyBatis Plus提供了一个IDEA插件——MybatisX,使用它可根据数据库快速生成EntityMapperMapper.xmlServiceServiceImpl等代码,使用户更专注于业务。

  • 安装插件

    在IDEA插件市场搜索MyBatisX,进行在线安装

  • 配置数据库连接

    在IDEA中配置数据库连接

    生成代码

    首先将之前编写的UserUserMapperUserServcieUserServiceImpl全部删除,然后按照下图指示使用插件生成代码

  • 配置实体类相关信息
  • 配置代码模版信息
  • 点击Finish然后查看生成的代码。
  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值