MP的官方文档地址
我们要学习MP,那我们先来了解一下什么是MybatisPlus
1、简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为
简化开发、提高效率而生。
这话的意思就是:Mybatis能做的MP就能做。这就是 叫做只做增强不做改变。
2、特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防 误操作。
3、支持多种数据库
任何能使用MyBatis进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下
MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,
ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据
库,瀚高数据库。
4、框架结构
开始入门
1、开发环境
IDE:idea 2020.3.2
JDK:JDK8
构建工具:maven 3.5.4
MySQL版本:MySQL 8
Spring Boot:2.6.3
MyBatis-Plus:3.5.1
2、数据准备
- 创建表
DROP TABLE IF EXISTS t_user;
CREATE TABLE t_user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
2.插入数据
DELETE FROM user;
INSERT INTO t_user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
3、创建SpringBoot工程
(创建过程需要联网,不建议使用校园网,因为有可能会出现构建不成功)
需要用到WEB模块,选择Web勾选Spring Web,
因为需要连接数据库,这SQL 选择MySQL Driver
4、引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
5、idea中安装lombok插件
在文件->设置->插件中搜索lombok安装并重启
编写代码
1、配置application.properties
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?serverTimezone&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#设置全局数据表前缀,设置之后可以不适用@TableName注解进行标注了
mybatis-plus.global-config.db-config.table-prefix=t_
#配置类型别名
mybatis-plus.type-aliases-package=com.sjm.pojo
#配置扫描通用枚举
mybatis-plus.type-enums-package=com.sjm.enums
注意:mysql版本不同连接方式和驱动名有所不同
MySQL5.7版本的url:
jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
驱动:com.mysql.jdbc.Driver
MySQL8.0版本的url:
jdbc:mysql://localhost:3306/mybatis_plus?
serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
驱动: com.mysql.cj.jdbc.Driver
2、新建文件结构,分别创建UserController类,UserService类,UserMapper类,ResultUtil类
3、配置启动类
@SpringBootApplication
//用于扫描mapper接口的包
@MapperScan("com.sjm.mapper")
@MapperScan("com.sjm.dao")
@MapperScan("com.sjm.utils")
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
4、添加mapper为了在mvc结构中调用方法不报错,在dao层或者mapper层添加注解。
IDEA在 userMapper 处报错,因为找不到注入的对象,因为类是动态创建的,但是程序可以正确
的执行。
为了避免报错,可以在mapper接口上添加 @Repository 注解
UserMapper类
//Repository将接口标记为实体
@Repository
public interface UserMapper extends BaseMapper<User> {
// 此处可以自定义查询
//这里就是MybatisPlus的神奇之处了,
}
5、添加实体类
@Data
//lombok注解
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
6、ResultUtil类代码,是封装后的结果类
package com.sjm.utils;
public class ResultUtil {
private String msg;
private Integer status;
private Object data;
//成功无结果集
private ResultUtil(String msg) {
this.status = 200;
this.msg = msg;
}
public static ResultUtil success(String msg) {
return new ResultUtil(msg);
}
// 成功有结果集
private ResultUtil(String msg, Object data) {
this.msg = msg;
this.data = data;
this.status = 200;
}
public static ResultUtil success(String msg, Object data) {
return new ResultUtil(msg, data);
}
//失败
private ResultUtil(int status, String msg) {
this.status = status;
this.msg = msg;
}
public static ResultUtil fail(int status, String msg) {
return new ResultUtil(status, msg);
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
7、测试查询功能
Controller:
@Controller
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/selectAll")
@ResponseBody
// 查询所有
public List<User> selectALLUser() {
return userService.selectAll();
}
}
Service接口
@Service
public class UserService {
@Autowired
UserMapper userMapper;
public List<User> selectAll() {
return userMapper.selectList(null);
}
}
浏览器打开:http://localhost:8080/selectAll
返回的结果:
添加日志
#配置mybatisplus日志输出
#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
基本CRUD
MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,我们可以直接使用。可以按住Ctrl点击BaseMapper查看BaseMapper代码。
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteById(T entity);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> queryWrapper);
int deleteBatchIds(@Param("coll") Collection<?> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
} else {
return ts.get(0);
}
} else {
return null;
}
}
default boolean exists(Wrapper<T> queryWrapper) {
Long count = this.selectCount(queryWrapper);
return null != count && count > 0L;
}
Long selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}
1、插入
Controller:
// 插入
@RequestMapping("/insertOne")
@ResponseBody
// @RequestBody用于接收json格式的数据{"id":7,"name":"sjm","age":23,"email":"test4@baomidou.com"}
public ResultUtil insertOne(@RequestBody User user) {
if (userService.selectById(user.getId()) == null) {
userService.insertOne(user);
return ResultUtil.success("成功新增一条记录");
} else {
return ResultUtil.fail(201, "新增失败");
}
}
Service
public Integer insertOne(User user) {
return userMapper.insert(user);
}
使用Postman测试:
成功插入数据库,若id为空时,MyBatis-Plus在实现插入数据时,会默认基于雪花算法的策略生成id
2、删除
Controller
// 根据ID删除
@RequestMapping("/deleteById")
@ResponseBody
public ResultUtil DeleteById(Long id) {
if (id != null && userService.deleteById(id) != 0) {
return ResultUtil.success("成功删除一条记录");
} else {
return ResultUtil.fail(201, "删除失败");
}
}
// 根据Map键值来删除
@RequestMapping("/deleteByMap")
@ResponseBody
// {"id":8,"name":"liHua","age":23,"email":"test4@baomidou.com"}
public ResultUtil DeleteByMap(@RequestBody User user) {
Map<String, Object> map = new HashMap<>();
if (user.toString() != null) {
// 设置删除的条件
map.put("name", user.getName());
map.put("age", user.getAge());
int result = userService.deleteByMap(map);
return ResultUtil.success("成功删除" + result + "条记录");
} else {
return ResultUtil.fail(201, "用户信息不能为空");
}
}
// 根据id来批量删除
@RequestMapping("/deleteByIdList")
@ResponseBody
// 请求方式:http://localhost:8080/deleteByIdList?IdList=5&IdList=7
public ResultUtil deleteByIdList(String IdList) {
if (IdList != null) {
String[] lists = IdList.split(",");
List<Long> bids = new ArrayList<>();
for (String list : lists) {
bids.add(Long.parseLong(list));
}
// DELETE FROM user WHERE id IN ( ? , ? )
int result = userService.deleteByList(bids);
if (result > 0) {
return ResultUtil.success("成功删除了" + result + "条信息");
} else {
return ResultUtil.fail(201, "删除失败!");
}
} else {
return ResultUtil.fail(201, "请至少选择一条信息!");
}
}
Service
// 根据ID删除
public Integer deleteById(Long id) {
return userMapper.deleteById(id);
}
// 根据Map键值来删除
public Integer deleteByMap(Map<String, Object> map) {
return userMapper.deleteByMap(map);
}
// 根据id来批量删除
public Integer deleteByList(List<Long> ids) {
return userMapper.deleteBatchIds(ids);
}
结果1
结果2
结果3
3、修改
Controller
// 修改
@RequestMapping("/updateById")
@ResponseBody
public ResultUtil UpdateUser(@RequestBody User user) {
if (user != null && user.getId() != null) {
int result = userService.updateUser(user);
if (result > 0) {
return ResultUtil.success("成功修改了" + result + "条记录");
} else {
return ResultUtil.fail(201, "修改失败!");
}
} else {
return ResultUtil.fail(202, "修改失败!参数不能为空!");
}
}
Service
public Integer updateUser(User user) {
return userMapper.updateById(user);
}
结果
4、查询
Controller
// 根据Id查询
@RequestMapping("/selectById")
@ResponseBody
public User selectById(Long id) {
return userService.selectById(id);
}
// 根据多个Id查询
@RequestMapping("/selectByMoreId")
@ResponseBody
// 请求方式:http://localhost:8080/selectByMoreId?ids=1&ids=3
//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
// 查询结果:
// {"msg":"查询成功!",
// "status":200,
// "data":[{"id":1,"name":"Jone","age":18,"email":"test1@baomidou.com"},
// {"id":3,"name":"Tom","age":28,"email":"test3@baomidou.com"}]}
public ResultUtil selectByMoreId(Long[] ids) {
List<Long> list = Arrays.asList(ids);
List<User> userList = userService.selectByIds(list);
return ResultUtil.success("查询成功!", userList);
}
Service
public User selectById(Long id) {
return userDao.selectByOne(id);
}
// 根据多个Id查询
public List<User> selectByIds(List<Long> ids) {
return userMapper.selectBatchIds(ids);
}
结果1
结果2
使用构造器QueryWrapper
关于Wrappper
eg1:查询用户名包含a,年龄在20到23之间,邮箱信息不为null的用户信息
Controller
// 查询用户名包含a,年龄在20到23之间,邮箱信息不为null的用户信息
@RequestMapping("/TestWrapper")
@ResponseBody
public ResultUtil testWrapper(Integer i) {
if (i == 1) {
List<User> list = userService.TestWrapper("a", 20, 30, "email");
return ResultUtil.success("查询成功", list);
} else {
return ResultUtil.fail(201, "查询失败");
}
}
Service
public List<User> TestWrapper(String name, Integer minAge, Integer maxAge, String email) {
// 查询用户名包含a,年龄在20到23之间,邮箱信息不为null的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", name)
.between("age", minAge, maxAge)
.isNotNull(email);
return userMapper.selectList(queryWrapper);
}
结果
eg2:排序
Controller
//排序
@RequestMapping("/TestWrapperAsc")
@ResponseBody
public ResultUtil TestWrapperAsc() {
if (true) {
List<User> list = userService.TestWrapperAsc();
return ResultUtil.success("查询成功", list);
} else {
return ResultUtil.fail(201, "查询失败");
}
}
Service
public List<User> TestWrapperAsc() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 先根据年龄降序排列,如果年龄想相同再根据id升序排列
queryWrapper.orderByDesc("age")
.orderByAsc("id");
return userMapper.selectList(queryWrapper);
}
结果
eg3:删除邮箱为null的记录
Controller
//条件构造器删除
@RequestMapping("/TestWrapperDelete")
@ResponseBody
public ResultUtil TestWrapperDelete() {
int result = userService.deleteIsNullEmail();
System.out.println(result);
if (result > 0) {
return ResultUtil.success("成功删除" + result + "条信息");
} else {
return ResultUtil.fail(201, "删除失败");
}
}
Service
// 组装删除
public int deleteIsNullEmail() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email"); //条件构造器也可以构建删除语句的条件
int result = userMapper.delete(queryWrapper);
return result;
}
结果:
eg4:使用QueryWrapper构造器修改
Controller
//条件构造器修改
@RequestMapping("/TestWrapperUpdate")
@ResponseBody
// @RequestBody User user,Integer age,String name,String email
public ResultUtil TestWrapperUpdate(@RequestBody User user) {
int result = userService.WrapperUpdate(user, 20, "a", "email");
System.out.println(result);
if (result > 0) {
return ResultUtil.success("成功修改" + result + "条信息");
} else {
return ResultUtil.fail(201, "修改失败");
}
}
Service
public int WrapperUpdate(User user, Integer age, String name, String email) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", age).like("name", name).or().isNull(email);
return userMapper.update(user, queryWrapper);
}
结果
eg6:条件优先级
Controller
// 条件优先级
@RequestMapping("/TestWrapperCondition")
@ResponseBody
public ResultUtil TestWrapperCondition(@RequestBody User user) {
// 将用户名中含有a并且年龄大于20或邮箱为null的用户信息修改
// lambda中的条件优先
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "a")
.and(i -> i.gt("age", 20).or().isNull("email"));
int result = userService.WrapperCondition(user, queryWrapper);
if (result > 0) {
return ResultUtil.success("成功修改" + result + "条信息");
} else {
return ResultUtil.fail(201, "修改失败");
}
}
Service
public int WrapperCondition(User user, QueryWrapper<User> queryWrapper) {
return userMapper.update(user, queryWrapper);
}
结果
eg7:组装select子句多条件查询
Controller
//多条件查询
// http://localhost:8080/TestWrapperSelectMoreCondition?name=name&age=age&email=email
@RequestMapping("/TestWrapperSelectMoreCondition")
@ResponseBody
public ResultUtil TestWrapperSelectMoreCondition(String name, String age, String email) {
List<Map<String, Object>> maps = userService.WrapperSelectMoreCondition(name, age, email);
if (!maps.isEmpty()) {
return ResultUtil.success("查询成功", maps);
} else {
return ResultUtil.fail(201, "查询失败");
}
}
Service
public List<Map<String, Object>> WrapperSelectMoreCondition(String name, String age, String email) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select(name, age, email);
return userMapper.selectMaps(queryWrapper);
}
结果
eg8:实现子查询
Controller
// 子查询
@RequestMapping("/TestWrapperSonSelect")
@ResponseBody
public ResultUtil TestWrapperSonSelect(Long id) {
List<User> list = userService.WrapperSonSelect(id);
if (!list.isEmpty()) {
return ResultUtil.success("查询成功", list);
} else {
return ResultUtil.fail(201, "查询失败");
}
}
Service
public List<User> WrapperSonSelect(Long id) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from t_user where id <= "+id![在这里插入图片描述](https://img-blog.csdnimg.cn/83558f87d585468485e36290a180eaa2.png)
);
return userMapper.selectList(queryWrapper);
}
结果
eg9:条件修改
Controller
// 条件修改
@RequestMapping("/TestUpdateWrapper")
@ResponseBody
// 请求方式:http://localhost:8080/TestUpdateWrapper?
// oldName=a&name=李华&age=20&OldEmail=email&email=sjm@qq.com
// 返回结果:{
// "msg": "修改成功",
// "status": 200,
// "data": null
// }
public ResultUtil TestUpdateWrapper(String oldName, String name, Integer age, String OldEmail, String email) {
int result = userService.TestUpdateWrapper(oldName, name, age, OldEmail, email);
if (result > 0) {
return ResultUtil.success("修改成功");
} else {
return ResultUtil.fail(201, "修改失败");
}
}
Service
public int TestUpdateWrapper(String oldName,String name, Integer age, String OldEmail,String email) {
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.like("name", oldName)
.and(i -> i.gt("age", age).or().isNull(OldEmail));
updateWrapper.set("name",name).set("email",email);
return userMapper.update(null, updateWrapper);
}
结果
eg9:拼接条件
Controller
// 拼接条件
// 请求方式:http://localhost:8080/TestConditionAdd?name=李&beginAge=20&endAge=30
// 结果:{"msg":"查询成功","status":200,"data":[{"id":4,"name":"李华","age":23,"email":"sjm@qq.com"}]}
@RequestMapping("/TestConditionAdd")
@ResponseBody
public ResultUtil TestConditionAdd(String name, Integer beginAge, Integer endAge) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// if (StringUtils.isNotBlank(name) ) {
// queryWrapper.like("name",name);
//
// }if (beginAge != null){
// queryWrapper.ge("age",beginAge);
// }
// if (endAge != null){
// queryWrapper.le("age",endAge);
// }
// 此方式可替代if语句
queryWrapper.like(StringUtils.isNotBlank(name), "name", name)
.ge(beginAge != null, "age", beginAge)
.le(endAge != null, "age", endAge);
List<User> list = userService.ConditionAdd(queryWrapper);
if (!list.isEmpty()) {
return ResultUtil.success("查询成功", list);
} else {
return ResultUtil.fail(201, "查询失败");
}
//
}
Service
public List<User> ConditionAdd(QueryWrapper<User> queryWrapper) {
return userMapper.selectList(queryWrapper);
}
结果
LambdaQueryWrapper
Controller
// 请求方式:http://localhost:8080/LambdaQueryWrapper?name=J&beginAge=18&endAge=25
// 返回结果;{
// "msg": "success",
// "status": 200,
// "data": [
// {
// "id": 1,
// "name": "Jone",
// "age": 18,
// "email": "test1@baomidou.com"
// },
// {
// "id": 2,
// "name": "Jack",
// "age": 20,
// "email": "test2@baomidou.com"
// }
// ]
//}
@RequestMapping("/LambdaQueryWrapper")
@ResponseBody
public ResultUtil LambdaQueryWrapper(String name, Integer beginAge, Integer endAge) {
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(name), User::getName, name)
.ge(beginAge != null, User::getAge, beginAge)
.le(endAge != null, User::getAge, endAge);
return ResultUtil.success("success", userService.LambdaWrapper(queryWrapper));
}
Service
public List<User> LambdaWrapper(LambdaQueryWrapper<User> queryWrapper) {
return userMapper.selectList(queryWrapper);
}
结果
LambdaUpdateWrapper
Controller
@RequestMapping("/LambdaUpdateWrapper")
@ResponseBody
public ResultUtil LambdaUpdateWrapper(String name, Integer age, Integer endAge) {
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
//组装set语句
updateWrapper.set(User::getAge, 18).
set(User::getEmail, "user@atguigu.com")
.like(User::getName, "a")
.and(i -> i.lt(User::getAge, 24)
.or().isNull(User::getEmail)); //lambda 表达式内的逻辑优先运算
return ResultUtil.success("success", userService.updateWrapper(updateWrapper));
}
Service
public int updateWrapper(LambdaUpdateWrapper<User> updateWrapper) {
return userMapper.update(null,updateWrapper);
}
结果
分页实现
MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
新建分页配置类
package com.sjm.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//分页配置类
@Configuration
@MapperScan("com.sjm.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
Controller
// 分页实现
@RequestMapping("/splitPage")
@ResponseBody
public ResultUtil splitPage(Integer current, Integer size) {
Page<User> page = new Page<>(current, size);
userService.selectPage(page);
return ResultUtil.success("success", page.getRecords());
}
Service
public Page<User> selectPage(Page<User> page) {
return userMapper.selectPage(page,null);
}
结果
自定义分页查询
Controller
// 自定义分页查询
// 请求方式:http://localhost:8080/splitMySelfPage?current=1&size=2&age=19
// 返回结果:{
// "msg": "success",
// "status": 200,
// "data": [
// {
// "id": 3,
// "name": "Tom",
// "age": 28,
// "email": "test3@baomidou.com"
// },
// {
// "id": 4,
// "name": "XXX",
// "age": 23,
// "email": "sjm@qq.com"
// }
// ]
//}
@RequestMapping("/splitMySelfPage")
@ResponseBody
public ResultUtil splitMySelfPage(Integer current, Integer size,Integer age) {
Page<User> page = new Page<>(current, size);
userService.MySelfPage(page,age);
return ResultUtil.success("success", page.getRecords());
}
Service
public Page<User> MySelfPage(Page<User> page, Integer age) {
return userDao.selectPageVo(page,age);
}
dao,新建一个UserDao
package com.sjm.dao;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sjm.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao {
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
}
在resource中新建UserMapper.xml,使用方式与Mybatis是一样的。
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.sjm.dao.UserDao">
<select id="selectPageVo" resultType="User">
select id,name,age,email from t_user where age > #{age}
</select>
</mapper>
结果
通用Seivec-----IService
说明:
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删 除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,
泛型 T 为任意实体对象
建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承
Mybatis-Plus 提供的基类
官网地址:https://baomidou.com/pages/49cc81/#service-crud-%E6%8E%A5%E5%8F%
A3
MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑
详情查看源码IService和ServiceImpl
>创建Service接口和实现类
/*** UserService继承IService模板提供的基础功能 */
public interface UserService extends IService<User> {
}
/*** ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现 */
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { }
IService测试
Controller
package com.sjm.controller;
import com.sjm.pojo.User;
import com.sjm.service.UsersService;
import com.sjm.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
@Controller
@RequestMapping("/IService")
public class IServiceController {
@Autowired
UsersService usersService;
@RequestMapping("/testIservice")
@ResponseBody
public ResultUtil testIservice() {
return ResultUtil.success("统计成功",usersService.count());
}
// 批量添加 使用usersService.saveBatch(list),参数为集合,放回结果为boolean类型
@RequestMapping("/InsertMore")
@ResponseBody
// 接收json格式的数据,需要用到@RequestBody注解,
// 接收格式:[{"id":5,"name":"苏建铭","age":23,"email":"test4@baomidou.com"},
// {"id":7,"name":"李华","age":23,"email":"test4@baomidou.com"}]
//
public ResultUtil testInsertMore(@RequestBody ArrayList<User> list){
// 输出接收到的数据
System.out.println(list.toArray());
if (list.toArray().length!=0&&usersService.saveBatch(list)) {
return ResultUtil.success("添加成功!");
}else
{
return ResultUtil.fail(201,"添加失败!");
}
}
}
通用枚举
创建通用枚举类
package com.sjm.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
@Getter
public enum SexEnum {
MALE(1, "男"), FEMALE(2, "女");
@EnumValue
private Integer sex;
private String sexName;
SexEnum(Integer sex, String sexName) {
this.sex = sex;
this.sexName = sexName;
}
}
测试
@Test
public void testSexEnum() {
User user = new User();
user.setId(10L);
user.setName("Enum");
user.setAge(22);
//设置性别信息为枚举项,会将@EnumValue注解所标识的属性值存储到数据库
user.setSex(SexEnum.FEMALE );
//INSERT INTO t_user ( username, age, sex ) VALUES ( ?, ?, ? )
// Parameters: Enum(String), 20(Integer), 1(Integer)
userMapper.insert(user);
}
代码生成器
- 引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>`
- 快速生成
package com.sjm;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class FastAutoGeneratorTest {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/testdb? characterEncoding=utf-8&userSSL=false", "root", "123456")
.globalConfig(builder -> {builder.author("sjm").fileOverride().outputDir("F://mybatis_plus");
})
.packageConfig(builder -> {builder.parent("com").moduleName("sjm")
.pathInfo(Collections.singletonMap(OutputFile.mapper,"F://mybatis_plus"));
})
.strategyConfig(builder -> {builder.addInclude("t_user")
.addTablePrefix("t_","c_");
})
.templateEngine(new FreemarkerTemplateEngine()).execute();
}
}