MyBatisPlus

MyBatisPlus

1. 介绍

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

1.1 特性

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

1.2 架构

image

2. 快速开始

2.1 SpringBoot + MP

  1. 创建工程

  2. 依赖

    <!-- spring-boot-starter-web 的依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- 引入MyBatisPlus的依赖 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.1</version>
            </dependency>
            <!-- 数据库使用MySQL数据库 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- 数据库连接池 Druid -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.14</version>
            </dependency>
            <!-- lombok依赖 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
    
  3. application.yml

    spring.application.name = itcast-mp-springboot
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mp?
    useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL
    =false
    spring.datasource.username=root
    spring.datasource.password=root
    
  4. 编写 pojo

  5. 编写 mapper

3. 通用 CRUD

3.1 插入

3.1.1 示例

User user = new User();
// 返回的result是受影响的行数, 并不是自增后的id
int result = userMapper.insert(user); 

3.1.2 ID 生成策略

@TableId(type = IdType.AUTO)
private Long id;

IdType:

  • AUTO: ID 自增
  • NONE: 未设置主键类型
  • INPUT: 用户输入 ID
  • ID_WORKER:全局唯一 ID (idWorker)
  • UUID: 全局唯一 ID (UUID)

3.1.3 @TableField

添加 @TableField 注解可以指定字段属性, 通常解决以下问题:

  1. 对象中的属性名和数据库列表字段名不一致问题(非驼峰)
  2. 对象中的属性字段在表中不存在的问题
  3. 字段不加入查询
@TableField(value = "email")
private String mail;  // 解决字段名不一致问题

@TableField(exist = false)
private String address; // 该字段在数据库表中不存在

@TableField(select = false)
private String password; // 该字段不加入查询

3.2 更新

3.2.1 根据 id 更新

// 根据id修改
int updateById(@Param(Constants.ENTITY) T entity);

// 查询
User user = new User();
user.setId(6L); // 主键
user.SETaGE(21); // 更新的字段

userMapper.updateById(user);

3.2.2 根据条件更新

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

方式一:

User user = new User();
user.setAge = 22; // 更新的字段

// 更新的条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("id", 6);

// 执行更新操作
int result = userMapper.update(user, wrapper);

方式二:

// 更新条件及字段
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 6).set("age", 23);

// 执行更新操作
int result = userMapper.update(null, wrapper);

3.3 删除

3.3.1 deleteById

// 方法定义
int deleteById(Serializable id);

// -------------------------------------

//执行删除操作
int result = userMapper.deleteById(6L);

3.3.2 deleteByMap

/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 20);
columnMap.put("name", "张三");

// 将columnMap中的元素设置为删除的条件, 多个之间为and关系
int result = userMapper.deleteByMap(columnMap);

3.3.3 delete

/**
* 根据 entity 条件,删除记录
*
* @param wrapper 实体对象封装操作类(可以为 null)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
User user = new User();
user.setAge(20);
user.setName("张三");

// 将实体对象进行包装,包装为操作条件
QueryWrapper<User> wrapper = new QueryWrapper<>(user);
int result = userMapper.delete(wrapper);

3.3.4 deleteBatchIds

/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable>
idList);
// 根据id集合批量删除
int result = userMapper.deleteBatchIds(Arrays.asList(1L, 10L, 20L));

3.4 查询

3.4.1 selectById

/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
//根据id查询数据
User user = userMapper.selectById(2L);

3.4.2 selectBatchIds

/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable>
idList);
//根据id集合批量查询
List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L));

3.4.3 selectOne

/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
QueryWrapper<User> wrapper = new QueryWrapper<User>();
wrapper.eq("name", "李四");
//根据条件查询一条数据,如果结果超过一条会报错
User user = this.userMapper.selectOne(wrapper);

3.4.4 selectCount

/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
QueryWrapper<User> wrapper = new QueryWrapper<User>();
wrapper.gt("age", 23); //年龄大于23岁

// 根据条件查询数据条数
Integer count = this.userMapper.selectCount(wrapper);

3.4.5 selectList

/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
QueryWrapper<User> wrapper = new QueryWrapper<User>();
wrapper.gt("age", 23); //年龄大于23岁

//根据条件查询数据
List<User> users = this.userMapper.selectList(wrapper);

3.4.6 selectPage

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

配置分页插件:

@MapperScan("cn.itcast.mp.mapper") //设置mapper接口的扫描包
public class MybatisPlusConfig {
    /**
    * 分页插件
    */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

查询:

QueryWrapper<User> wrapper = new QueryWrapper<User>();
wrapper.gt("age", 20); //年龄大于20岁

Page<User> page = new Page<>(1,1);

//根据条件查询数据
IPage<User> iPage = this.userMapper.selectPage(page, wrapper);
System.out.println("数据总条数:" + iPage.getTotal());
System.out.println("总页数:" + iPage.getPages());

List<User> users = iPage.getRecords();

4. 配置

4.1 基本配置

4.1.1 configLocation

MyBatis 配置文件位置

  1. SpringBoot:

    mybatis-plus.config-location = classpath:mybatis-config.xml
    
  2. Spring MVC:

    <bean id="sqlSessionFactory"    class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    

4.1.2 mapperLocations

MyBatis Mapper 所对应的 XML 文件位置,如果您在 Mapper 中有自定义方法(XML 中有自定义实现),需要进行该配置,告诉 Mapper 所对应的 XML 文件位置。

  1. SpringBoot:

    mybatis-plus.mapper-locations = classpath*:mybatis/*.xml
    
  2. Spring MVC:

    <bean id="sqlSessionFactory"
    class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="mapperLocations" value="classpath*:mybatis/*.xml"/>
    </bean>
    

4.1.3 typeAliasesPackage

  1. SpringBoot:

    mybatis-plus.type-aliases-package = cn.itcast.mp.pojo
    
  2. Spring MVC:

    <bean id="sqlSessionFactory"
    class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="typeAliasesPackage"
    value="com.baomidou.mybatisplus.samples.quickstart.entity"/>
    </bean>
    

4.2 进阶配置

本部分(Configuration)的配置大都为 MyBatis 原生支持的配置,这意味着您可以通过 MyBatis XML 配置文件的形式进行配置。

4.2.1 mapUnderscoreToCamelCase

  • 类型:boolean
  • 默认值:true

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射。

注意:

此属性在 MyBatis 中原默认值为 false,在 MyBatis-Plus 中,此属性也将用于生成最终的 SQL 的 select body

如果您的数据库命名符合规则无需使用 `@TableField`​ 注解指定数据库字段名

示例(SpringBoot):

#关闭自动驼峰映射,该参数不能和mybatis-plus.config-location同时存在
mybatis-plus.configuration.map-underscore-to-camel-case=false

4.2.2 cacheEnabled

  • 类型:boolean
  • 默认值:true

开启 Mybatis 二级缓存,默认为 true。

mybatis-plus.configuration.cache-enabled=false

4.3 DB 策略配置

4.3.1 idType

  • 类型:com.baomidou.mybatisplus.annotation.IdType
  • 默认值:ASSIGN_ID

全局默认主键类型

  1. SpringBoot:

    mybatis-plus.global-config.db-config.id-type=auto
    
  2. Spring MVC:

    <!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合-->
    <bean id="sqlSessionFactory"
          class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="globalConfig">
            <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">
                <property name="dbConfig">
                    <bean
                            class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                        <property name="idType" value="AUTO"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    

4.3.2 tablePrefix

  • 类型:String
  • 默认值:null

表名前缀, 全局配置后可省略 @TableName()配置。

  1. SpringBoot:

    mybatis-plus.global-config.db-config.table-prefix=tb_
    
  2. Spring MVC:

    <bean id="sqlSessionFactory"
          class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="globalConfig">
            <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">
                <property name="dbConfig">
                    <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                        <property name="idType" value="AUTO"/>
                        <property name="tablePrefix" value="tb_"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    

5. 条件构造器

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件的核心工具。以下是主要的 Wrapper 类及其功能:

  • AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。
  • QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 and​ 和 or​ 逻辑。
  • UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。
  • LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。
  • LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

5.1 allEq

allEq​ 方法是 MyBatis-Plus 中用于构建查询条件的方法之一,它允许我们通过一个 Map​ 来设置多个字段的相等条件。

5.1.1 使用范围
  • QueryWrapper
  • LambdaQueryWrapper
  • UpdateWrapper
  • LambdaUpdateWrapper
5.1.2 方法签名
// 设置所有字段的相等条件,如果字段值为null,则根据null2IsNull参数决定是否设置为IS NULL
allEq(Map<String, Object> params)
allEq(Map<String, Object> params, boolean null2IsNull)
allEq(boolean condition, Map<String, Object> params, boolean null2IsNull)

// 设置所有字段的相等条件,通过filter过滤器决定哪些字段应该被包含,如果字段值为null,则根据null2IsNull参数决定是否设置为IS NULL
allEq(BiPredicate<String, Object> filter, Map<String, Object> params)
allEq(BiPredicate<String, Object> filter, Map<String, Object> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<String, Object> filter, Map<String, Object> params, boolean null2IsNull)
5.1.3 参数说明
  • params​:一个 Map​,其中 key​ 是数据库字段名,value​ 是对应的字段值。
  • null2IsNull​:如果设置为 true​,当 Map​ 中的 value​ 为 null​ 时,会调用 isNull​ 方法;如果设置为 false​,则会忽略 value​ 为 null​ 的键值对。
  • filter​:一个 BiPredicate​,用于过滤哪些字段应该被包含在查询条件中。
  • condition​:一个布尔值,用于控制是否应用这些条件。
5.1.4 示例

普通 Wrapper (QueryWrapper)

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));

Lambda Wrapper (LambdaQueryWrapper)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));

带过滤器的普通 Wrapper (QueryWrapper)

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));

带过滤器的 Lambda Wrapper (LambdaQueryWrapper)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));

生成的 SQL

-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE id = 1 AND name = '老王' AND age IS NULL
-- 带过滤器的普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name = '老王' AND age IS NULL

5.2 基本比较操作

  1. eq: 等于=
  2. ne: 不等于<>
  3. gt: 大于>
  4. ge: 大于等于>=
  5. lt: 小于<
  6. le: 小于等于<=
  7. between: between 值1 and 值2
  8. notBetween: not between 值1 and 值2
  9. in: 字段 in (v0, v1, ...)
  10. notIn: 字段 not in (v0, v1, ...)

示例:

QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >= ? AND name IN (?,?,?)
wrapper.eq("password", "123456")
       .ge("age", 20)
       .in("name", "李四", "王五", "赵六");
List<User> users = this.userMapper.selectList(wrapper);

5.3 模糊查询

  1. like:

    LIKE '%值%'

    例: like("name", "王") ---> name like '%王%'

  2. notLike:

    NOT LIKE '%值%

    例: notLike("name", "王") ---> name not like '%王%'

  3. likeLeft:

    LIKE '%值'

    例: likeLeft("name", "王") ---> name like '%王'

  4. likeRight:

    LIKE '值%'

    例: likeRight("name", "王") ---> name like '王%'

示例:

//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name LIKE ?
//Parameters: %曹%(String)
wrapper.like("name", "曹");
List<User> users = this.userMapper.selectList(wrapper);

5.4 排序

  1. orderBy

    排序:ORDER BY 字段, ...

    例: orderBy(true, true, "id", "name") ---> order by id ASC,name ASC

  2. orderByAsc

    排序:ORDER BY 字段, ... ASC

    例: orderByAsc("id", "name") ---> order by id ASC,name ASC

  3. orderByDesc

    排序:ORDER BY 字段, ... DESC

    例: orderByDesc("id", "name") ---> order by id DESC,name DESC

示例:

QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC
wrapper.orderByDesc("age");
List<User> users = this.userMapper.selectList(wrapper);

5.5 逻辑查询

  1. or

    拼接 OR

    主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接)

  2. and

    AND 嵌套

    例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status

    <> '活着')

示例:

QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name = ? OR age = ?
wrapper.eq("name","李四").or().eq("age", 24);
List<User> users = this.userMapper.selectList(wrapper);

5.6 select

在MP查询中, 默认查询所有字段, 如果有需要也可以通过select方法进行指定字段

QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?
wrapper.eq("name", "李四")
       .or()
       .eq("age", 24)
       .select("id", "name", "age");
List<User> users = this.userMapper.selectList(wrapper);

6. 持久层接口

MP持久层主要有两个接口, 分别是: IService和BaseMapper, BaseMapper是DAO层的CRUD封装,而IService是业务业务逻辑层的CRUD封装,所以多了批量增、删、改的操作封装

ServiceImpl<M extends BaseMapper<T>, T>​提供了对IService 接口的实现

6.1 Service Interface

Iservice是 MyBatis-Plus 提供的一个通用 Service 层接口,它封装了常见的 CRUD 操作,包括插入、删除、查询和分页等。通过继承 IService 接口,可以快速实现对数据库的基本操作,同时保持代码的简洁性和可维护性。

IService 接口中的方法命名遵循了一定的规范,如 get 用于查询单行,remove 用于删除,list 用于查询集合,page 用于分页查询,这样可以避免与 Mapper 层的方法混淆。

6.1.1 save

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

默认批次数量为3

6.1.2 saveOrUpdate

// 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);

6.1.3 remove

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

6.1.4 update

// 根据 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);

6.1.5 get

// 根据 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);

6.1.6 list

// 查询所有
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);

6.1.7 page

// 无条件分页查询
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);

6.1.8 count

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

//自3.4.3.2开始,返回值修改为long
// 查询总记录数
long count();
// 根据 Wrapper 条件,查询总记录数
long count(Wrapper<T> queryWrapper);

6.2 Mapper Interface

BaseMapper 是 Mybatis-Plus 提供的一个通用 Mapper 接口,它封装了一系列常用的数据库操作方法,包括增、删、改、查等。通过继承 BaseMapper,开发者可以快速地对数据库进行操作,而无需编写繁琐的 SQL 语句。

6.2.1 insert

// 插入一条记录
int insert(T entity);

6.2.2 delete

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

6.2.3 update

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

6.2.4 select

// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

6.3 Chain

Chain 是 Mybatis-Plus 提供的一种链式编程风格,它允许开发者以更加简洁和直观的方式编写数据库操作代码。Chain 分为 query​ 和 update​ 两大类,分别用于查询和更新操作。每类又分为普通链式和 lambda 链式两种风格,其中 lambda 链式提供了类型安全的查询条件构造,但不支持 Kotlin。

使用步骤

query

提供链式查询操作,可以连续调用方法来构建查询条件。

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

示例:

// 普通链式查询示例
query().eq("name", "John").list(); // 查询 name 为 "John" 的所有记录
// lambda 链式查询示例
lambdaQuery().eq(User::getAge, 30).one(); // 查询年龄为 30 的单条记录
update

提供链式更新操作,可以连续调用方法来构建更新条件。

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

示例:

// 普通链式更新示例
update().set("status", "inactive").eq("name", "John").update(); // 将 name 为 "John" 的记录 status 更新为 "inactive"

// lambda 链式更新示例
User updateUser = new User();
updateUser.setEmail("new.email@example.com");
lambdaUpdate().set(User::getEmail, updateUser.getEmail()).eq(User::getId, 1).update(); // 更新 ID 为 1 的用户的邮箱

使用提示

  • 链式操作通过返回 QueryChainWrapper​ 或 UpdateChainWrapper​ 的实例,允许开发者连续调用方法来构建查询或更新条件。
  • lambda 链式操作提供了类型安全的查询条件构造,通过方法引用 Entity::getId​ 等方式,避免了字符串硬编码,提高了代码的可读性和安全性。
  • 在使用链式操作时,注意链式方法的调用顺序,通常是先设置条件,然后执行查询或更新操作。
  • 链式操作支持多种条件构造方法,如 eq​、ne​、gt​、lt​、like​ 等,可以根据实际需求选择合适的方法。
  • 链式操作返回的结果可以是单条记录、多条记录、总记录数等,具体取决于最后调用的方法。

通过使用 Chain,开发者可以更加高效地编写数据库操作代码,同时保持代码的清晰和可维护性。

6.4 ActiveRecord

ActiveRecord 模式是一种设计模式,它允许实体类直接与数据库进行交互,实体类既是领域模型又是数据访问对象。在 Mybatis-Plus 中,实体类只需继承 Model​ 类即可获得强大的 CRUD 操作能力。

注意, 使用 ActiveRecord 模式前,需要确保项目中已注入对应实体的 BaseMapper​。

使用步骤

继承 Model 类

import com.baomidou.mybatisplus.extension.activerecord.Model;

public class User extends Model<User> {
    // 实体类的字段定义...
    private Long id;
    private String name;
    private Integer age;
    // ... 其他字段和 getter/setter 方法
}

调用 CRUD 方法

// 创建新用户并插入数据库
User user = new User();
user.setName("John Doe");
user.setAge(30);
boolean isInserted = user.insert(); // 返回值表示操作是否成功

// 查询所有用户
List<User> allUsers = user.selectAll();

// 根据条件查询
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.le("age", "20");
List<User> users = user.selectList(userQueryWrapper);

// 根据 ID 更新用户信息
user.setId(1L);
user.setName("Updated Name");
boolean isUpdated = user.updateById(); // 返回值表示操作是否成功

// 根据 ID 删除用户
boolean isDeleted = user.deleteById(); // 返回值表示操作是否成功

使用提示

  • 在 ActiveRecord 模式下,实体类可以直接调用 insert​、selectAll​、updateById​、deleteById​ 等方法进行数据库操作。
  • 实体类继承 Model​ 类后,会自动获得一系列数据库操作方法,无需手动编写 SQL 语句。
  • 实体类中的字段需要与数据库表中的列对应,通常通过注解(如 @TableField​、@TableId​ 等)来指定字段与列的映射关系。
  • 在进行更新或删除操作时,通常需要先查询出实体对象,然后修改其属性,最后调用更新或删除方法。
  • 插入和更新操作通常会返回一个布尔值,表示操作是否成功。
  • 查询操作会返回相应的查询结果,如单个实体对象或实体对象列表。

通过使用 ActiveRecord 模式,开发者可以更加简洁地编写数据库操作代码,同时保持代码的清晰和可维护性。这种模式尤其适合于简单的 CRUD 操作,可以大大减少重复代码的编写。

7. 插件

8. Sql注入器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值