MyBatisPlus的使用介绍

什么是MyBatisPlus:

MyBatisPlus是主流orm框架-MyBatis的增强版本,是对MyBatis的进一步封装和拓展,可以提供更方便、快捷的api来访问持久层数据。

特性:

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

  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

安装和配置:

依赖引入:
<!-- mybatis-plus orm框架 -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.5.5</version>
</dependency>
​
<!-- mybatis-plus代码生成器 -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-generator</artifactId>
  <version>3.5.2</version>
</dependency>



配置:



@Slf4j
@Configuration
@MapperScan(basePackages = {"com.demo.mapper"})
public class MyBatisPlusConfig {
  
  /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
        //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
        return interceptor;
    }

    @Bean(name = "myBatisPlusSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
        log.info("开始mybatis-plus配置");

        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();

        factoryBean.setDataSource(dataSource);
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        //加载项目时显示mp图标
        globalConfig.setBanner(true);
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setIdType(IdType.ASSIGN_UUID);
        //设置主键类型
        globalConfig.setDbConfig(dbConfig);
        //具体配置
        MybatisConfiguration configuration = new MybatisConfiguration();
        //设置日志打印实现类
        configuration.setLogImpl(Slf4jImpl.class);
        //开启自动驼峰命名规则(camel case)映射
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setUseGeneratedKeys(true);
        factoryBean.setConfiguration(configuration);
        ResourcePatternResolver resourceLoader =  new PathMatchingResourcePatternResolver();
        factoryBean.setMapperLocations(resourceLoader.getResources("classpath*:mapper/**/*Dao.xml"));
        factoryBean.setTypeAliasesPackage("com.demo.**.mod");
        //全局设置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setMetaObjectHandler(mybatisPlusMetaObjectHandler);
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setIdType(IdType.ASSIGN_UUID);
        globalConfig.setDbConfig(dbConfig);
        factoryBean.setGlobalConfig(globalConfig);
        return factoryBean.getObject();
    }
	
	@Bean(name = "plusSqlSessionTemplate")
    public SqlSessionTemplate plusSqlSessionTemplate(@Qualifier("plusSqlSessionFactory")         
     SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new     
        SqlSessionTemplate(sqlSessionFactory);
        return sqlSessionTemplate;
    }
}



注意:如果mybatisplus和mybatis混用,必须配置各自的SqlSessionTemplate,用来管理各自的sql方法;

拓展:
  • 字段自动填充设置:

/**
 * @说明: mybatis-plus公共字段填充配置处理类
 * @作者 cql
 * @日期 2024/1/2 14:14
 */
@Slf4j
@Component
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {

    public MybatisPlusMetaObjectHandler() {
        log.info("是否开启字段填充:{}", this.openUpdateFill() && this.openInsertFill());
        log.info("MybatisPlusMetaObjectHandler初始化完成");
    }

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("mybatis-plus开始插入字段填充");
        SysUser sysUser = ShiroUtils.getSysUser();
        if (ObjectUtils.isEmpty(sysUser)){
            throw new RuntimeException("用户尚未登录");
        }
        if (ObjectUtils.isNotEmpty(metaObject)){
            try {
                Date date = new Date();
                this.fillStrategy(metaObject, "createBy", sysUser.getUserId());
                this.fillStrategy(metaObject, "createTime", date);
                this.fillStrategy(metaObject, "updateTime", date);
                this.fillStrategy(metaObject, "flag", 1);
            } catch (Exception e) {
                log.error("mybatis-plus新增公共字段填充异常:", e);
            }
        }

    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("mybatis-plus开始更新字段填充");
        SysUser sysUser = ShiroUtils.getSysUser();
        if (ObjectUtils.isEmpty(sysUser)){
            throw new RuntimeException("用户尚未登录");
        }
        if (ObjectUtils.isNotEmpty(metaObject)){
            try {
                this.fillStrategy(metaObject, "updateBy", sysUser.getUserId());
                this.fillStrategy(metaObject, "updateTime", new Date());
            } catch (Exception e) {
                log.error("mybatis-plus更新公共字段填充异常:", e);
            }
        }
    }
}
代码生成器配置:



/**
 * @说明:
 * @作者 cql
 * @日期 2023/12/23 08:05
 */
public class MybatisPlusGenerator {

    /**
     * 代码生成路径
     */
    private static final String OUTPUT_DIR_PATH = "D:\\java-workspace\\RuoYiSingle\\custom-demo\\src\\main\\java";

    /**
     * 父路径包名
     */
    public static final String PARENT_PACKAGE_NAME = "com.demo";

    public static final String PARENT_MAPPER_XML_PATH = "D:\\java-workspace\\RuoYiSingle\\custom-demo\\src\\main" +
            "\\resources\\mapper\\";

    public static final String PARENT_TEMPLATE_PATH = "templates/mybatisplus/";

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/ry", "root", "123456")
                // 全局配置
                .globalConfig((scanner, builder) -> {
                    builder.author(scanner.apply("请输入作者名称?"));
                    builder.enableSwagger();
                    builder.outputDir(OUTPUT_DIR_PATH);
                    builder.dateType(DateType.ONLY_DATE);
                })
                // 包配置
                .packageConfig((scanner, builder) -> {
                    String moduleName = scanner.apply("请输入新增业务模块名称?");
//                    builder.parent(scanner.apply("请输入包名?"));
                    builder.parent(PARENT_PACKAGE_NAME);
                    builder.controller(String.join(".", "controller", moduleName));
                    builder.entity(String.join(".", "mod", moduleName));
                    builder.service(String.join(".", "server", moduleName));
                    builder.serviceImpl(String.join(".", "server", moduleName, "impl"));
                    builder.mapper(String.join(".", "mapper", moduleName));
                    builder.pathInfo(Collections.singletonMap(OutputFile.xml, PARENT_MAPPER_XML_PATH));
                })
                //模板配置
                .templateConfig(builder -> {
                    builder.controller(PARENT_TEMPLATE_PATH + "controller.java.vm");
                    builder.entity(PARENT_TEMPLATE_PATH + "entity.java.vm");
                    builder.entityKt(PARENT_TEMPLATE_PATH + "entity.kt.vm");
                    builder.mapper(PARENT_TEMPLATE_PATH + "mapper.java.vm");
                    builder.xml(PARENT_TEMPLATE_PATH + "mapper.xml.vm");
                    builder.service(PARENT_TEMPLATE_PATH + "service.java.vm");
                    builder.serviceImpl(PARENT_TEMPLATE_PATH + "serviceImpl.java.vm");
                })
                // 策略配置
                .strategyConfig((scanner, builder) -> {
                    builder.addInclude(MybatisPlusGenerator.getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
                            .controllerBuilder().enableRestStyle().enableHyphenStyle().build();
//                    builder.controllerBuilder()
//                            .superClass(BaseController.class)
//                                    .build();
                    builder.serviceBuilder()
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            .build();
                    //表前缀过滤配置
                    builder.addTablePrefix("demo_")
                            .build();
                    builder.mapperBuilder()
                            .formatMapperFileName("%sDao")
                            .formatXmlFileName("%sDao")
                            .enableBaseResultMap()
                            .enableBaseColumnList()
                            .fileOverride()
                            .build();
                    //entity的策略配置
                    builder.entityBuilder()
                            .enableLombok()
                            .enableTableFieldAnnotation()
                            //开启字段activeRecord模式
                            .enableActiveRecord()
                            .columnNaming(NamingStrategy.underline_to_camel)
                            .idType(IdType.AUTO)
                            .addTableFills(
                                    new Column("create_by", FieldFill.INSERT),
                                    new Column("update_by", FieldFill.UPDATE),
                                    new Column("create_time", FieldFill.INSERT),
                                    new Column("update_time", FieldFill.INSERT_UPDATE),
                                    new Column("flag", FieldFill.INSERT)
                            )
                            .fileOverride()
//                            .formatFileName("%sEntity")
                            .build();
                })
                .execute();
    }
}



模板设置:
  • controller.java.vm:

package ${package.Controller};

import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import com.demo.utils.QueryGenerator;
import com.ruoyi.common.core.domain.AjaxResult;
import org.apache.commons.lang3.ObjectUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
#if(${restControllerStyle})
import org.springframework.web.bind.annotation.RestController;
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
#end

/**
 * $!{table.comment}
 * @author ${author}
 * @since ${date}
 */
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
#if(${swagger})
@Api(tags = "$!{table.comment}")
#end
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
@Slf4j
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end

#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end

    @Autowired
    private ${table.serviceName} service;

    @ApiOperation(value = "列表查询")
    @PostMapping("/list")
    public AjaxResult list(@RequestBody ${entity} vo, HttpServletRequest request){
        try{
            Map<String, String[]> parameterMap = request.getParameterMap();
            LambdaQueryWrapper<${entity}> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
            Page<${entity}> page = QueryGenerator.initPageInfo(parameterMap);
            if (ObjectUtils.isEmpty(page)){
                return AjaxResult.success(service.list(queryWrapper));
            }
            return AjaxResult.success(service.page(page, queryWrapper));
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

#foreach($field in ${table.fields})
#if(${field.keyFlag})
#if(${field.keyIdentityFlag} || !$null.isNull(${idType}) && "$!idType" != "" || ${field.convert})
#set($idPropertyName=${field.propertyName})
#set($idPropertyType=${field.propertyType})
    @ApiOperation(value = "根据id查询")
    @GetMapping("/getById")
    public AjaxResult getById(@RequestParam ${idPropertyType} ${idPropertyName}){
        try{
            return AjaxResult.success(service.getById(${idPropertyName}));
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }
#end
#end
#end

    @ApiOperation(value = "新增$!{table.comment}")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody ${entity} vo){
        try{
            service.save(vo);
            return AjaxResult.success();
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @ApiOperation(value = "修改或逻辑删除$!{table.comment}")
    @PostMapping("/update")
    public AjaxResult update(@RequestBody ${entity} vo){
        try{
            service.updateById(vo);
            return AjaxResult.success();
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

#foreach($field in ${table.fields})
#if(${field.keyFlag})
#if(${field.keyIdentityFlag} || !$null.isNull(${idType}) && "$!idType" != "" || ${field.convert})
#set($idPropertyName=${field.propertyName})
#set($idPropertyType=${field.propertyType})
    @ApiOperation(value = "根据id删除")
    @GetMapping("/delById")
    public AjaxResult delById(@RequestParam ${idPropertyType} ${idPropertyName}){
        try{
            service.removeById(${idPropertyName});
            return AjaxResult.success();
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }
#end
#end
#end

    @ApiOperation(value = "根据查询条件导出excel")
    @PostMapping("/exportExcel")
    public void exportExcel(@RequestBody ${entity} vo, HttpServletResponse response, HttpServletRequest request){
        try{
            Map<String, String[]> parameterMap = request.getParameterMap();
            LambdaQueryWrapper<${entity}> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
            service.exportExcel(queryWrapper, response);
        }catch(Exception e){
            log.error("根据查询条件导出excel-异常:", e);
        }
    }
}
#end
  • service.java.vm
package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * $!{table.comment} 服务类
 * @author ${author}
 * @since ${date}
 */
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    void exportExcel(LambdaQueryWrapper<${entity}> queryWrapper, HttpServletResponse response);
}
#end
  • serviceImpl.java.vm
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Objects;
import com.demo.exception.ServiceException;
import java.io.OutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.net.URLEncoder;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * $!{table.comment} 服务实现类
 * @author ${author}
 * @since ${date}
 */
@Slf4j
@Service
#if(${kotlin})
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

}
#else
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {

    @Autowired
    private ${table.mapperName} dao;

    @Override
    public void exportExcel(LambdaQueryWrapper<${entity}> queryWrapper, HttpServletResponse response){
        //根据条件查询列表数据
        List<${entity}> poList = this.list(queryWrapper);
        if (ObjectUtils.isEmpty(poList) || poList.stream().allMatch(Objects::isNull)){
            throw new ServiceException("数据不存在");
        }
        try(OutputStream outputStream = response.getOutputStream()) {
            //构建响应头数据
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            String fileName = URLEncoder.encode(StringUtils.joinWith("-", "$!{table.comment}", System.currentTimeMillis() +
            ".xlsx"),
            StandardCharsets.UTF_8.name());
            response.setHeader("Content-disposition", "attachment;filename*=" + fileName);
            EasyExcel.write(outputStream).sheet("sheet1").head(${entity}.class).doWrite(poList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
#end
  • entity.java.vm
package ${package.Entity};

#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
#if(${activeRecord})
import lombok.EqualsAndHashCode;
#end
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;

/**
 * $!{table.comment} 实体类
 * @author ${author}
 * @since ${date}
 */
#if(${activeRecord})
@EqualsAndHashCode(callSuper = true)
#end
#if(${entityLombokModel})
@Data
  #if(${chainModel})
@Accessors(chain = true)
  #end
#end
#if(${table.convert})
@TableName("${schemaName}${table.name}")
#end
#if(${swagger})
@ApiModel(value = "${entity}对象", description = "$!{table.comment}")
#end
@HeadRowHeight(38)
@ContentRowHeight(20)
@ColumnWidth(22)
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#elseif(${entitySerialVersionUID})
public class ${entity} implements Serializable {
#else
public class ${entity} {
#end
#if(${entitySerialVersionUID})

    private static final long serialVersionUID = 1L;
#end
## ----------  BEGIN 字段循环遍历  ----------
#foreach($field in ${table.fields})

#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
  #if(${swagger})
    @ApiModelProperty("${field.comment}")
  #else
    /**
     * ${field.comment}
     */
  #end
#end
#if(${field.keyFlag})
## 主键
  #if(${field.keyIdentityFlag})
    @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
    @ExcelIgnore
  #elseif(!$null.isNull(${idType}) && "$!idType" != "")
    @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
    @ExcelIgnore
  #elseif(${field.convert})
    @TableId("${field.annotationColumnName}")
    @ExcelIgnore
  #end
## 普通字段
#elseif(${field.fill})
## -----   存在字段填充设置   -----
  #if(${field.convert})
    @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
    @ExcelProperty("${field.comment}")
  #else
    @TableField(fill = FieldFill.${field.fill})
    @ExcelProperty("${field.comment}")
  #end
#elseif(${field.convert})
    @TableField("${field.annotationColumnName}")
    @ExcelProperty("${field.comment}")
#end
  #if(${field.propertyType.equals("Date")})
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
  #end
## 乐观锁注解
#if(${field.versionField})
    @Version
#end
## 逻辑删除注解
#if(${field.logicDeleteField})
    @TableLogic
#end
    private ${field.propertyType} ${field.propertyName};
#end
## ----------  END 字段循环遍历  ----------

#if(!${entityLombokModel})
#foreach($field in ${table.fields})
  #if(${field.propertyType.equals("boolean")})
    #set($getprefix="is")
  #else
    #set($getprefix="get")
  #end

    public ${field.propertyType} ${getprefix}${field.capitalName}() {
        return ${field.propertyName};
    }

  #if(${chainModel})
    public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
  #else
    public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
  #end
        this.${field.propertyName} = ${field.propertyName};
  #if(${chainModel})
        return this;
  #end
    }
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--

#if(${entityColumnConstant})
  #foreach($field in ${table.fields})
    public static final String ${field.name.toUpperCase()} = "${field.name}";

  #end
#end
#if(${activeRecord})
    @Override
    public Serializable pkVal() {
  #if(${keyPropertyName})
        return this.${keyPropertyName};
  #else
        return null;
  #end
    }

#end
#if(!${entityLombokModel})
    @Override
    public String toString() {
        return "${entity}{" +
  #foreach($field in ${table.fields})
    #if($!{foreach.index}==0)
        "${field.propertyName}=" + ${field.propertyName} +
    #else
        ", ${field.propertyName}=" + ${field.propertyName} +
    #end
  #end
        "}";
    }
#end
}



使用方法示例:

  • 普通crud操作:

//查询列表
List<Student> poList = this.list(new LambdaQueryWrapper<Student>().eq(Student::getTheClass, "3-2")
                                 .eq(Student::getFlag, false));
//单个查询
Student po = this.getOne(new LambdaQueryWrapper<Student>().eq(Student::getName, "张三"));
//单个新增
this.save(new Student());
//批量新增
this.saveBatch(Arrays.asList(new Student(), new Student()));
//单个修改
this.updateById(new Student());
//根据id删除
this.removeById(1);



  • 链式条件构造



//更加简洁的链式条件构造
List<Student> poList2 = this.lambdaQuery().eq(Student::getTheClass, "3-2").eq(Student::getFlag, false).list();
this.lambdaUpdate().eq(Student::getName, "张三").set(Student::getTheClass, "3-3").update();



  • 便捷的新增或更新操作



//有记录则更新,无记录则新增(对应mysql insert into table(id,name)values(?,?) on duplicate key update name = ?)
this.saveOrUpdate(new Student());



  • 简单查询工具的使用

//获取表中的某个字段,并对字段做操作
List<String> nameList = new ArrayList<>();
SimpleQuery.list(new LambdaQueryWrapper<>(), Student::getAge, c -> nameList.add(c.getName()));
//根据某个字段分组获取一个map,以该字段为key并指定value的值
Map<String, List<String>> theClassAndNameGroup = SimpleQuery.group(new LambdaQueryWrapper<>(),
                                                                   Student::getTheClass,
                                                                   Collectors.mapping(Student::getName,
                                                                   Collectors.toList()));
//根据字段分组并统计每组包含元素的数量
Map<String, Long> theClassGroupStatistics = SimpleQuery.group(new LambdaQueryWrapper<>(), Student::getTheClass,
                                                              Collectors.counting());
  • 针对QueryWrapper自行封装的QueryGenerator类(参考jeecgboot),可以实现查询条件自动构建,无需改动后端代码即可实现模糊查询,区间查询和分页操作;



@ApiOperation(value = "列表查询")
@PostMapping("/list")
public AjaxResult list(@RequestBody Student vo, HttpServletRequest request){
  try{
    Map<String, String[]> parameterMap = request.getParameterMap();
    LambdaQueryWrapper<Student> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
    Page<Student> page = QueryGenerator.initPageInfo(parameterMap);
    if (ObjectUtils.isEmpty(page)){
      return AjaxResult.success(service.list(queryWrapper));
    }
    return AjaxResult.success(service.page(page, queryWrapper));
  }catch(Exception e){
    return AjaxResult.error(e.getMessage());
  }
}



  • 时间区间查询



image.png



  • 模糊查询



image.png



  • 智能分页查询

不分页时:



image.png



添加分页参数进行分页:



image.png



MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,它拓展了 MyBatis 的功能,提供了许多实用的功能,简化了开发流程,提高了开发效率。 下面是 MyBatis-Plus 的使用步骤: 1. 引入 MyBatis-Plus 的依赖包。 Maven 项目需要在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本</version> </dependency> ``` 2. 配置 MyBatis-Plus 的相关参数。 MyBatis-Plus 的配置文件通常是在 application.yml 或 application.properties 文件中进行配置。 例如,在 application.yml 文件中添加以下配置: ```yaml mybatis-plus: mapper-locations: classpath:mapper/*.xml # mapper 文件的位置 global-config: db-config: id-type: auto # 主键类型为自增 field-strategy: not_empty # 字段非空检查 logic-delete-value: 1 # 逻辑删除值 logic-not-delete-value: 0 # 逻辑未删除值 ``` 3. 创建实体类。 在 MyBatis-Plus 中,实体类需要继承 Model 类,同时需要使用 @TableName 注解指定表名,@TableField 注解指定字段名。 例如,创建一个 User 实体类: ```java import com.baomidou.mybatisplus.annotation.*; import lombok.Data; @Data @TableName("user") public class User extends Model<User> { @TableId(type = IdType.AUTO) private Long id; @TableField(value = "username") private String username; @TableField(value = "password") private String password; @TableLogic @TableField(value = "is_deleted") private Integer deleted; } ``` 4. 创建 Mapper 接口。 在 MyBatis-Plus 中,Mapper 接口需要继承 BaseMapper 接口,同时需要使用 @Mapper 注解指定 Mapper 的名称。 例如,创建一个 UserMapper 接口: ```java import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<User> { } ``` 5. 使用 MyBatis-Plus 进行 CRUD 操作。 MyBatis-Plus 提供了许多常用的方法,例如:insert、update、delete、selectById、selectList 等等。使用这些方法可以快速地进行 CRUD 操作。 例如,使用 MyBatis-Plus 进行查询操作: ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserMapper userMapper; public User getById(Long id) { return userMapper.selectById(id); } public List<User> getList() { return userMapper.selectList(null); } public List<User> getByUsername(String username) { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("username", username); return userMapper.selectList(queryWrapper); } public int save(User user) { return userMapper.insert(user); } public int update(User user) { return userMapper.updateById(user); } public int delete(Long id) { return userMapper.deleteById(id); } } ``` 至此,MyBatis-Plus 的使用介绍完了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值