Mybatis插件之MybatisPlus入门

目录

一、引言

二、简介

三、特性

四、架构

五、快速入门(基于IDEA开发工具)

5.1 数据库准备

5.1.1 创建数据库、表、插入数据

5.2 使用IDEA编写入门案例

5.2.1创建maven工程

5.2.2 导入依赖(整合SpringBoot进行开发)

5.2.3 编写application.properties文件

5.2.4 编写User实体类

5.2.5 编写UserMapper接口

5.2.6 编写SpringBoot启动类

5.2.7 编写测试用例

5.3 BaseMapper接口

5.3.1 源码详解

5.3.2 BaseMapper接口的方法进行测试

5.3.3 分页查询

5.4 Mybatis-plus插件的配置


一、引言

针对ORM这一层的技术选型,一般采用 Mybatis框架作为持久层框架,原因是Mybatis对SQL语句编写更加的灵活。 为了提升开发的效率,很多人会选用MybatisPlus作为mybatis开发的的插件,以提升开发的效率。

二、简介

官网地址:https://mp.baomidou.com/guide/

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

三、特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操 作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、 SQLServer2005、SQLServer 等多种数据库
  • 支持主键自动生成:支持多达4种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题支持XML热加载:Mapper对应的XML支持热加载,对于简单的 CRUD 操作,甚至可以无 XML启动支持
  • ActiveRecord 模式:支持ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作支持自定义
  • 全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、update 操作智能分析阻断,也可自定义拦截规则,预防误操作
  • 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击

四、架构

五、快速入门(基于IDEA开发工具)

5.1 数据库准备

5.1.1 创建数据库、表、插入数据

# 创建mumu数据库
create database dbmumu character set utf8;
# 使用数据库
use dbmumu;

# 创建user表
create table user(
	id bigint(20) not null comment '主键ID',
	name varchar(30) default null comment '姓名',
	age int(11) default null comment '年龄',
	email varchar(50) default null comment '邮箱',
	primary key(id)
	)engine=InnoDB default charset=utf8;
	
# 向user表插入数据
INSERT INTO `user` (`id`, `name`, `age`, `email`) VALUES ('1', 'Jone', '18','[email protected]');
INSERT INTO `user` (`id`, `name`, `age`, `email`) VALUES ('2', 'Jack', '20','[email protected]');
INSERT INTO `user` (`id`, `name`, `age`, `email`) VALUES ('3', 'Tom', '28','[email protected]');
INSERT INTO `user` (`id`, `name`, `age`, `email`) VALUES ('4', 'Sandy', '21','[email protected]');
INSERT INTO `user` (`id`, `name`, `age`, `email`) VALUES ('5', 'Billie', '24','[email protected]');
insert into user(`id`,`name`,`age`,`email`) values('6','张无忌','18','[email protected]');
insert into user(`id`,`name`,`age`,`email`) values('7','赵敏','17','[email protected]');
insert into user(`id`,`name`,`age`,`email`) values('8','周芷若','17','[email protected]');
insert into user(`id`,`name`,`age`,`email`) values('9','宋青书','20','[email protected]');
insert into user(`id`,`name`,`age`,`email`) values('10','赵敏君','30','[email protected]');


# 查看表记录
select * from user;

5.2 使用IDEA编写入门案例

5.2.1创建maven工程

5.2.2 导入依赖(整合SpringBoot进行开发)

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.poison.mybatisplus</groupId>
    <artifactId>poison-mybatis-plus</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--SpringBoot版本锁定-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <dependencies>
        <!--SpringBoot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--SpringBoot测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--mybatis的SpringBoot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--SpringBoot的maven插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.2.3 编写application.properties文件

#SpringBoot应用配置的名称
spring.application.name=poison-mybatis-plus

#mysql驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#mysql数据源连接地址
spring.datasource.url=jdbc:mysql://10.10.10.220:3306/dbmumu?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&userSSL=false
#mysql数据库登录名
spring.datasource.username=root
#mysql数据库登录密码
spring.datasource.password=root

5.2.4 编写User实体类

package cn.poison.mybatisplus.pojo;
import java.io.Serializable;
/**
 * 用户表实体类
 * Tool: IntelliJ IDEA.
 * Author: Poison
 * CreateDateTime: 2020/3/15 12:03
 */
public class User implements Serializable {
    @TableId(value = "ID",type = IdType.AUTO)  //设置id自增
    private Long id;      //用户id
    private String name;  //用户姓名
    private Integer age;  //用户年龄
    private String email; //用户邮箱

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

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

    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }
}
  • 注意点1:

这里通过@TableId注解设置user实体类封装时的id自增,它会根据数据库的自增初始值进行增加,所以数据库user表要先设置id自增

  • 注意点2:

如果数据库user表设置了id自增,而不在user实体类中添加@TableId注解设置id属性自增的话,则id值会在实体类封装的时候随机生成,不会按照数据库user表的自增初始值进行增长,并且会把随机生成的随机值设置为数据库user表的自增初始值,如下面

5.2.5 编写UserMapper接口

这里使用mybatis-plus插件,直接继承BaseMapper接口,

package cn.poison.mybatisplus.mapper;
import cn.poison.mybatisplus.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * 用户表mapper接口
 * 继承mybatisplus插件的BaseMapper接口,传入User泛型
 * Tool: IntelliJ IDEA.
 * Author: Poison
 * CreateDateTime: 2020/3/15 12:06
 */
public interface UserMapper extends BaseMapper<User> {

}

5.2.6 编写SpringBoot启动类

package cn.poison.mybatisplus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * SpringBoot启动类
 * Tool: IntelliJ IDEA.
 * Author: Poison
 * CreateDateTime: 2020/3/15 12:26
 */
@MapperScan(basePackages = "cn.poison.mybatisplus.mapper") //指定mapper接口的扫描包
@SpringBootApplication
public class MyApplication {

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

5.2.7 编写测试用例

在test目录下编写

package cn.poison.mybatisplus.mapper;

import cn.poison.mybatisplus.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

/**
 * 编写UserMapper接口的测试用例
 * Tool: IntelliJ IDEA.
 * Author: Poison
 * CreateDateTime: 2020/3/15 12:30
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    /**
     * 此处会报错,实际上没有错误,不影响运行
     */
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testUserMapper(){
        List<User> users = this.userMapper.selectList(null);
        for (User user : users) {
            System.out.println("--->"+user);
        }
    }
}

运行结果:

5.3 BaseMapper接口

5.3.1 源码详解

在MybatisPlus中,BaseMapper中定义了一些常用的CRUD方法,当我们自定义的Mapper接口继承BaseMapper 后即可拥有了这些方法。

需要说明的是:这些方法仅适合单表操作。

/**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * 这个 Mapper 支持 id 泛型
 */
public interface BaseMapper<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)
     */
    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 实体对象
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

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

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

5.3.2 BaseMapper接口的方法进行测试

接着上面的入门案例对BaseMapper的CRUD方法进行调用

  • 通过主键查询
    /**
     * 测试通过id查询用户
     */
    @Test
    public void testSelectById(){
        //id为long类型
        User user = this.userMapper.selectById(3L);
        System.out.println(user);
    }

  • 通过字段模糊查询(like)
    /**
     * 测试模糊查询
     */
    @Test
    public void testSelectListByLike(){
        //定义Wrapper类型对象
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        //添加模糊查询字段
        wrapper.like("name","o");
        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println("--->"+user);
        }
    }

  • 通过条件查询
    /**
     * 测试条件查询
     */
    @Test
    public void testSelectListByLe(){
        //定义Wrapper类型对象
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        //添加条件查询字段,年龄小于18的用户(包含18)
        wrapper.le("age","18");
        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println("--->"+user);
        }
    }

  • 插入数据
   /**
     * 测试插入数据
     */
    @Test
    public void testSave(){
        User user = new User();
        user.setName("杨过");
        user.setAge(20);
        user.setEmail("[email protected]");
        int i = this.userMapper.insert(user);
    }

  • 删除数据
    /**
     * 测试删除数据
     */
    @Test
    public void testDelete(){
        int i = this.userMapper.deleteById(12L);
        System.out.println("删除数据-->"+i);

    }

 --------->

  • 修改数据

根据id修改user对象中不为null的用户数据

    /**
     * 根据id修改user不为null的字段
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(11L);
        user.setName("郭靖");

        int i = this.userMapper.updateById(user);
        System.out.println("修改结果--->"+i);
    }

----------->

5.3.3 分页查询

第一步:在案例的SpringBoot启动类MyApplication中添加分页插件,注册到Spring容器

   /**
     * 添加分页插件,放进Spring容器
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
    

第二步:测试使用

   /**
     * 分页查询
     */
    @Test
    public void testSelectByPage(){
        //第一个参数为当前页码,第二个参数为每页显示的数据
        Page<User> page=new Page<>(1,5);
        IPage<User> userIPage = this.userMapper.selectPage(page, null);
        System.out.println("总条数---->"+userIPage.getTotal());
        System.out.println("当前页码-->"+userIPage.getCurrent());
        System.out.println("每页显示记录条数--->"+userIPage.getSize());
        System.out.println("总页数---->"+userIPage.getPages());
        System.out.println("查询得到的记录---->"+userIPage.getRecords());
    }

运行结果: 

5.4 Mybatis-plus插件的配置

虽然在MybatisPlus中可以实现零配置,但是有些时候需要我们自定义一些配置,就需要使用Mybatis原生的一些配置文件方式了。

可在application.properties文件中配置

# 指定全局配置文件
mybatis-plus.config-location = classpath:mybatis-config.xml
# 指定mapper.xml文件
mybatis-plus.mapper-locations = classpath*:mybatis/*.xml

详细配置可查看官网:https://mp.baomidou.com/config/#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE

  • Spring Boot 工程:

    • 配置 MapperScan 注解

      @SpringBootApplication
      @MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
      public class Application {
      
          public static void main(String[] args) {
              SpringApplication.run(QuickStartApplication.class, args);
          }
      
      }
      
  • Spring MVC 工程:

    • 配置 MapperScan

      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
          <property name="basePackage" value="com.baomidou.mybatisplus.samples.quickstart.mapper"/>
      </bean>
      
    • 调整 SqlSessionFactory 为 MyBatis-Plus 的 SqlSessionFactory

      <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
      </bean>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章