mybatisPlus使用说明介绍

MybatisPlus使用

简介

官网直通:https://mp.baomidou.com/

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

本文主要对一些特殊的地方(修改操作的返回值,insert的主键回写,wrapper的使用等)进行简单说明,对应和spring啦,springboot啦等的整合,官网上都有,不重复搬砖啦就。

特性:来自官网

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 注入攻击

版本Springboot方式

3.0.5

<properties>
	        <mybatisplus.version>3.0.5</mybatisplus.version>
	    </properties>

依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatisplus.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-generator</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

全局策略配置

1)默认驼峰转大写策略

mybatis-plus.global-config.db-config.column-underline=true

2)主键类型 AUTO:“数据库ID自增”, INPUT:“用户输入ID”, ID_WORKER:“全局唯一ID (数字类型唯一ID)”, UUID:“全局唯一ID UUID”;

mybatis-plus.global-config.db-config.id-type=UUID

3)全局tableName前缀,这个建议单表设置

mybatis-plus.global-config.db-config.table-prefix=tb_
  1. 单表设置

在这里插入图片描述
此外,还有一个@TableField注解

//value标识一个数据库字段对应关系,如果全局设置了下划线和大写的转换配置,则不用单独设置value属性的值
	// exist 默认true,设置为false的时候,表示MP在映射生成sql的时候,不加入(忽略)该字段,从而不会报什么“unkown column” in “field_list”等sql异常啦
    @TableField(value = "user_name",exist = false)
	private String userName;

关于columnMap

这里columnMap里:

key:是数据库表对应的字段名,不是对应实体属性名
	value:就是对应值啦

关于Wrapper

就是一个条件构造器,有很多链式调用的方法,在官网上都有详细的描述和举例:
【wrapper】https://mp.baomidou.com/guide/wrapper.html
这里说明都放到注释里啦

public List<AddressEntity> selectByQueryWrapper(AddressEntity addressEntity) {
// 2.x版本用 EntityWrapper
// 3.x版本用QueryWrapper --- 相当于where,注意这里的字段属性只是举例:
// 通过Condition.create(); 创建查询条件构造器QueryWrapper
// QueryWrapper<AddressDTO> condition = Condition.create();
// 通过 new QueryWrapper(); 创建查询条件构造器QueryWrapper 
        QueryWrapper<AddressEntity> queryWrapper = new QueryWrapper();
         queryWrapper.eq("user_name", addressEntity.getUserName())
                .ne("tel_number", addressEntity.getTelNumber()) // tel_number <> 获取过来的值
                .notIn("user_id", "1", "10722", "") //user_id not in( "1", "10722", "")
                .between("is_del", 0, 1) // is_del between 0 and 1
                .like("user_name", "w")// user_name like '%w%'
                .likeLeft("user_name", "w")// user_name like '%w'
                .likeRight("user_name", "w")// user_name like 'w%' //likeLeft、likeRight中的左右标识表示%的位置
                .isNull("user_name")// user_name is null 
                .groupBy(false, "user_name", "user_id")  // group by user_name,user_id ...
                .orderBy(false, true, "is_default"); //order by is_default asc

//另一种写法:lambda方式,就是通过属性名代替数据库字段名的方式进行条件构造
        QueryWrapper<AddressEntity> queryWrapper = new QueryWrapper();
        LambdaQueryWrapper<AddressEntity> lambda = queryWrapper.lambda();
        lambda.eq(e -> e.getUserName(), addressEntity.getTelNumber())
                .ne(e->e.getTelNumber(), addressEntity.getTelNumber())
                .ne(AddressEntity::getTelNumber, addressEntity.getTelNumber())
                .like(AddressEntity::getUserName, "w");

// select * from td_address where user_name = addressEntity.getUserName();

        List<AddressEntity> addressEntities = addressDao.selectList(queryWrapper);
// Map<String, Object> map = Maps.newHashMap();
// map.put("tel_number", addressEntity.getTelNumber());
// map.put("user_name", addressEntity.getUserName());
// addressDao.selectByMap(map);

// 修改时,用到UpdateWrapper,用法就是先set要修改的自选,后面跟修改的where条件:
        UpdateWrapper<AddressEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("user_name", "xixixi")
                .set("tel_number","13880800000")
                .eq("user_id", "1")//update xx set user_name ='xixixi', tel_number = '13880800000' where user_id = 1
                .eq(false, "is_del", "1");//update xx set user_name ='xixixi', tel_number = '13880800000' where user_id = 1
                
// 修改时,同查询也是有lambda的方式的 
// LambdaUpdateWrapper<AddressEntity> lambda1 = updateWrapper.lambda();
// lambda1.set(AddressEntity::getTelNumber, addressEntity.getTelNumber())
// .eq(e -> e.getUserName(), addressEntity.getTelNumber())
// .ne(e->e.getTelNumber(), addressEntity.getTelNumber())
// .like(AddressEntity::getUserName, "w");
        int update = addressDao.update(new AddressEntity(), updateWrapper);
        
其他方法比较简单,其他类似框架里也有,不再重复说明。这里主要是对常用的做简单介绍。

BaseMapper通用接口:

/* * Copyright (c) 2011-2020, hubin ([email protected]). * <p> * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */
package io.renren.utils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;

/* :` .:, :::,,. :: `:::::: ::` `,:,` .:` `:: `::::::::.:` `:';,` ::::, .:::` `@++++++++: `` :::` @+++++++++++# :::, #++++++++++++++` ,: `::::::;'##++++++++++ [email protected]#@;` ::::::::::::::::::::; #@####@, :::::::::::::::+#;::. @@######[email protected]:::::::::::::. #@:; , @@########':::::::::::: .#''':` ;##@@@+:##########@::::::::::: @#;.,:. #@@@######++++#####'::::::::: .##+,:#` @@@@@#####+++++'#####+::::::::` ,`::@#:` `@@@@#####++++++'#####+#':::::::::::@. @@@@######+++++''#######+##';::::;':,` @@@@#####+++++'''#######++++++++++` #@@#####++++++''########++++++++' `#@######+++++''+########+++++++; `@@#####+++++''##########++++++, @@######+++++'##########+++++#` @@@@#####+++++############++++; ;#@@@@@####++++##############+++, @@@@@@@@@@@###@###############++' @#@@@@@@@@@@@@###################+: `@#@@@@@@@@@@@@@@###################'` :@#@@@@@@@@@@@@@@@@@##################, ,@@@@@@@@@@@@@@@@@@@@################; ,#@@@@@@@@@@@@@@@@@@@##############+` .#@@@@@@@@@@@@@@@@@@#############@, @@@@@@@@@@@@@@@@@@@###########@, :#@@@@@@@@@@@@@@@@##########@, `##@@@@@@@@@@@@@@@########+, `[email protected]@@@@@@@@@@@@@@#####@:` `:@@@@@@@@@@@@@@##@;. `,'@@@@##@@@+;,` ``...`` _ _ /_ _ _/_. ____ / _ / / //_//_//_|/ /_\ /_///_/_\ Talk is cheap. Show me the code. _/ / */

/** * <p> * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能 * </p> * <p> * 这个 Mapper 支持 id 泛型 * </p> * * @author hubin * @since 2016-01-23 */
public interface BaseMapper<T> {

    /** * <p> * 插入一条记录 * 1) 返回受影响的条数 * 2)插入成功后,mp会自动将主键值会写到对应实体T中,直接get即可 * </p> * * @param entity 实体对象 */
    int insert(T entity);

    /** * <p> * 根据 ID 删除 * 1) 返回受影响的条数 * </p> * * @param id 主键ID */
    int deleteById(Serializable id);

    /** * <p> * 根据 columnMap 条件,删除记录 * 【这里columnMap里的key是数据库表对应的字段名,不是对应实体属性名】 * 1) 返回受影响的条数 * </p> * * @param columnMap 表字段 map 对象 */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /** * <p> * 根据 entity 条件,删除记录 * 1) 返回受影响的条数 * </p> * * @param queryWrapper 实体对象封装操作类(可以为 null) */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /** * <p> * 删除(根据ID 批量删除) * 1) 返回受影响的条数 * </p> * * @param idList 主键ID列表(不能为 null 以及 empty) */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /** * <p> * 根据 ID 修改 * 1)返回受影响的条数 * </p> * * @param entity 实体对象 */
    int updateById(@Param(Constants.ENTITY) T entity);

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

    /** * <p> * 根据 ID 查询 * </p> * * @param id 主键ID */
    T selectById(Serializable id);

    /** * <p> * 查询(根据ID 批量查询) * </p> * * @param idList 主键ID列表(不能为 null 以及 empty) */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /** * <p> * 查询(根据 columnMap 条件) * 【这里columnMap里的key是数据库表对应的字段名,不是对应实体属性名】 * </p> * * @param columnMap 表字段 map 对象 */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /** * <p> * 根据 entity 条件,查询一条记录 * </p> * * @param queryWrapper 实体对象 */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /** * <p> * 根据 Wrapper 条件,查询总记录数 * </p> * * @param queryWrapper 实体对象 */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /** * <p> * 根据 entity 条件,查询全部记录 * </p> * * @param queryWrapper 实体对象封装操作类(可以为 null) */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /** * <p> * 根据 Wrapper 条件,查询全部记录 * </p> * * @param queryWrapper 实体对象封装操作类(可以为 null) */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

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

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