前文已经整合过Mybatis-Plus,本篇记录一下一些Mybatis-Plus一些常用方法的使用
首先我们来到官网,https://baomidou.com/
点击快速开始可以看到以下目录
快速入门可以看上篇文章,https://blog.csdn.net/l_zl2021/article/details/129385836
本次从核心功能开始记录
点击代码生成器(旧),本次以代码生成器旧版作为演示
mybatis-plus自动生成器旧版适用于3.5.1以下版本,3.5.1以上需要使用新版,新版和旧版并不兼容
代码生成器是mybatis-plus为了简化开发而推出的功能,它的作用就是,只需要设置好相关配置,就可以对某一张数据表一键生成,实体类,控制层,业务层,和持久层的基本代码,不需要我们再一个个的手动创建。接下来看官网的说明
官网已经给出了核心的配置,可以根据提示去修改成为自己需要的代码生成工具,关于详细的配置,官网也已经给出了说明
新建一个SpringBoot项目,不再演示,直接进入导入依赖
com.baomidou mybatis-plus-boot-starter 3.4.1 com.baomidou mybatis-plus-generator 3.4.1 org.apache.velocity velocity-engine-core 2.3 io.springfox springfox-swagger2 2.9.2 io.springfox springfox-swagger-ui 2.9.2 mysql mysql-connector-java 8.0.13 com.alibaba druid-spring-boot-starter 1.2.9 org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
编写配置文件application.yml
#配置连接数据库
spring:datasource:username: 用户名password: 密码driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/库名?serverTimezone=Asia/Shanghai&characterEncoding=utf8type: com.alibaba.druid.pool.DruidDataSource#配置mybatis-plus
mybatis-plus:configuration:#日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#驼峰形式显示map-underscore-to-camel-case: true#扫描mapper.xml文件mapper-locations: classpath:mappers/*.xml
编写代码生成器,这里我放再和启动类的同一级目录下,编写,命名方式无所谓,根据官网给出的文档,整理如下
package com.lzl;import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;import java.util.ArrayList;
import java.util.List;/*** --效率,是成功的核心关键--** @Author lzl* @Date 2023/3/8 14:23*/
public class MybatisPlusGenerator {public static void main(String[] args) {//代码生成对象AutoGenerator mpg = new AutoGenerator();//默认模拟引擎 Veloctiympg.setTemplateEngine(new VelocityTemplateEngine());// 全局配置GlobalConfig gc = new GlobalConfig();gc.setAuthor("zhenLong");//开发人员名称gc.setOutputDir("项目绝对路径\\src\\main\\java");//代码生成目录gc.setFileOverride(true);// 是否覆盖同名文件,默认是falsegc.setEnableCache(false);// XML 二级缓存gc.setBaseResultMap(true);// XML ResultMapgc.setBaseColumnList(true);// XML columListgc.setServiceName("%sService");//去掉Service的前缀Igc.setSwagger2(true); //实体属性 Swagger2 注解,提前导入 Swagger 依赖mpg.setGlobalConfig(gc);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUsername("数据库用户名");dsc.setPassword("数据库密码");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUrl("jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");mpg.setDataSource(dsc);// 包配置PackageConfig pc = new PackageConfig();pc.setParent("com.lzl");//父类包名,和创建项目时起的包名一致//pc.setModuleName("user");//在父类包下再创建一个包(可以设置不同模块生成不同包)//手动设置包名pc.setEntity("pojo");//实体类包名pc.setMapper("mapper");//mapper接口包名pc.setXml("mappers");//mapper.xml文件包名mpg.setPackageInfo(pc);// 策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略:下划线转驼峰strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略, 未指定按照 naming 执行strategy.setEntityLombokModel(true);//实体是否为lombok模型strategy.setRestControllerStyle(true);//生成 @RestController 控制器strategy.setControllerMappingHyphenStyle(true);//驼峰转连字符//strategy.setTablePrefix("t_");//生成代码时类名不带表前缀//手动指定映射表名(不写参数映射所有表)strategy.setInclude("user");//通过表名对当前表生成代码//strategy.setLikeTable(new LikeTable("t_"));//生成以t_开头的多张表的代码mpg.setStrategy(strategy);//解决Mapper.xml生成位置// 自定义配置InjectionConfig cfg = new InjectionConfig() {@Overridepublic void initMap() {// to do nothing}};// 如果模板引擎是 freemarker// String templatePath = "/templates/mapper.xml.ftl";// 如果模板引擎是 velocityString templatePath = "/templates/mapper.xml.vm";// 自定义输出配置List focList = new ArrayList<>();// 自定义配置会被优先输出focList.add(new FileOutConfig(templatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名以及位置 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return "项目的绝对路径/src/main/resources/mappers/"+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}});/*cfg.setFileCreate(new IFileCreate() {@Overridepublic boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {// 判断自定义文件夹是否需要创建checkDir("调用默认方法创建的目录,自定义目录用");if (fileType == FileType.MAPPER) {// 已经生成 mapper 文件判断存在,不想重新生成返回 falsereturn !new File(filePath).exists();}// 允许生成模板文件return true;}});*/cfg.setFileOutConfigList(focList);mpg.setCfg(cfg);// 配置模板TemplateConfig templateConfig = new TemplateConfig();// 配置自定义输出模板//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别// templateConfig.setEntity("templates/entity2.java");// templateConfig.setService();// templateConfig.setController();templateConfig.setXml(null);//不生成系统配置的xml文件mpg.setTemplate(templateConfig);// 执行生成mpg.execute();}
}
配置完成,点击运行mian方法即可,注意,一定要开启数据库服务,如下:
生成完成,检查目录结构如下:
需要注意的是,生成器可以自动生成Swagger注解的实体类,但某些注解还是需要自己手动添加,例如,有参和无参构造,和持久层接口的@Repository
mybatis-plus帮我们自动生成的mapper.xml映射文件中,已经有了基本的resultMap结果集映射,和sql片段。当mybaits-plus内部封装的基本CRUD方法无法满足业务需求的时候需要我们自己按照mybatis的方法进行手动编写除此之外
(报红是插件的问题,不影响使用)
mybatis-plus内部帮我们封装了基本上所有的基础CRUD,我们可以在代码生成器的基础上,直接调用mapper层的方法,如果需要增加额外的业务逻辑,例如,对传给前端的数据返回格式进行加工。最好还是在service业务层的实现类进行额外逻辑代码的编写。
官方给出的说明
我需要对返回值进行改造,所以还是在service业务层的中间稍微做了一些编码工作,如果不需要改造,可以直接调用持久层接口,或者改造返回值的任务交给Controller层,这个看个人喜好
controller层
package com.lzl.controller;import com.lzl.pojo.User;
import com.lzl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Map;/*** * 前端控制器*
** @author zhenLong* @since 2023-03-08*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService service;@RequestMapping("/insert")public Map insert(User user){return service.addNew(user);}
}
ServiceImpl
package com.lzl.service.impl;import com.lzl.pojo.User;
import com.lzl.mapper.UserMapper;
import com.lzl.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;/*** * 服务实现类*
** @author zhenLong* @since 2023-03-08*/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {@Autowiredprivate UserMapper mapper;@Overridepublic Map addNew(User user) {Map map = new HashMap<>();int key = mapper.insert(user);//mapper接口自带的新增方法,直接调用if(key != 0){map.put("code",0);map.put("msg","新增成功!");}else {map.put("code",1);map.put("msg","新增失败!");}return map;}
}
此时,我的mapper接口没有写任何代码,接着运行项目,打开postman进行测试
新增成功
删除方法的controller层就不再展示了,这里只展示ServiceImpl,
@Overridepublic Map delete(Integer id) {Map map = new HashMap<>();int key = mapper.deleteById(id);if(key != 0){map.put("code",0);map.put("msg","删除成功!");}else {map.put("code",1);map.put("msg","删除失败!");}return map;}
测试,删除刚才我新增的那一条数据
批量删除
controller层
@RequestMapping("/deleteList")public Map deleteList(@Param("ids") Integer[] ids){return service.deleteList(ids);}
ServiceImpl
@Overridepublic Map deleteList(Integer[] ids) {List list = Arrays.asList(ids);Map map = new HashMap<>();int key = mapper.deleteBatchIds(list);if(key != 0){map.put("code",0);map.put("msg","删除成功!");}else {map.put("code",1);map.put("msg","删除失败!");}return map;}
测试
ServiceImpl
@Overridepublic Map updateInfo(User user) {Map map = new HashMap<>();int key = mapper.updateById(user);//直接调用if(key != 0){map.put("code",0);map.put("msg","修改成功!");}else {map.put("code",1);map.put("msg","修改失败!");}return map;}
查询所有
ServiceImpl
@Overridepublic Map getAll() {Map map = new HashMap<>();List list = mapper.selectList(null);Integer count = mapper.selectCount(null);if(list.size() != 0){map.put("code",0);map.put("data",list);map.put("count",count);}else {map.put("code",1);map.put("msg","没有数据!");}return map;}
条件查询+分页
条件查询需要用到Mybatis-plus自定义查询参数对象Wrapper< T >,并且配置分页插件
首先配置分页插件
package com.lzl.config;import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Configuration;
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;/*** --效率,是成功的核心关键--** @Author lzl* @Date 2023/3/8 16:11*/
@Configuration
public class MybatisPlusConfig {/*** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页插件return interceptor;}}
测试
模糊查询
controller
@RequestMapping("/getAllByKeyWords")public Map getAllByKeyWords(String username){return service.getAllByKeyWords(username);}
ServiceImpl
@Overridepublic Map getAllByKeyWords(String username) {Map map = new HashMap<>();QueryWrapper wrapper = new QueryWrapper<>();wrapper.like("username",username);List list = mapper.selectList(wrapper);if(list.size() != 0){map.put("code",0);map.put("data",list);}else {map.put("code",1);map.put("msg","没有数据!");}return map;}
测试
本篇记录了Mybatis-plus的代码生成器和基本CRUD方法的使用,更多内容见下篇