前言
前文已经整合过Mybatis-Plus,本篇记录一下一些Mybatis-Plus一些常用方法的使用
一、代码生成器
1、简介
首先我们来到官网,https://baomidou.com/
点击快速开始可以看到以下目录
快速入门可以看上篇文章,https://blog.csdn.net/l_zl2021/article/details/129385836
本次从核心功能开始记录
点击代码生成器(旧),本次以代码生成器旧版作为演示
mybatis-plus自动生成器旧版适用于3.5.1以下版本,3.5.1以上需要使用新版,新版和旧版并不兼容
代码生成器是mybatis-plus为了简化开发而推出的功能,它的作用就是,只需要设置好相关配置,就可以对某一张数据表一键生成,实体类,控制层,业务层,和持久层的基本代码,不需要我们再一个个的手动创建。接下来看官网的说明
官网已经给出了核心的配置,可以根据提示去修改成为自己需要的代码生成工具,关于详细的配置,官网也已经给出了说明
2、使用步骤
新建一个SpringBoot项目,不再演示,直接进入导入依赖
<dependencies>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- mybatis-plus 代码生成 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!-- mybatis-plus默认模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
编写配置文件application.yml
#配置连接数据库
spring:
datasource:
username: 用户名
password: 密码
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/库名?serverTimezone=Asia/Shanghai&characterEncoding=utf8
type: 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();
//默认模拟引擎 Veloctiy
mpg.setTemplateEngine(new VelocityTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setAuthor("zhenLong");//开发人员名称
gc.setOutputDir("项目绝对路径\\src\\main\\java");//代码生成目录
gc.setFileOverride(true);// 是否覆盖同名文件,默认是false
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);// XML ResultMap
gc.setBaseColumnList(true);// XML columList
gc.setServiceName("%sService");//去掉Service的前缀I
gc.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() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名以及位置 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return "项目的绝对路径/src/main/resources/mappers/"
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
/*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
checkDir("调用默认方法创建的目录,自定义目录用");
if (fileType == FileType.MAPPER) {
// 已经生成 mapper 文件判断存在,不想重新生成返回 false
return !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
二、MybatisPlus常用方法
1.基本的CRUD
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;
/**
* <p>
* 前端控制器
* </p>
*
* @author zhenLong
* @since 2023-03-08
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService service;
@RequestMapping("/insert")
public Map<String,Object> 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;
/**
* <p>
* 服务实现类
* </p>
*
* @author zhenLong
* @since 2023-03-08
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper mapper;
@Override
public Map<String, Object> addNew(User user) {
Map<String, Object> 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,
@Override
public Map<String, Object> delete(Integer id) {
Map<String, Object> 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<String,Object> deleteList(@Param("ids") Integer[] ids){
return service.deleteList(ids);
}
ServiceImpl
@Override
public Map<String, Object> deleteList(Integer[] ids) {
List<Integer> list = Arrays.asList(ids);
Map<String, Object> 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
@Override
public Map<String, Object> updateInfo(User user) {
Map<String, Object> 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
@Override
public Map<String, Object> getAll() {
Map<String, Object> map = new HashMap<>();
List<User> 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 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页插件
return interceptor;
}
}
测试
模糊查询
controller
@RequestMapping("/getAllByKeyWords")
public Map<String,Object> getAllByKeyWords(String username){
return service.getAllByKeyWords(username);
}
ServiceImpl
@Override
public Map<String, Object> getAllByKeyWords(String username) {
Map<String, Object> map = new HashMap<>();
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("username",username);
List<User> 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方法的使用,更多内容见下篇