简介
MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
小蓝鸟代表Mybatis,小红鸟代表MP,就像魂斗罗两兄弟,基友搭配,效率翻倍。
特性(来自官网)
无侵入 :只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小 :启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持的数据库 常用的如MySQL,Oracle,DB2,SQLite等等。
框架结构
mapper CRUD接口 引入MP
依赖 新建springboot项目,引入依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 <?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.7.3</version > <relativePath /> </parent > <groupId > roydon.xyz</groupId > <artifactId > Mybatis-Plus-Demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <name > Mybatis-Plus-Demo</name > <description > Mybatis-Plus-Demo</description > <properties > <java.version > 1.8</java.version > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-jdbc</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <scope > runtime</scope > </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 > <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.1.1</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.12</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <scope > 4.12</scope > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <configuration > <excludes > <exclude > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </exclude > </excludes > </configuration > </plugin > </plugins > </build > </project >
yml配置文件 yml配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 server: port: 9090 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/mybatis-plus-first?serverTimezone=GMT%2b8 username: root password: qwer1234 mybatis-plus: global-config: db-config: id-type: auto configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath:mapper/*.xml type-aliases-package: roydon.xyz.mybatisplusdemo.entity
数据库 新建数据库文件:
1 2 3 4 5 6 7 8 9 CREATE TABLE `tb_user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID' , `user_name` varchar (20 ) NOT NULL COMMENT '用户名' , `password` varchar (20 ) NOT NULL COMMENT '密码' , `name` varchar (30 ) DEFAULT NULL COMMENT '姓名' , `age` int DEFAULT NULL COMMENT '年龄' , `email` varchar (50 ) DEFAULT NULL COMMENT '邮箱' , PRIMARY KEY (`id`) ) ENGINE= InnoDB AUTO_INCREMENT= 6 DEFAULT CHARSET= utf8;
导入数据:
1 2 3 4 5 6 7 8 9 10 INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('1' , 'zhangsan' , '123456' , '张三' , '18' , 'test1@itcast.cn' ); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('2' , 'lisi' , '123456' , '李四' , '20' , 'test2@itcast.cn' ); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('3' , 'wangwu' , '123456' , '王五' , '28' , 'test3@itcast.cn' ); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('4' , 'zhaoliu' , '123456' , '赵六' , '21' , 'test4@itcast.cn' ); INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('5' , 'sunqi' , '123456' , '孙七' , '24' , 'test5@itcast.cn' );
实体类User 项目新建实体类User
:
注意下方注解用法:
@Data @AllArgsConstructor @NoArgsConstructor // 简化set,get
@TableName(“tb_user”) // 指定表名
@TableField // 下方已给出作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package roydon.xyz.mybatisplusdemo.entity;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data @AllArgsConstructor @NoArgsConstructor @TableName("tb_user") public class User { private Long id; private String userName; @TableField(select = false) private String password; @TableField(value = "name") private String nickName; private Integer age; private String email; @TableField(exist = false) private String address; }
UserMapper 新建UserMapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package roydon.xyz.mybatisplusdemo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import roydon.xyz.mybatisplusdemo.entity.User;public interface UserMapper extends BaseMapper <User> { }
通过继承BaseMapper就可以获取到各种各样的单表操作,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package com.baomidou.mybatisplus.core.mapper;import com.baomidou.mybatisplus.core.conditions.Wrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import java.io.Serializable;import java.util.Collection;import java.util.List;import java.util.Map;import org.apache.ibatis.annotations.Param;public interface BaseMapper <T> extends Mapper <T> { int insert (T entity) ; int deleteById (Serializable id) ; int deleteByMap (@Param("cm") Map<String, Object> columnMap) ; int delete (@Param("ew") Wrapper<T> wrapper) ; int deleteBatchIds (@Param("coll") Collection<? extends Serializable> 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) ; T selectOne (@Param("ew") Wrapper<T> queryWrapper) ; Integer 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) ; IPage<T> selectPage (IPage<T> page, @Param("ew") Wrapper<T> queryWrapper) ; IPage<Map<String, Object>> selectMapsPage (IPage<T> page, @Param("ew") Wrapper<T> queryWrapper) ; }
UserMapper.xml 1 2 3 4 5 6 7 8 9 10 11 <?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 ="roydon.xyz.mybatisplusdemo.mapper.UserMapper" > <select id ="getById" resultType ="user" > select * from tb_user where id = #{id}; </select > </mapper >
MybatisPlusConfig 新建MP
配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package roydon.xyz.mybatisplusdemo.config;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration @MapperScan("roydon/xyz/mybatisplusdemo/mapper") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor () { return new PaginationInterceptor (); } }
Test 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 package roydon.xyz.mybatisplusdemo;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 org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import roydon.xyz.mybatisplusdemo.entity.User;import roydon.xyz.mybatisplusdemo.mapper.UserMapper;import javax.annotation.Resource;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;@SpringBootTest class MybatisPlusDemoApplicationTests { @Resource private UserMapper userMapper; @Test public void testSelectById () { userMapper.selectById(2L ); } @Test public void testSelectOne () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("name" , "张三" ); userMapper.selectOne(wrapper); } @Test void testSelectBatchIds () { userMapper.selectBatchIds(Arrays.asList(1L , 2L , 3L )); } @Test public void testSelectList () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.like("email" , "itcast" ); userMapper.selectList(wrapper); } @Test public void testSelectByMap () { Map<String, Object> map = new HashMap <>(); map.put("user_name" , "zhangsan" ); map.put("password" , "123456" ); userMapper.selectByMap(map); } @Test public void testSelectPage () { IPage<User> page = new Page <>(0 , 2 ); QueryWrapper<User> queryWrapper = new QueryWrapper <>(); queryWrapper.like("password" , "123456" ); userMapper.selectPage(page, queryWrapper); System.out.println("数据总条数" + page.getTotal()); System.out.println("数据总页数" + page.getPages()); System.out.println("当前页数" + page.getCurrent()); } @Test public void testSelectCount () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.gt("age" , 20 ); userMapper.selectCount(wrapper); } @Test public void testUpdateById () { User user = new User (); user.setId(1L ); user.setAge(19 ); user.setPassword("666666" ); userMapper.updateById(user); } @Test public void testUpdate () { User user = new User (); user.setAge(20 ); user.setPassword("8888888" ); QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("user_name" , "zhangsan" ); userMapper.update(user, wrapper); } @Test public void testUpdate2 () { UpdateWrapper<User> updateWrapper = new UpdateWrapper <>(); updateWrapper.set("age" , 21 ).set("password" , "999999" ) .eq("user_name" , "zhangsan" ); userMapper.update(null , updateWrapper); } @Test public void testInsert () { User user = new User (); user.setUserName("baomidou" ); user.setNickName("苞米豆" ); user.setPassword("123456" ); user.setAge(30 ); user.setEmail("insert@itcast.cn" ); user.setAddress("北京" ); userMapper.insert(user); System.out.println("id => " + user.getId()); } @Test public void testDelete () { User user = new User (); user.setUserName("baomidou" ); user.setPassword("123456" ); QueryWrapper<User> wrapper = new QueryWrapper <>(user); userMapper.delete(wrapper); } @Test public void testDeleteById () { userMapper.deleteById(5L ); } @Test public void testDeleteByMap () { Map<String, Object> map = new HashMap <>(); map.put("user_name" , "lisi" ); map.put("password" , "123456" ); userMapper.deleteByMap(map); } @Test public void testDeleteBatchIds () { userMapper.deleteBatchIds(Arrays.asList(3L , 4L )); } @Test void selById () { userMapper.getById(1L ); } @Test public void testAllEq () { Map<String, Object> params = new HashMap <>(); params.put("name" , "李四" ); params.put("age" , "20" ); params.put("password" , null ); QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.allEq((k, v) -> (k.equals("age" ) || k.equals("id" ) || k.equals("name" )), params); userMapper.selectList(wrapper); } @Test public void testEq () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("password" , "123456" ) .ge("age" , 20 ) .in("name" , "李四" , "王五" , "赵六" ); userMapper.selectList(wrapper); } @Test public void testLike () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.likeLeft("name" , "五" ); userMapper.selectList(wrapper); } @Test public void testOrderByAgeDesc () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.orderByDesc("age" ); userMapper.selectList(wrapper); } @Test public void testOr () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("name" , "王五" ).or().eq("age" , 21 ); userMapper.selectList(wrapper); } @Test public void testSelect () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("name" , "王五" ) .or() .eq("age" , 21 ) .select("id" , "name" , "age" ); userMapper.selectList(wrapper); } }
条件构造器 指路—>官方文档:https://baomidou.com/pages/10c804/#abstractwrapper
allEq 1 2 3 allEq(Map<R, V> params) allEq(Map<R, V> params, boolean null2IsNull) allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
个别参数说明:
params
: key
为数据库字段名,value
为字段值null2IsNull
: 为true
则在map
的value
为null
时调用 isNull 方法,为false
时则忽略value
为null
的
例1: allEq({id:1,name:"老王",age:null})
—->id = 1 and name = '老王' and age is null
例2: allEq({id:1,name:"老王",age:null}, false)
—->id = 1 and name = '老王'
1 2 3 allEq(BiPredicate<R, V> filter, Map<R, V> params) allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
个别参数说明:
filter
: 过滤函数,是否允许字段传入比对条件中params
与 null2IsNull
: 同上
例1: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})
—->name = '老王' and age is null
例2: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)
—->name = '老王'
基本比较操作
eq
等于 =
ne
不等于 <>
gt
大于 >
ge
大于等于 >=
lt
小于 <
le
小于等于 <=
between
BETWEEN 值1 AND 值2
notBetween
NOT BETWEEN 值1 AND 值2
in
字段 IN (value.get(0), value.get(1), …)
notIn
字段 NOT IN (v0, v1, …)
模糊查询
LIKE ‘%值%’
例: like(“name”, “王”) —-> name like ‘%王%’
notLike
NOT LIKE ‘%值%’
例: notLike(“name”, “王”) —-> name not like ‘%王%’
likeLeft
LIKE ‘%值’
例: likeLeft(“name”, “王”) —-> name like ‘%王’
likeRight
LIKE ‘值%’
例: likeRight(“name”, “王”) —-> name like ‘王%’
排序
例: orderBy(true, true, “id”, “name”) —-> order by id ASC,name ASC
例: orderByAsc(“id”, “name”) —-> order by id ASC,name ASC
例: orderByDesc(“id”, “name”) —-> order by id DESC,name DES
逻辑查询
拼接 OR
主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接)
AND 嵌套
例: and(i -> i.eq(“name”, “李白”).ne(“status”, “活着”)) —-> and (name = ‘李白’ and status <> ‘活着’)
select 在MP查询中,默认查询所有的字段,如果有需要也可以通过select方法进行指定字段。
1 2 3 4 5 6 7 8 9 10 @Test public void testSelect () { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("name" , "王五" ) .or() .eq("age" , 21 ) .select("id" , "name" , "age" ); userMapper.selectList(wrapper); }
代码生成器(新) Github—>https://github.com/roydonGuo/Mybatis-Plus-Generator