mybatis学习笔记——mybatis-plus快速入门

一、快速入门

MyBatis-plus (简称mp)是一款 Mybatis 增强工具,用来简化开发、增强效率。本文结合Spring Boot来实现mp的快速入门。
注:本文演示mp版本为当前最新的3.5.1
官方网站:https://baomidou.com/

1、创建SpringBoot项目
2、导入依赖


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.7.2version>
        <relativePath/> 
    parent>
    <groupId>com.examplegroupId>
    <artifactId>mybatis-plus-demoartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>mybatis-plus-demoname>
    <description>Demo project for Spring Bootdescription>
    <properties>
        <java.version>1.8java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.5.1version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.20version>
            <scope>runtimescope>
        dependency>
        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
            <scope>testscope>
        dependency>

    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>
    build>

project>

3、配置
application.yml配置文件

spring:
  datasource:
  	#mysql驱动6.0版本以上的为com.mysql.cj.jdbc.Driver
    driver-class-name: com.mysql.jdbc.Driver	
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root1234
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启SQL语句打印

4、数据库脚本

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL 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)
);

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

5、编码
实体类:

package com.example.demo.po;

import lombok.Data;

/**
 * 〈实体类,类名和属性名需要符合驼峰命名法,可以不用关联表名,mybatis会自动关联〉
* 否则需要使用mybatis的@TableName,@TableId,@TableField等注解,将实体类和表关联 */
@Data public class User { private Long id; private String name; private Integer age; private String email; }

mapper接口:

package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.po.User;

public interface UserMapper extends BaseMapper<User> {
}

service接口

package com.example.demo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.po.User;

public interface UserService extends IService<User> {
}

service实现类:

package com.example.demo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.mapper.UserMapper;
import com.example.demo.po.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

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

Spring Boot 启动类:

package com.example.mybatisplusdemo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.example")
@MapperScan("com.example.demo.mapper")
public class MybatisPlusDemoApplication {

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

}

测试类

package com.example.mybatisplusdemo;

import com.example.demo.mapper.UserMapper;
import com.example.demo.po.User;
import com.example.demo.service.UserService;
import org.junit.jupiter.api.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;

@RunWith(SpringRunner.class)
@SpringBootTest
class MybatisPlusDemoApplicationTests {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {

        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }
    @Test
    void test(){
        List<User> userList = userService.getBaseMapper().selectList(null);
        userList.forEach(System.out::println);
    }

}

运行测试方法结果:
mybatis学习笔记——mybatis-plus快速入门_第1张图片
项目结构:
mybatis学习笔记——mybatis-plus快速入门_第2张图片
mp的service里定义了mapper,我们在service里使用mapper时无需注入,直接使用this.baseMapper即可。

二、核心功能

1、注解

@TableName

表名注解,标识实体类对应的表。如果类名使用驼峰命名法命名,可以不使用该注解。示例:ta_user表对应的实体类为taUser。或者表名与类名相同也无需使用该注解

属性 类型 必须指定 默认值 描述
value String "" 表名
schema String "" schema
keepGlobalPrefix boolean false 是否保持使用全局的 tablePrefix 的值(当全局 tablePrefix 生效时)
resultMap String "" xml 中 resultMap 的 id(用于满足特定类型的实体类对象绑定)
autoResultMap boolean false 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建与注入)
excludeProperty String[] {} 需要排除的属性名 @since 3.3.1

@TableId

主键注解,用在主键字段上

属性 类型 必须指定 默认值 描述
value String "" 主键字段名
type Enum IdType.NONE 指定主键类型

IdType的值

描述
AUTO 数据库 ID 自增
NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert 前自行 set 主键值
ASSIGN_ID 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
ID_WORKER 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID)
UUID 32 位 UUID 字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)

@TableField

字段注解(非主键)

属性 类型 必须指定 默认值 描述
value String "" 数据库字段名
exist boolean true 是否为数据库表字段
condition String "" 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考 (opens new window)
update String "" 字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性)
insertStrategy Enum FieldStrategy.DEFAULT 举例:NOT_NULL
insert into table_a(column) values (#{columnProperty})
updateStrategy Enum FieldStrategy.DEFAULT 举例:IGNORED
update table_a set column=#{columnProperty}
whereStrategy Enum FieldStrategy.DEFAULT 举例:NOT_EMPTY
where column=#{columnProperty}
fill Enum FieldFill.DEFAULT 字段自动填充策略
select boolean true 是否进行 select 查询
keepGlobalFormat boolean false 是否保持使用全局的 format 进行处理
jdbcType JdbcType JdbcType.UNDEFINED JDBC 类型 (该默认值不代表会按照该值生效)
typeHandler Class UnknownTypeHandler.class 类型处理器 (该默认值不代表会按照该值生效)
numericScale String "" 指定小数点后保留的位数

FieldStrategy
字段验证策略

描述
IGNORED 忽略判断
NOT_NULL 非 NULL 判断
NOT_EMPTY 非空判断(只对字符串类型字段,其他类型字段依然为非 NULL 判断)
DEFAULT 追随全局配置
NEVER 不加入SQL

FieldFill
字段填充策略

描述
DEFAULT 默认不处理
INSERT 插入时填充字段
UPDATE 更新时填充字段
INSERT_UPDATE 插入和更新时填充字段

@Version

乐观锁注解、标记 @Verison 在字段上,作为版本号。

@EnumValue

普通枚举类注解(注解在枚举字段上)

@TableLogic

属性 类型 必须指定 默认值 描述
value String "" 逻辑未删除值
delval String "" 逻辑删除值

@KeySequence

序列主键策略 (oracle)

属性 类型 必须指定 默认值 描述
value String "" 序列名
clazz Class Long.class id 的类型, 可以指定 String.class,这样返回的 Sequence 值是字符串"1"

@OrderBy

内置 SQL 默认指定排序,优先级低于 wrapper 条件查询

属性 类型 必须指定 默认值 描述
isDesc boolean true 是否倒序查询
sort short Short.MAX_VALUE 数字越小越靠前

@InterceptorIgnore

插件过滤规则

2、CRUD接口

mp封装了一些最基础的CRUD方法,只需要直接继承mp提供的接口,无需编写任何SQL,即可食用。mp提供了两套接口,分别是Mapper CRUD接口和Service CRUD接口。并且mp还提供了条件构造器Wrapper,可以方便地组装SQL语句中的WHERE条件。

Mapper CRUD接口

只需定义好实体类,然后创建一个接口,继承mp提供的BaseMapper,即可使用。mp会在mybatis启动时,自动解析实体类和表的映射关系,并注入带有通用CRUD方法的mapper。

部分方法示例:

insert(T entity)  插入一条记录

deleteById(Serializable id)  根据主键id删除一条记录

delete(Wrapper<T> wrapper) 根据条件构造器wrapper进行删除

deleteByMap(Map<String, Object> columnMap) 根据多个列删除数据

deleteBatchIds(Collection<?> idList) 根据主键id进行批量删除

selectById(Serializable id) 根据主键id进行查找

selectBatchIds(Collection idList) 根据主键id进行批量查找

selectByMap(Map<String,Object> map) 根据map中指定的列名和列值进行等值匹配查找

selectMaps(Wrapper<T> wrapper)  根据 wrapper 条件,查询记录,将查询结果封装为一个MapMap的key为结果的列,value为值

selectList(Wrapper<T> wrapper) 根据条件构造器wrapper进行查询

selectOne(Wrapper<T> queryWrapper) 根据条件查找第一条记录

update(T entity, Wrapper<T> wrapper) 根据条件构造器wrapper进行更新

updateById(T entity) 根据id更新记录

exists(Wrapper<T> queryWrapper) 根据条件查找是否存在记录

selectCount(Wrapper<T> queryWrapper) 查询行数

selectPage(P page, Wrapper<T> queryWrapper) 分页查询,结果是实体类

selectMapsPage(P page, Wrapper<T> queryWrapper) 分页查询,结果是map

selectObjs(Wrapper<T> queryWrapper) 只查询第一列数据

Service CRUD 接口

另外一套CRUD是Service层的,只需要编写一个接口,继承IService,并创建一个接口实现类即可使用。这个接口提供的CRUD方法,和Mapper接口提供的功能大同小异,比较明显的区别在于IService支持了更多的批量化操作,如saveBatch,saveOrUpdateBatch等方法。

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

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

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);

// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();

// 链式更改 普通
UpdateChainWrapper<T> update();
// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();

3、条件构造器

mp提供了强大的条件构造器Wrapper,条件构造器主要涉及到3个类,AbstractWrapper,QueryWrapper,UpdateWrapper。条件构造器也支持lambda表达式,使用LambdaQueryChainWrapper、LambdaUpdateChainWrapper。
在AbstractWrapper中提供了非常多的方法用于构建WHERE条件,而QueryWrapper针对SELECT语句,提供了select()方法,可自定义需要查询的列,而UpdateWrapper针对UPDATE语句,提供了set()方法,用于构造set语句。

AbstractWrapper中用于构建SQL语句中的WHERE条件的方法进行部分列举

eq:equals,等于
allEq:all equals,全等于
ne:not equals,不等于
gt:greater than ,大于 >
ge:greater than or equals,大于等于≥
lt:less than,小于<
le:less than or equals,小于等于≤
between:相当于SQL中的BETWEEN
notBetween
like:模糊匹配。like("name","黄"),相当于SQL的name like '%黄%'
likeRight:模糊匹配右半边。likeRight("name","黄"),相当于SQL的name like '黄%'
likeLeft:模糊匹配左半边。likeLeft("name","黄"),相当于SQL的name like '%黄'
notLike:notLike("name","黄"),相当于SQL的name not like '%黄%'
isNull
isNotNull
in
and:SQL连接符AND
or:SQL连接符OR
apply:用于拼接SQL,该方法可用于数据库函数,并可以动态传参
last:无视优化规则直接拼接到 sql 的最后

使用案例:

// 案例先展示需要完成的SQL语句,后展示Wrapper的写法  
  
// 1. 名字中包含佳,且年龄小于25  
// SELECT * FROM user WHERE name like '%佳%' AND age < 25  
QueryWrapper<User> wrapper = new QueryWrapper<>();  
wrapper.like("name", "佳").lt("age", 25);  
List<User> users = userMapper.selectList(wrapper);  
// 下面展示SQL时,仅展示WHERE条件;展示代码时, 仅展示Wrapper构建部分  
  
// 2. 姓名为黄姓,且年龄大于等于20,小于等于40,且email字段不为空  
// name like '黄%' AND age BETWEEN 20 AND 40 AND email is not null  
wrapper.likeRight("name","黄").between("age", 20, 40).isNotNull("email");  
  
// 3. 姓名为黄姓,或者年龄大于等于40,按照年龄降序排列,年龄相同则按照id升序排列  
// name like '黄%' OR age >= 40 order by age desc, id asc  
wrapper.likeRight("name","黄").or().ge("age",40).orderByDesc("age").orderByAsc("id");  
  
// 4.创建日期为2021年3月22日,并且直属上级的名字为李姓  
// date_format(create_time,'%Y-%m-%d') = '2021-03-22' AND manager_id IN (SELECT id FROM user WHERE name like '李%')  
wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", "2021-03-22") // 建议采用{index}这种方式动态传参, 可防止SQL注入  
    .inSql("manager_id", "SELECT id FROM user WHERE name like '李%'");  
// 上面的apply, 也可以直接使用下面这种方式做字符串拼接,但当这个日期是一个外部参数时,这种方式有SQL注入的风险  
wrapper.apply("date_format(create_time, '%Y-%m-%d') = '2021-03-22'");  
  
// 5. 名字为王姓,并且(年龄小于40,或者邮箱不为空)  
// name like '王%' AND (age < 40 OR email is not null)  
wrapper.likeRight("name", "王").and(q -> q.lt("age", 40).or().isNotNull("email"));  
  
// 6. 名字为王姓,或者(年龄小于40并且年龄大于20并且邮箱不为空)  
// name like '王%' OR (age < 40 AND age > 20 AND email is not null)  
wrapper.likeRight("name", "王").or(  
    q -> q.lt("age",40)  
      .gt("age",20)  
      .isNotNull("email")  
  );  
  
// 7. (年龄小于40或者邮箱不为空) 并且名字为王姓  
// (age < 40 OR email is not null) AND name like '王%'  
wrapper.nested(q -> q.lt("age", 40).or().isNotNull("email"))  
    .likeRight("name", "王");  
  
// 8. 年龄为30,31,34,35  
// age IN (30,31,34,35)  
wrapper.in("age", Arrays.asList(30,31,34,35));  
// 或  
wrapper.inSql("age","30,31,34,35");  
  
// 9. 年龄为30,31,34,35, 返回满足条件的第一条记录  
// age IN (30,31,34,35) LIMIT 1  
wrapper.in("age", Arrays.asList(30,31,34,35)).last("LIMIT 1");  
  
// 10. 只选出id, name 列 (QueryWrapper 特有)  
// SELECT id, name FROM user;  
wrapper.select("id", "name");  
  
// 11. 选出id, name, age, email, 等同于排除 manager_id 和 create_time  
// 当列特别多, 而只需要排除个别列时, 采用上面的方式可能需要写很多个列, 可以采用重载的select方法,指定需要排除的列  
wrapper.select(User.class, info -> {  
   String columnName = info.getColumn();  
   return !"create_time".equals(columnName) && !"manager_id".equals(columnName);  
  });

Condition

条件构造器的诸多方法中,均可以指定一个boolean类型的参数condition,用来决定该条件是否加入最后生成的WHERE语句中,比如

String name = "黄"; // 假设name变量是一个外部传入的参数  
QueryWrapper<User> wrapper = new QueryWrapper<>();  
wrapper.like(StringUtils.hasText(name), "name", name);  
// 仅当 StringUtils.hasText(name) 为 true 时, 会拼接这个like语句到WHERE中  
// 其实就是对下面代码的简化  
if (StringUtils.hasText(name)) {  
 wrapper.like("name", name);  
}

实体对象作为条件
调用构造函数创建一个Wrapper对象时,可以传入一个实体对象。后续使用这个Wrapper时,会以实体对象中的非空属性,构建WHERE条件(默认构建等值匹配的WHERE条件,这个行为可以通过实体类里各个字段上的@TableField注解中的condition属性进行改变)例如:@TableField(condition = SqlCondition.LIKE) // 配置该字段使用like进行拼接
SqlCondition类中预定义了一些字符串以供选择

package com.baomidou.mybatisplus.annotation;  
  
public class SqlCondition {  
    //下面的字符串中, %s 是占位符, 第一个 %s 是列名, 第二个 %s 是列的值  
    public static final String EQUAL = "%s=#{%s}";  
    public static final String NOT_EQUAL = "%s<>#{%s}";  
    public static final String LIKE = "%s LIKE CONCAT('%%',#{%s},'%%')";  
    public static final String LIKE_LEFT = "%s LIKE CONCAT('%%',#{%s})";  
    public static final String LIKE_RIGHT = "%s LIKE CONCAT(#{%s},'%%')";  
}

SqlCondition中提供的配置比较有限,有时需要自己拼接
例如:
@TableField(condition = “%s > #{%s}”) 表示大于

lambda条件构造器

lambda条件构造器,支持lambda表达式,可以不必像普通条件构造器一样,以字符串形式指定列名,它可以直接以实体类的方法引用来指定列。

 LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();  
  wrapper.like(User::getName, "黄").lt(User::getAge, 30);  
  List<User> users = userMapper.selectList(wrapper);  
  users.forEach(System.out::println);  

lambda条件构造器可以链式调用,使代码更简洁

 LambdaQueryChainWrapper<User> chainWrapper = new LambdaQueryChainWrapper<>(userMapper);  
  List<User> users = chainWrapper.like(User::getName, "黄").gt(User::getAge, 30).list();  
  users.forEach(System.out::println); 

三、代码示例

查询简单示例

	@Test
    void selectTest(){

        //QueryWrapper查询
        List<User> userList = userService.getBaseMapper().selectList(
                new QueryWrapper<User>().eq("name","Jack")
        );
        userList.forEach(System.out::println);
        //LambdaQueryWrapper查询
        List<User> userList1 = userService.getBaseMapper().selectList(
                new LambdaQueryWrapper<User>().eq(User::getName,"Jack")
        );
        userList1.forEach(System.out::println);

        //LambdaQueryChainWrapper查询
        List<User> userList2 = userService.lambdaQuery().eq(User::getName,"Jack").list();
        userList2.forEach(System.out::println);
    }

update 简单示例

@Test
    void updateTest(){
        //UpdateWrapper更新
        boolean flag = userService.update(
                new UpdateWrapper<User>()
                .eq("name","Jack")
                .set("age",20)
        );
        System.out.println(flag);

        //LambdaUpdateWrapper更新
        boolean flag1 = userService.update(
                new LambdaUpdateWrapper<User>()
                .in(User::getId,new int[]{1,2})
                .set(User::getAge,18)
        );
        System.out.println(flag1);

        boolean flag2 = userService.lambdaUpdate()
                .in(User::getId,new String[]{"1","2"})
                .set(User::getAge,17)
                .update();
        System.out.println(flag2);
    }

insert 简单示例:

@Test
    void insertTest(){
        User user1 = new User();
        user1.setId(6L);
        user1.setName("Mic");
        user1.setAge(29);
        user1.setEmail("[email protected]");
        int count = userMapper.insert(user1);

        System.out.println(count);

        User user2 = new User();
        user2.setId(7L);
        user2.setName("Sam");
        user2.setAge(23);
        user2.setEmail("[email protected]");
        boolean falg = userService.save(user2);

        System.out.println(falg);
    }

delete示例:

@Test
    void deleteTest(){
        int result = userMapper.delete(new QueryWrapper<User>().eq("id",6));
        System.out.println(result);

        int result2 = userMapper.delete(new LambdaQueryWrapper<User>().eq(User::getId,7));
        System.out.println(result);

    }

分页查询示例

mp使用分页查询前,需要先把分页查询查插件注册到spring中

package com.example.demo.config;

import com.baomidou.mybatisplus.annotation.DbType;
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 MybatisPlusConfig {

    /** 新版mp **/
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    /** 旧版mp 用 PaginationInterceptor **/
}

分页查询示例:

 @Test
    void selectpageTest(){
        //QueryWrapper查询
        IPage<User> pageList = userService.getBaseMapper().selectPage(
                new Page<User>(0,2),
                new QueryWrapper<User>()
        );

        List<User> userList = pageList.getRecords();
        userList.forEach(System.out::println);

        IPage<User> pageList1 = userService.getBaseMapper().selectPage(
                new Page<User>(0,2),
                new LambdaQueryWrapper<User>()
        );

        List<User> userList1 = pageList1.getRecords();
        userList1.forEach(System.out::println);

        IPage<User> pageList2 = userService.lambdaQuery().page(new Page<User>(0,2));

        List<User> userList2 = pageList2.getRecords();
        userList2.forEach(System.out::println);

分页查询默认会先查count总条数,如果不希望查count,可以通过Page的重载构造函数,指定isSearchCount为false即可

public Page(long current, long size, boolean isSearchCount)

使用mybatis原生的方式做查询时,如果需要使用分页,可以在接口上加上page参数:Param(“page”) Page<> page,即可使用分页方法,而无需在sql中写分页语句

四、总结

mp在mybatis的基础上做了增强,提供许多简单的CRUD方法,我们拿来直接用即可。而且mp也保留了原生的mybatis的功能,我们也可以使用原生的在mapper.xml中写sql的方式执行crud。本文只是介绍了mybatis-plus的基础功能,方便新手快速入门,mybatis-plus还有许多有趣的功能,可以自行去官网查阅。

你可能感兴趣的:(mybatis,mybatis,学习,java)