SpringBoot集成MyBatis-Plus(简化)
简易的环境:
JDK 1.8、Windows10 专业版、IDEA2020、MySQL 5.7.13、maven 3.6.3
环境准备
-
新建SpringBoot项目,这里我项目命名为test
-
pom.xml文件引入一下相关依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> <version>5.1.37</version> </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> <!-- mybatis plus 代码生成器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies>
-
application.yml配置环境信息
server: port: 8081 servlet: context-path: / spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/dome-mybatis-plus?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: root password: root jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 serialization: write-dates-as-timestamps: false mybatis-plus: configuration: map-underscore-to-camel-case: true auto-mapping-behavior: full log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath*:mapper/**/*Mapper.xml global-config: db-config: logic-not-delete-value: 1 logic-delete-value: 0
-
在conf包下创建MybatisPlusConfig.java,用于配置MyBatis-Plus的分页
package com.example.conf; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 配置分页插件 */ @Configuration public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
-
在conf包下创建GeneratorCodeConfig.java,通过反向代理自动生成MyBatis-Plus的相关代码
package com.example.conf; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.util.Scanner; /** * 自动生成 mybatis-plus 的相关代码 * 自动生成 controller 层 * 自动生成 service 层 * 自动生成 mapper 层 * 自动生成 model 层 */ public class GeneratorCodeConfig { public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("astupidcoder"); gc.setOpen(false); //实体属性 Swagger2 注解 gc.setSwagger2(false); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://127.0.0.1:3306/dome-mybatis-plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("root"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); // pc.setModuleName(scanner("模块名")); pc.setParent("com.example"); pc.setEntity("model.auto"); pc.setMapper("mapper.auto"); pc.setService("service"); pc.setServiceImpl("service.impl"); mpg.setPackageInfo(pc); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setSuperEntityClass("com.baomidou.mybatisplus.extension.activerecord.Model"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setEntityLombokModel(true); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }
-
MySQL数据创建数据库名为dome-mybatis-plus,数据表名为user表,字段如下
列名 数据类型 字段类型 长度 是否为空 默认值 备注 id bigint(20) bigint NO 主键ID name varchar(30) varchar 30 YES 姓名 age int(11) int YES 年龄 email varchar(50) varchar 50 YES 邮箱 -
执行GeneratorCodeConfig,输入表名后回车即可生成controller层、service层、mapper层、model层
- 在Springboot启动类上添加扫描mapper注解
-
在http包下创建ResultInfo.java,返回结果类统一封装
package com.example.conf.http; import lombok.Data; import java.io.Serializable; /** * 统一返回请求接口封装 */ @Data public class ResultInfo implements Serializable { // 状态码 private Integer code; // 消息 private String message; // 数据对象 private Object result; private Integer total; /** * 无参构造器 */ public ResultInfo() { super(); } public ResultInfo(Status status) { super(); this.code = status.code; this.message = status.message; } public ResultInfo result(Object result) { this.result = result; return this; } public ResultInfo message(String message) { this.message = message; return this; } public ResultInfo total(Integer total) { this.total = total; return this; } /** * 只返回状态,状态码,消息 * * @param code * @param message */ public ResultInfo(Integer code, String message) { super(); this.code = code; this.message = message; } /** * 只返回状态,状态码,数据对象 * * @param code * @param result */ public ResultInfo(Integer code, Object result) { super(); this.code = code; this.result = result; } /** * 返回全部信息即状态,状态码,消息,数据对象 * * @param code * @param message * @param result */ public ResultInfo(Integer code, String message, Object result) { super(); this.code = code; this.message = message; this.result = result; } }
-
在http包下创建Status.java,http状态编码-枚举类
package com.example.conf.http; /** * http状态编码-枚举类 */ public enum Status { // 公共 SUCCESS(2000, "成功"), UNKNOWN_ERROR(9998,"未知异常"), SYSTEM_ERROR(9999, "系统异常"), INSUFFICIENT_PERMISSION(4003, "权限不足"), WARN(9000, "失败"), REQUEST_PARAMETER_ERROR(1002, "请求参数错误"), // 登录 LOGIN_EXPIRE(2001, "未登录或者登录失效"), LOGIN_CODE_ERROR(2002, "登录验证码错误"), LOGIN_ERROR(2003, "用户名不存在或密码错误"), LOGIN_USER_STATUS_ERROR(2004, "用户状态不正确"), LOGOUT_ERROR(2005, "退出失败,token不存在"), LOGIN_USER_NOT_EXIST(2006, "该用户不存在"), LOGIN_USER_EXIST(2007, "该用户已存在"); public int code; public String message; Status(int code, String message) { this.code = code; this.message = message; } }
自定义SQL语句
-
在resources目录下新建mapper文件夹,新建UserMapper.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.auto.UserMapper"> <!-- 查找用户信息 --> <select id="findAllUser" resultType="com.example.model.auto.User"> select * from user </select> </mapper>
-
UserMapper.java
package com.example.mapper.auto; import com.example.model.auto.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import java.util.List; /** * <p> * Mapper 接口 * </p> * * @author astupidcoder * @since 2021-07-13 */ public interface UserMapper extends BaseMapper<User> { /** * 查找用户信息 */ public List<User> findAllUser(); }
-
IUserService.java
package com.example.service; import com.example.model.auto.User; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * <p> * 服务类 * </p> * * @author astupidcoder * @since 2021-07-13 */ public interface IUserService extends IService<User> { /** * 查找用户信息 */ public List<User> findAllUser(); }
-
UserServiceImpl.java
package com.example.service.impl; import com.example.model.auto.User; import com.example.mapper.auto.UserMapper; import com.example.service.IUserService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; /** * <p> * 服务实现类 * </p> * * @author astupidcoder * @since 2021-07-13 */ @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { @Resource private UserMapper userMapper; @Override public List<User> findAllUser() { return userMapper.findAllUser(); } }
-
UserController.java
package com.example.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.conf.http.ResultInfo; import com.example.conf.http.Status; import com.example.model.auto.User; import com.example.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; /** * <p> * 前端控制器 * </p> * * @author astupidcoder * @since 2021-07-13 */ @RestController @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; @PostMapping("/getById/{id}") public User getById(@PathVariable(value = "id") Integer id){ return userService.getById(id); } @PostMapping("/findAllUser") public List<User> findAllUser(){ return userService.findAllUser(); } }
-
测试
package com.example; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.example.controller.UserController; import com.example.mapper.auto.UserMapper; import com.example.model.auto.User; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; import java.util.List; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest class TestApplicationTests { @Autowired private UserController userController; @Test public void findAllUser(){ List<User> allUser = userController.findAllUser(); for (User user : allUser) { System.out.println(user.toString()); } } }
测试结果:
Service CRUD 接口
package com.example.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.conf.http.ResultInfo;
import com.example.conf.http.Status;
import com.example.model.auto.User;
import com.example.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author astupidcoder
* @since 2021-07-13
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
@PostMapping("/getById/{id}")
public User getById(@PathVariable(value = "id") Integer id){
return userService.getById(id);
}
@PostMapping("/findAllUser")
public List<User> findAllUser(){
return userService.findAllUser();
}
// 测试 CRUD 接口
/**
* 插入一条记录 Save
* Method: boolean save(T entity);
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/insertRecords")
public ResultInfo insertRecords(){
User user = new User();
user.setName("张三");
user.setAge(15);
user.setEmail("zhansan@163.com");
boolean save = userService.save(user);
if (save) {
return new ResultInfo(Status.SUCCESS);
}else {
return new ResultInfo(Status.WARN);
}
}
/**
* 插入(批量)
* Method 1: boolean saveBatch(Collection<T> entityList);
* Method 2: boolean saveBatch(Collection<T> entityList, int batchSize); 分批插入数据
* 参数说明: batchSize(插入批次数量)、Collection<T>(实体对象集合)
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/batchInsertRecord")
public void batchInsertRecord(){
List<User> users = new ArrayList<>();
User user = null;
for (int i = 1; i <= 10; i++) {
user = new User();
user.setName("李四"+i);
user.setAge(i+10);
user.setEmail("lisi"+i+"@168.com");
users.add(user);
}
System.out.println(users.toString());
boolean save = userService.saveBatch(users);
if (save) {
System.out.println("Method 1 批量插入成功!");
}else {
System.out.println("Method 1 批量插入失败!");
}
// 指定插入数量
users = new ArrayList<>();
for (int i = 1; i <= 20; i++) {
user = new User();
user.setName("王五"+i);
user.setAge(i+10);
user.setEmail("wangwu"+i+"@168.com");
users.add(user);
}
boolean b = userService.saveBatch(users,5);
if (b) {
System.out.println("Method 2 批量插入成功!");
}else {
System.out.println("Method 2 批量插入失败!");
}
}
/**
* 修改记录
* Method: boolean update(T updateEntity, Wrapper<T> whereWrapper);
* 参数说明: Wrapper<T>(实体对象封装操作类 UpdateWrapper) 根据 whereWrapper 条件,更新记录
* 参数说明: T updateEntity(实实体对象) 更新的数据
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/modifyTheRecord")
public ResultInfo modifyTheRecord(){
User user = new User();
user.setName("张三");
user.setEmail("zhanshan0@168.com");
user.setAge(50);
// user.setId(6L);
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper.eq("id",1415155858291544070L);
boolean update = userService.update(user, userUpdateWrapper);
if (update) {
return new ResultInfo(Status.SUCCESS);
}else {
return new ResultInfo(Status.WARN);
}
}
/**
* 根据ID 批量修改
* Method: boolean updateBatchById(Collection<T> entityList);
* 参数说明: Collection<T>(实体对象集合)
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/batchModifying")
public ResultInfo batchModifying(){
List<User> users = new ArrayList<>();
User user = new User();
user.setId(1L);
user.setName("Jone1");
user.setAge(20);
users.add(user);
user = new User();
user.setId(2L);
user.setName("Jack1");
users.add(user);
boolean b = userService.updateBatchById(users);
if (b) {
return new ResultInfo(Status.SUCCESS);
}else {
return new ResultInfo(Status.WARN);
}
}
/**
* 根据 entity 条件,删除记录
* Method: boolean remove(Wrapper<T> queryWrapper);
* 参数说明: Wrapper<T>(实体对象封装操作类 UpdateWrapper)
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/deleteRecord")
public ResultInfo deleteRecord(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.eq("name","张三");
boolean remove = userService.remove(userQueryWrapper);
if (remove) {
return new ResultInfo(Status.SUCCESS);
}else {
return new ResultInfo(Status.WARN);
}
}
/**
* 删除(根据ID 批量删除)
* Method: boolean removeByIds(Collection<? extends Serializable> idList);
* 参数说明: Collection<? extends Serializable> 主键ID列表
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/batchDeleteRecords")
public ResultInfo batchDeleteRecords(){
List<Long> list = new ArrayList<>();
list.add(7L);
list.add(8L);
list.add(10L);
list.add(9L);
boolean remove = userService.removeByIds(list);
if (remove) {
return new ResultInfo(Status.SUCCESS);
}else {
return new ResultInfo(Status.WARN);
}
}
/**
* 根据 条件,查询一条记录
* Method: T getOne(Wrapper<T> queryWrapper, boolean throwEx);
* 参数说明: queryWrapper(实体对象封装操作类 QueryWrapper)
* 参数说明: throwEx 有多个 result 是否抛出异常
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/queryASingleRecord")
public ResultInfo queryASingleRecord(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.eq("id",2L).last("LIMIT 1");
User one = userService.getOne(userQueryWrapper,true);
return new ResultInfo(200,one);
}
/**
* 查询接口多样化
* 个人觉得常用的可能是一下几个接口
* Method 1: List<T> list(); 查询所有
* Method 2: List<T> list(Wrapper<T> queryWrapper); 查询列表
* Method 3: Collection<T> listByMap(Map<String, Object> columnMap); 查询(根据 columnMap 条件)
* Author: Yang
* Time: 2021/7/14
*/
/**
* 分页查询
* 无条件分页查询:
* IPage<T> page(IPage<T> page);
* 条件分页查询:
* IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
* Author: Yang
* Time: 2021/7/14
*/
@GetMapping("/queryASingleRecord/{current}/{size}")
public ResultInfo queryUserForPage(@PathVariable(value = "current") Integer currentPage, @PathVariable(value = "size") Integer size){
IPage<User> userPage = new Page<>(currentPage, size);//参数一是当前页,参数二是每页个数
userPage = userService.page(userPage);
List<User> list = userPage.getRecords();
return new ResultInfo(200, list).total((int) userPage.getTotal());
}
}
Mapper CRUD 接口
package com.example;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.controller.UserController;
import com.example.mapper.auto.UserMapper;
import com.example.model.auto.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class TestApplicationTests {
@Autowired
private UserController userController;
@Test
public void findAllUser(){
List<User> allUser = userController.findAllUser();
for (User user : allUser) {
System.out.println(user.toString());
}
}
@Resource
private UserMapper userMapper;
// Mapper CRUD 接口
@Test
public void insertRecords(){
User user = new User();
user.setName("王麻子2");
user.setAge(22);
user.setEmail("wangmazi@qq.com");
int insert = userMapper.insert(user);
System.out.println("插入状态:"+(insert>0?"成功!":"失败!"));
}
@Test
public void deleteRecord(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.like("name","李四");
int delete = userMapper.delete(userQueryWrapper);
System.out.println("删除状态:"+(delete>0?"成功!":"失败!"));
}
@Test
public void modifyTheRecord(){
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper.like("name","王麻子");
User user = new User();
user.setAge(1);
user.setEmail("@@@@");
int update = userMapper.update(user, userUpdateWrapper);
System.out.println("更新状态:"+(update>0?"成功!":"失败!"));
}
}