前言
本篇文章介绍博主在公司工作时,如何使用Mybatis-plus。
什么是Mybatis-plus?
它是Mybatis的增强工具,只做增强功能而不改变。Mybatis是一个半ORM框架,内部封装了JDBC。由于博主不喜欢将SQL写在代码中(解耦),故不提供QueryWrapper构造器、注解开发。
快速上手
- 配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.17.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ucap</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>这是一个springboot项目</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入mybatis-plus相关依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!--mysql相关配置-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 一键生成代码器
package com.ucap.demo.utils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
public class MybatisGenerator {
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
//1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java"); //生成路径(一般都是生成在此项目的src/main/java下面)
gc.setAuthor("jack deng"); //设置作者
gc.setOpen(false);
gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
// gc.setBaseResultMap(true); //生成resultMap
// gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost/communication?serverTimezone=Asia/Shanghai");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
//dsc.setSchemaName("dmjk");
mpg.setDataSource(dsc);
// 3、包配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName("sys");
pc.setParent("com.ucap.demo");
mpg.setPackageInfo(pc);
// 4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperControllerClass("com.lcy.demo.sys.controller.BaseController");
// strategy.setSuperEntityClass("com.lcy.demo.sys.entity.BaseEntity");
strategy.setTablePrefix("org_"); // 表名前缀
strategy.setEntityLombokModel(true); //使用lombok
strategy.setInclude("org_department"); // 逆向工程使用的表 如果要生成多个,这里可以传入String[]
mpg.setStrategy(strategy);
//5、执行
mpg.execute();
}
}
- 配置application.yml文件
##设置端口号
server:
port: 9000
##设置服务名
spring:
application:
name: demo
##配置数据库连接信息
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1/communication?allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
##设置mapper.xml路径
mybatis-plus:
mapper-locations: classpath:mapping/*.xml
##打印sql
logging:
level:
com.ucap.demo.mapper: debug
4.启动类设置扫描mapper路径
@MapperScan("com.ucap.demo.mapper")
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
5.在DepartmentMapper接口添加注解
@Repository
public interface DepartmentMapper extends BaseMapper<Department> {
}
6.在DepartmentController替换注解
@RestController
@RequestMapping("department")
public class DepartmentController {}
7.springboot服务结构目录
实战
1.CRUD示例,一般使用mybatis-plus提供的方法进行新增,修改,删除,其它接口视情况而定。
(1)、DepartmentController代码示例。
package com.ucap.demo.controller;
import com.ucap.demo.service.DepartmentService;
import com.ucap.demo.utils.parameter.ReqPageParams;
import com.ucap.demo.utils.parameter.ResResultType;
import com.ucap.demo.vo.DeptVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 部门表 前端控制器
* </p>
*
* @author jack deng
* @since 2023-02-27
*/
@RestController
@RequestMapping("department")
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
/**
* 新增
* @param deptVo
* @return
*/
@RequestMapping("insert")
public ResResultType insert(@RequestBody DeptVo deptVo) {
departmentService.insert(deptVo);
return ResResultType.success();
}
/**
* 修改
* @param deptVo
* @return
*/
@RequestMapping("update")
public ResResultType update(@RequestBody DeptVo deptVo) {
departmentService.update(deptVo);
return ResResultType.success();
}
/**
* 删除
* @param id
* @return
*/
@RequestMapping("delete")
public ResResultType delete(Long id) {
departmentService.delete(id);
return ResResultType.success();
}
/**
* 分页查询
* @param req
* @return
*/
@RequestMapping("pageList")
public ResResultType pageList(@RequestBody ReqPageParams req) {
return ResResultType.create(departmentService.pageList(req));
}
/**
* 部门树
* @return
*/
@RequestMapping("deptTree")
public ResResultType deptTree(){
return ResResultType.create(departmentService.deptTree());
}
/**
* 根据id查询列表
*/
@RequestMapping("idsPageList")
public ResResultType idsPageList(@RequestBody List<Long> ids){
return ResResultType.create(departmentService.idsPageList(ids));
}
}
(2)、DepartmentServiceImpl代码示例
package com.ucap.demo.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ucap.demo.dto.DeptDto;
import com.ucap.demo.dto.DeptTreeDto;
import com.ucap.demo.entity.Department;
import com.ucap.demo.mapper.DepartmentMapper;
import com.ucap.demo.service.DepartmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ucap.demo.utils.Snowflake;
import com.ucap.demo.utils.parameter.ReqPageParams;
import com.ucap.demo.vo.DeptVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
/**
* <p>
* 部门表 服务实现类
* </p>
*
* @author jack deng
* @since 2023-02-27
*/
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Override
public void insert(DeptVo deptVo) {
Department department = new Department();
department.setId(Snowflake.getId());
BeanUtils.copyProperties(deptVo, department);
department.setIsDel(0);
department.setCreateTime(LocalDateTime.now());
departmentMapper.insert(department);
}
@Override
public void update(DeptVo deptVo) {
Department department = new Department();
BeanUtils.copyProperties(deptVo, department);
department.setIsDel(0);
department.setUpdateTime(LocalDateTime.now());
departmentMapper.updateById(department);
}
@Override
public void delete(Long id) {
Department department = new Department();
department.setId(id);
department.setIsDel(1);
department.setUpdateTime(LocalDateTime.now());
departmentMapper.updateById(department);
}
@Override
public IPage<DeptDto> pageList(ReqPageParams req) {
return departmentMapper.pageList(new Page<>(req.getPageNum(), req.getPageSize()), req);
}
@Override
public List<DeptTreeDto> deptTree() {
return departmentMapper.deptTree();
}
@Override
public List<DeptDto> idsPageList(List<Long> ids) {
return departmentMapper.idsPageList(ids);
}
}
(3)、DepartmentMapper代码示例
package com.ucap.demo.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ucap.demo.dto.DeptDto;
import com.ucap.demo.dto.DeptTreeDto;
import com.ucap.demo.entity.Department;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ucap.demo.utils.parameter.ReqPageParams;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* <p>
* 部门表 Mapper 接口
* </p>
*
* @author jack deng
* @since 2023-02-27
*/
@Repository
public interface DepartmentMapper extends BaseMapper<Department> {
IPage<DeptDto> pageList(Page<Object> page, ReqPageParams req);
List<DeptTreeDto> deptTree();
List<DeptDto> idsPageList(@Param("ids") List<Long> ids);
}
3.分页查询
(1)、调用接口时,需要传参数。参数包括页码、页码大小、查询条件、排序条件。ReqPageParams为分页查询列表参数类。这个类在DepartmentController、DepartmentServiceImpl 类的pageList方法有介绍。
@Data
public class ReqPageParams {
/**
* 页码
*/
private Integer pageNum;
/**
* 大小
*/
private Integer pageSize;
/**
* 排序条件
*/
private Map<String, String> sorts;
/**
* 查询条件
*/
private Map<String, String> params;
public Integer getPageNum() {
return (pageNum == null || pageNum < 1) ? 1 : pageNum;
}
public Integer getPageSize() {
return (pageSize == null || pageSize < 1) ? 10 : pageSize > 1000 ? 1000 : pageSize;
}
public Map<String, String> getSorts() {
return sorts == null ? new HashMap<String, String>() : sorts;
}
public Map<String, String> getParams() {
return params == null ? new HashMap<String, String>() : params;
}
}
(2)、DepartmentMapper.xml 列表查询SQL
<select id="pageList" resultType="com.ucap.demo.dto.DeptDto">
SELECT id,name,description
FROM org_department
WHERE is_del=0
<if test="req.params.name!=null and req.params.name!=''">
and concat('%',#{req.params.name},'%')
</if>
<if test="req.sorts.createTime!=null and req.sorts.createTime!=''">
<if test="req.sorts.createTime=='desc'">
order by CREATE_TIME desc
</if>
<if test="req.sorts.createTime=='asc'">
order by CREATE_TIME asc
</if>
</if>
</select>
4、使用mybatis-plus递归,利用延迟加载 一对多实现。
(1)、DepartmentMapper.xml 部门树 DepartmentController、DepartmentServiceImpl 对应deptTree方法
<resultMap id="childs" type="com.ucap.demo.dto.DeptTreeDto">
<collection property="childs" column="parent_id=id" select="deptTree"/>
</resultMap>
<select id="deptTree" resultMap="childs">
SELECT id, name as deptName
FROM org_department
WHERE is_del = 0
<if test="parent_id==null or parent_id==''">
AND parent_id=0
</if>
<if test="parent_id!=null and parent_id!=''">
AND parent_id=#{parent_id}
</if>
</select>
(2)、DeptTreeDto类,接收返回数据。
@Data
public class DeptTreeDto {
/**
* 部门id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 部门名字
*/
private String deptName;
/**
* 部门子集
*/
private List<DeptTreeDto> childs;
}
5、foreach使用,DepartmentController、DepartmentServiceImpl 对应idsPageList方法
<select id="idsPageList" resultType="com.ucap.demo.dto.DeptDto">
SELECT id,name,description
FROM org_department
WHERE is_del=0
AND id in
<foreach collection="ids" item="item" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</select>