一 、MyBatisPlus 介绍 转自mybatisplus官网 下方附有mybatisplus官方网站

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
(1)愿景
我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
(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、SQLServer2005、SQLServer 等多种数据库
⑪内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
⑫内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

代码及文档发布地址
官方地址:
http://mp.baomidou.com
代码发布地址:
Github: https://github.com/baomidou/mybatis-plus
Gitee: https://gitee.com/baomidou/mybatis-plus
文档发布地址:
http://mp.baomidou.com/#/?id=%E7%AE%80%E4%BB%8B
二、 springboot 快速开始使用
快速开始参考:http://mp.baomidou.com/guide/quick-start.html
测试项目: mybatis_plus
数据库:mybatis_plus
1 创建并初始化数据库
(1)创建数据库:
mybatis_plus
(2)创建 User 表
其表结构如下:

其对应的数据库 Schema 脚本如下:
DROP TABLE IF EXISTS user;
CREATE TABLE 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)
);
其对应的数据库 Data 脚本如下:
DELETE FROM user;
INSERT INTO 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');
2 初始化工程
使用 Spring Initializr 快速初始化一个 Spring Boot 工程
Group:com.Daniel
Artifact:mybatis-plus
版本:2.0.7.RELEASE
<mybatis-plus.version>3.0.5</mybatis-plus.version>
pom.xml
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>daniel-parent</artifactId> 7 <groupId>com.daniel</groupId> 8 <version>0.0.1-SNAPSHOT</version> 9 <relativePath>../daniel-parent/pom.xml</relativePath> 10 </parent> 11 <modelVersion>4.0.0</modelVersion> 12 13 <groupId>com.daniel</groupId> 14 <artifactId>mybatis-plus</artifactId> 15 16 <dependencies> 17 <dependency> 18 <groupId>org.springframework.boot</groupId> 19 <artifactId>spring-boot-starter</artifactId> 20 </dependency> 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-test</artifactId> 24 <scope>test</scope> 25 </dependency> 26 <!--mybatis-plus--> 27 <dependency> 28 <groupId>com.baomidou</groupId> 29 <artifactId>mybatis-plus-boot-starter</artifactId> 30 <version>3.0.5</version> 31 </dependency> 32 <!--mysql--> 33 <dependency> 34 <groupId>mysql</groupId> 35 <artifactId>mysql-connector-java</artifactId> 36 </dependency> 37 <!--lombok用来简化实体类--> 38 <dependency> 39 <groupId>org.projectlombok</groupId> 40 <artifactId>lombok</artifactId> 41 </dependency> 42 </dependencies> 43 44</project>
3 配置
在 application.properties 配置文件中添加 MySQL 数据库的相关配置:
注意:
(1)springboot2.0.x和springboot2.1.x使用不同
springboot2.1.x版本时候,写数据库驱动和数据库路径时候不一样的
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
(2)springboot1.x和springboot2.x区别
①springboot1.x底层使用spring4.x
②springboot2.x底层使用spring5.x
本工程由于父工程为2.0.7故配置文件为:(为完整配置已经进行过完整的mybatis的基本功能测试)
1spring.datasource.driver-class-name=com.mysql.jdbc.Driver 2spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus 3spring.datasource.username=****** 4spring.datasource.password=****** 5#mybatis日志 6mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 7#全局设置主键生成策略 8#global-config 全局配置对所的类起作用 9#mybatis-plus.global-config.db-config.id-type=auto 10#其它主键策略:分析 IdType 源码可知 11#配置的是逻辑删除的删除的两个状态值,默认也是这两个配不配都可以 12mybatis-plus.global-config.db-config.logic-delete-value=1 13mybatis-plus.global-config.db-config.logic-not-delete-value=0 14#环境设置:dev、test、prod 本工程为SQL 执行性能分析插件时设置 15spring.profiles.active=dev
4 编写代码
(1)主类
在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹
注意:扫描的包名根据实际情况修改
1@SpringBootApplication 2@MapperScan("com.atguigu.mybatisplus.mapper") 3public class MybatisPlusApplication { 4public static void main(String[] args) { 5 SpringApplication.run(MybatisPlusApplication.class,args); 6} 7}
(2)实体
创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)
1@Data 2public class User { 3private Long id; 4private String name; 5private Integer age; 6private String email; 7}
Lombok使用参考:
https://blog.csdn.net/motui/article/details/79012846
(3)mapper
创建包 mapper 编写Mapper 接口: UserMapper.java
1@Component 2public interface UserMapper extends BaseMapper<User> { 3}
5 开始使用
添加测试类,进行功能测试:
1@RunWith(SpringRunner.class) 2@SpringBootTest 3public class MybatisPlusApplicationTests { 4 5@Autowired 6private UserMapper userMapper; 7 8@Test 9public void testSelectList() { 10System.out.println(("----- selectAll method test ------")); 11//UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper 12//所以不填写就是无任何条件 13List<User> users = userMapper.selectList(null); 14users.forEach(System.out::println); 15} 16}
6 基本的crud
以下为测试代码
1package com.daniel.mp; 2 3import org.mybatis.spring.annotation.MapperScan; 4import org.springframework.boot.SpringApplication; 5import org.springframework.boot.autoconfigure.SpringBootApplication; 6 7/** 8 * @author Daniel 9 * @Description: 10 */ 11@SpringBootApplication 12public class MpApplication { 13 public static void main(String[] args) { 14 SpringApplication.run(MpApplication.class,args); 15 } 16} 17 18package com.daniel.mp.entity; 19 20import com.baomidou.mybatisplus.annotation.*; 21import lombok.AllArgsConstructor; 22import lombok.Data; 23import lombok.NoArgsConstructor; 24import lombok.ToString; 25 26import java.util.Date; 27import java.util.logging.FileHandler; 28 29/** 30 * @author Daniel 31 * @Description: 32 */ 33@Data 34@ToString 35@NoArgsConstructor 36@AllArgsConstructor 37public class User { 38 @TableId(type = IdType.ID_WORKER) 39 private Long id; 40 private String name; 41 private Integer age; 42 private String email; 43 @TableField(fill = FieldFill.INSERT) 44 private Date createTime; 45 @TableField(fill = FieldFill.INSERT_UPDATE) 46 private Date updateTime; 47 @Version 48 @TableField(fill = FieldFill.INSERT) 49 private Integer version; 50 @TableLogic 51 @TableField(fill = FieldFill.INSERT) 52 private Integer deleted; 53} 54 55package com.daniel.mp.mapper; 56 57import com.atguigu.mp.entity.User; 58import com.baomidou.mybatisplus.core.mapper.BaseMapper; 59import org.springframework.stereotype.Component; 60 61/** 62 * @author Daniel 63 * @Description: 64 */ 65@Component 66public interface UserMapper extends BaseMapper<User> { 67} 68 69 70package com.daniel.mp.config; 71 72import com.baomidou.mybatisplus.core.injector.ISqlInjector; 73import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; 74import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; 75import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 76import org.mybatis.spring.annotation.MapperScan; 77import org.springframework.boot.SpringBootConfiguration; 78import org.springframework.context.annotation.Bean; 79import org.springframework.transaction.annotation.EnableTransactionManagement; 80 81/** 82 * @author Daniel 83 * @Description: 84 */ 85@MapperScan("com.atguigu.mp.mapper") 86@SpringBootConfiguration 87@EnableTransactionManagement 88public class MybatisPlusConfig { 89 /** 90 * 乐观锁插件 91 */ 92 @Bean 93 public OptimisticLockerInterceptor optimisticLockerInterceptor(){ 94 return new OptimisticLockerInterceptor(); 95 } 96 /** 97 * 逻辑删除插件 98 */ 99 @Bean 100 public ISqlInjector sqlInjector(){ 101 return new LogicSqlInjector(); 102 } 103 /** 104 * SQL 执行性能分析插件 105 * 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 106 */ 107 @Profile({"dev","test"})// 设置 dev test 环境开启 108 @Bean 109 public PerformanceInterceptor performanceInterceptor(){ 110 PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); 111 performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行 112 performanceInterceptor.setFormat(true); 113 return performanceInterceptor; 114 } 115} 116 117package com.daniel.mp.handler; 118 119import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 120import org.apache.ibatis.reflection.MetaObject; 121import org.slf4j.Logger; 122import org.slf4j.LoggerFactory; 123import org.springframework.stereotype.Component; 124 125import java.util.Date; 126 127/** 128 * @author Daniel 129 * @Description: 130 */ 131@Component 132public class MyMetaObjectHandler implements MetaObjectHandler { 133 private static final Logger LOGGER = LoggerFactory.getLogger(MetaObjectHandler.class); 134 135 @Override 136 public void insertFill(MetaObject metaObject) { 137 LOGGER.debug("开始insert fill ..."); 138 this.setFieldValByName("createTime",new Date(),metaObject); 139 this.setFieldValByName("updateTime",new Date(),metaObject); 140 this.setFieldValByName("version",1,metaObject); 141 this.setFieldValByName("deleted",0,metaObject); 142 143 } 144 145 @Override 146 public void updateFill(MetaObject metaObject) { 147 LOGGER.debug("开始update fill ..."); 148 this.setFieldValByName("updateTime",new Date(),metaObject); 149 } 150} 151 152 153package com.daniel.mp.test; 154 155import com.daniel.mp.entity.User; 156import com.daniel.mp.mapper.UserMapper; 157import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 158import com.baomidou.mybatisplus.core.metadata.IPage; 159import com.baomidou.mybatisplus.core.toolkit.IdWorker; 160import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 161import org.junit.Test; 162import org.junit.runner.RunWith; 163import org.springframework.beans.factory.annotation.Autowired; 164import org.springframework.boot.test.context.SpringBootTest; 165import org.springframework.test.context.junit4.SpringRunner; 166 167import java.util.Arrays; 168import java.util.HashMap; 169import java.util.List; 170import java.util.Map; 171 172/** 173 * @author Daniel 174 * @Description: 175 */ 176//public final class SpringRunner extends org.springframework.test.context.junit4.SpringJUnit4ClassRunner { 177@RunWith(SpringRunner.class) 178@SpringBootTest 179public class MybatisPlusApplicationTests { 180 181 @Autowired 182 UserMapper userMapper; 183 184 @Test 185 public void testSelect() { 186// List<User> users = userMapper.selectList(null); 187// users.forEach(System.out::println); 188 /* 189 * User(id=1, name=Jone, age=18, email=test1@baomidou.com) 190 *User(id=2, name=Jack, age=20, email=test2@baomidou.com) 191 *User(id=3, name=Tom, age=28, email=test3@baomidou.com) 192 *User(id=4, name=Sandy, age=21, email=test4@baomidou.com) 193 *User(id=5, name=Billie, age=24, email=test5@baomidou.com) 194 * */ 195 //SELECT id,name,age,email FROM user WHERE id=? 196// User user = userMapper.selectById(1L); 197// System.err.println(user);//User(id=1, name=Jone, age=18, email=test1@baomidou.com) 198// 199// List<Long> ids = Arrays.asList(1L, 2L, 3L); 200// //SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? , ? ) 201// List<User> users = userMapper.selectBatchIds(ids); 202// users.forEach(System.err::println); 203 //当配置了性能优化时,设置为1ms时 204 // The SQL execution time is too large, please optimize ! 205 /* 206 User(id=1, name=Jone, age=18, email=test1@baomidou.com) 207 User(id=2, name=Jack, age=20, email=test2@baomidou.com) 208 User(id=3, name=Tom, age=28, email=test3@baomidou.com) 209 */ 210// Map<String,Object> map = new HashMap<>(); 211// map.put("name","Jack"); 212// map.put("age",20); 213// List<User> users = userMapper.selectByMap(map); 214// users.forEach(System.err::println);//User(id=2, name=Jack, age=20, email=test2@baomidou.com) 215 216 //本查询需要借助于分页插件 PaginationInterceptor 与 SSM框架整合不同 217 Page<User> page = new Page<>(1,2); 218 IPage<User> userIPage = userMapper.selectPage(page, null); 219 List<User> users = userIPage.getRecords(); 220 users.forEach(System.err::println); 221 System.err.println("当前页:"+page.getCurrent()); 222 System.err.println("每页显示记录数:"+page.getSize()); 223 System.err.println("总记录数:"+page.getTotal()); 224 System.err.println("总页数:"+page.getPages()); 225 System.err.println("总记录数:"+page.getTotal()); 226 System.err.println("是否下一页:"+page.hasNext()); 227 System.err.println("是否上一页:"+page.hasPrevious()); 228 /* 229 SELECT 230 id, 231 name, 232 age, 233 email, 234 create_time, 235 update_time, 236 version, 237 deleted 238 FROM 239 user 240 WHERE 241 deleted=0 LIMIT 0,2 242 User(id=1, name=Jone, age=18, email=test1@baomidou.com, createTime=Thu Aug 15 09:31:29 GMT+08:00 2019, updateTime=Thu Aug 15 09:31:29 GMT+08:00 2019, version=1, deleted=0) 243 User(id=2, name=Jack, age=20, email=test2@baomidou.com, createTime=Thu Aug 15 09:31:29 GMT+08:00 2019, updateTime=Thu Aug 15 09:31:29 GMT+08:00 2019, version=1, deleted=0) 244 当前页:1 245 每页显示记录数:2 246 总记录数:6 247 总页数:3 248 总记录数:6 249 是否下一页:true 250 是否上一页:false 251 */ 252 //本查询需要借助于分页插件 PaginationInterceptor 253// Page<User> page = new Page<>(1,5); 254// IPage<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, null);//?????? 255// //注意:此行必须使用 mapIPage 获取记录列表,否则会数据类型转换错误 256// List<Map<String, Object>> users = mapPage.getRecords(); 257// users.forEach(System.err::println); 258// System.err.println("当前页:"+page.getCurrent()); 259// System.err.println("每页显示记录数:"+page.getSize()); 260// System.err.println("总记录数:"+page.getTotal()); 261// System.err.println("总页数:"+page.getPages()); 262// System.err.println("总记录数:"+page.getTotal()); 263// System.err.println("是否下一页:"+page.hasNext()); 264// System.err.println("是否上一页:"+page.hasPrevious()); 265 /* 266 SELECT 267 id, 268 name, 269 age, 270 email, 271 create_time, 272 update_time, 273 version, 274 deleted 275 FROM 276 user 277 WHERE 278 deleted=0 LIMIT 0,5 279 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Jone, id=1, version=1, age=18, email=test1@baomidou.com} 280 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Jack, id=2, version=1, age=20, email=test2@baomidou.com} 281 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Tom, id=3, version=1, age=28, email=test3@baomidou.com} 282 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Sandy, id=4, version=1, age=21, email=test4@baomidou.com} 283 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Billie, id=5, version=1, age=24, email=test5@baomidou.com} 284 当前页:1 285 每页显示记录数:5 286 总记录数:6 287 总页数:2 288 总记录数:6 289 是否下一页:true 290 是否上一页:false 291 */ 292 } 293 294 @Test 295 public void testInsert() { 296 User user = new User(); 297 user.setName("苏洵"); 298 user.setEmail("sx@daniel.com"); 299 user.setAge(182); 300 //加了版本号后 301 //INSERT INTO user ( id, name, age, email, create_time, update_time, version ) VALUES ( ?, ?, ?, ?, ?, ?, ? ) 302 //加了时间后 303 //INSERT INTO user ( id, name, age, email, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ? ) 304 //INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) 305 int insert = userMapper.insert(user); 306 System.out.println("影响了" + insert + "行");//影响了1行 307// //id自动回填 System.out.println(user);//User(id=1161598217527648258, name=苏明玉, age=30, email=smy@daniel.com) 308 309 } 310 311 312 @Test 313 public void testIdWorker(){ 314 long id = new com.atguigu.mp.utils.IdWorker().nextId(); 315 System.out.println(id);//1161599849573281792 316 317 } 318 319 @Test 320 public void testUpdate(){ 321 User user = new User(); 322 user.setId(5L); 323 user.setName("苏明成"); 324 user.setEmail("smy@daniel.com"); 325 user.setAge(30); 326 //UPDATE user SET name=?, age=?, email=?, update_time=? WHERE id=? 327// UPDATE user SET name=?, age=?, email=? WHERE id=? 328 int updateById = userMapper.updateById(user); 329 System.out.println("修改了" + updateById + "行");//修改了1行 330 331 } 332 /** 333 * 测试 乐观锁插件 334 */ 335 @Test 336 public void testOptimisticLocker(){ 337 User user = userMapper.selectById(1L); 338 user.setName("苏辙"); 339 user.setAge(111); 340 user.setEmail("sz@daniel.com"); 341 //UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=? 342 //版本号如果对应不上修改就不会成功 343 user.setVersion(user.getVersion()-1); 344 int updateById = userMapper.updateById(user); 345 System.out.println("修改了" + updateById + "行");//修改了1行 346 347 } 348 @Test 349 public void testDelete(){ 350 //DELETE FROM user WHERE id=? 351 int rows = userMapper.deleteById(3L); 352 System.out.println(rows + "行被删除了!!!");//1行被删除了!!! 353 } 354 @Test 355 public void testDeleteBatchIds() { 356 //DELETE FROM user WHERE id IN ( ? , ? , ? ) 357// int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));//公司基本不会用删除的命令 358// System.out.println(result); 359 } 360 361 /** 362 * 测试 逻辑删除 363 */ 364 @Test 365 public void testLogicDelete(){ 366 //UPDATE user SET deleted=1 WHERE id=? AND deleted=0 367 int rows = userMapper.deleteById(3L); 368 System.out.println(rows + "行被删除了!!!");//1行被删除了!!! 369 } 370 371 /** 372 * wrapper 的测试由此往下 条件构造器 373 * 1、delete 374 *2、selectOne 375 *3、selectCount 376 *4、selectList 377 5、selectMaps 378 6、selectObjs 379 7、update 380 */ 381 @Test 382 public void testWrapperSelect(){ 383// QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 384// queryWrapper.isNotNull("name") 385// .ge("age",28) 386// .le("age",110); 387// List<User> users = userMapper.selectList(queryWrapper); 388// users.forEach(System.err::println); 389 /* 390 Execute SQL: 391 SELECT 392 id, 393 name, 394 age, 395 email, 396 create_time, 397 update_time, 398 version, 399 deleted 400 FROM 401 user 402 WHERE 403 deleted=0 404 AND name IS NOT NULL 405 AND age >= 28 406 AND age <= 110 407 */ 408 409 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 410 queryWrapper.eq("name","苏大强"); 411 User user = userMapper.selectOne(queryWrapper); 412 System.out.println(user); 413 } 414}
7 条件构造器

Wrapper : 条件构造抽象类,最顶端父类
|---AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
|---QueryWrapper : Entity 对象封装操作类,不是用lambda语法
|---UpdateWrapper : Update 条件封装,用于Entity对象更新操作
|---AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
|---LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
|---LambdaUpdateWrapper : Lambda 更新封装Wrapper
1/** 2 * @author Daniel 3 * @create 2019--08--15--11:41 4 * @Description: 5 */ 6@RunWith(SpringRunner.class) 7@SpringBootTest 8public class QueryWrapperTests { 9 10 @Autowired 11 private UserMapper userMapper; 12}
注意:以下条件构造器的方法入参中的 column 均表示数据库字段
(1) ge、gt、le、lt、isNull、isNotNull
1@Test 2public void testDelete(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 queryWrapper 5 .isNull("name") 6 .ge("age", 12) 7 .isNotNull("email"); 8 int result = userMapper.delete(queryWrapper); 9 System.out.println("delete return count = " + result); 10 11}
SQL:UPDATE user SET deleted=1 WHERE deleted=0 AND name IS NULL AND age >= ? AND email IS NOT NULL
(2) eq、ne
注意:seletOne返回的是一条实体记录,当出现多条时会报错
1@Test 2public void testSelectOne() { 3 4 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 5 queryWrapper.eq("name", "Tom"); 6 7 User user = userMapper.selectOne(queryWrapper); 8 System.out.println(user); 9}
SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ?
(3) between、notBetween
包含大小边界
1@Test 2public void testSelcecCount(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 queryWrapper.between("age",20,30); 5 Integer integer = userMapper.selectCount(queryWrapper); 6 System.out.println("20<-->30之间" + integer + "人"); 7 //SELECT COUNT(1) FROM user WHERE deleted=0 AND age BETWEEN ? AND ? 8}
(4)allEq
1@Test 2public void testAllEq(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 Map<String, Object> map = new HashMap<>(); 5 map.put("id",2L); 6 map.put("name","Jack"); 7 map.put("age",20); 8 queryWrapper.allEq(map); 9 List<User> users = userMapper.selectList(queryWrapper); 10 users.forEach(System.err::println); 11//SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND name = ? AND id = ? AND age = ? 12}
(5)like、notLike、likeLeft、likeRight
selectMaps返回Map集合列表
1@Test 2public void testSelectMaps(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 queryWrapper.notLike("name","e") 5 .likeRight("email","t"); 6 List<Map<String, Object>> mapList = userMapper.selectMaps(queryWrapper);//返回值是Map列表 7 mapList.forEach(System.err::println); 8 /* 9 姓名中不含e且邮箱以e开头 10 SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND name NOT LIKE '%e%' AND email LIKE 't%' 11 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Jack, id=2, version=1, age=20, email=test2@baomidou.com} 12 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Tom, id=3, version=1, age=28, email=test3@baomidou.com} 13 {update_time=2019-08-15 09:31:29.0, deleted=0, create_time=2019-08-15 09:31:29.0, name=Sandy, id=4, version=1, age=21, email=test4@baomidou.com} 14 */ 15}
(6)in、notIn、inSql、notinSql、exists、notExists
in、notIn:
notIn("age",{1,2,3})--->age not in (1,2,3)
notIn("age", 1, 2, 3)--->age not in (1,2,3)
inSql、notinSql:可以实现子查询
例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
exits和notExists
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。
EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,
这一行行可作为外查询的结果行,否则不能作为结果。
1 @Test 2 public void testSelectObjs(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4// queryWrapper.in("id",1,2,3,4);//SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND id IN (?,?,?,?) 5 // SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND id IN (select id from user where id < 3) 6// queryWrapper.inSql("id","select id from user where id < 3"); 7// List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表 8// objects.forEach(System.err::println); 9// SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND EXISTS (select id from user where age = 2) 10 //当exists内的子查询值(非空)时返回true当无值为空(null)时返回false 11 queryWrapper.exists("select id from user where age = 2"); 12 List<Object> objects = userMapper.selectObjs(queryWrapper); 13 objects.forEach(System.err::println); 14 }
(7)or、and
注意:这里使用的是 UpdateWrapper
不调用or则默认为使用 and 连
1@Test 2public void testUpdateOrAnd(){ 3 //本例修改后其版本号为改变故此修改不合理 4 //修改或其他改变数据值得操作均需要携带version值 5 //修改值 6 User user = new User(); 7 user.setVersion(1); 8 user.setAge(99); 9 user.setName("Andy"); 10 //修改条件 11 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); 12 updateWrapper.like("name","d") 13 .or() 14 .between("age",98,100); 15 int update = userMapper.update(user, updateWrapper); 16 System.out.println(update + "行被修改"); 17 /* 18 UPDATE user SET name='Andy', age=99, update_time='2019-08-15 16:32:53', version=2 WHERE deleted=0 AND name LIKE '%d%' OR age BETWEEN 98 AND 100 AND version = 1 19 */ 20}
(8)嵌套or、嵌套and
这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号
1@Test 2public void testUpdateLambdaOrAnd(){ 3 //本例修改后其版本号为改变故此修改不合理 4 //修改或其他改变数据值得操作均需要携带version值 5 //修改值 6 User user = new User(); 7 user.setVersion(1); 8 user.setAge(99); 9 user.setName("Andy"); 10 //修改条件 11 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); 12 updateWrapper.like("name","a") 13 .or(i->i.eq("name","苏洵").ne("age",20)); 14 int update = userMapper.update(user, updateWrapper); 15 System.out.println(update + "行被修改"); 16 /* 17 UPDATE user SET name='Andy', age=99, update_time='2019-08-15 16:47:02', version=2 WHERE deleted=0 AND name LIKE '%a%' OR ( name = '苏洵' AND age <> 20 ) AND version = 1 18 */ 19}
(9) orderBy、orderByDesc、orderByAsc
1@Test 2public void testSelectListOrderBy(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 queryWrapper.orderByDesc("id","age"); 5 List<User> users = userMapper.selectList(queryWrapper); 6 users.forEach(System.err::println); 7 /* 8 SELECT id, name, age, email, create_time,update_time, version, deleted FROM user WHERE deleted=0 ORDER BY id DESC , age DESC 9 */ 10}
(10) last
直接拼接到 sql 的最后
注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
1@Test 2public void testSelectListLast(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 //SELECT id,name,age,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 limit 1,2 5 queryWrapper.last("limit 1,2"); 6 List<User> users = userMapper.selectList(queryWrapper); 7 users.forEach(System.err::println); 8}
(11) 指定要查询的列
1@Test 2public void testSelectListColumn(){ 3 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); 4 queryWrapper.select("name","age","id"); 5 List<User> users = userMapper.selectList(queryWrapper); 6 users.forEach(System.err::println); 7 /* 8 SELECT name, age, id FROM user WHERE deleted=0 9 */ 10}
12、set、setSql
最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段
1@Test 2public void testUpdateSet(){ 3 //修改值 4 User user = new User(); 5 user.setVersion(3); 6 user.setAge(1099); 7 8 //修改条件 9 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); 10 updateWrapper.like("name","大") 11 .set("name","王大强") 12 .setSql("email='wang@daniel.com'"); 13 int update = userMapper.update(user, updateWrapper); 14 System.out.println(update + "行被修改"); 15 /* 16 UPDATE user SET age=1099,update_time='2019-08-15 17:24:28', version=4,name='王大强', email='wang@daniel.com' WHERE deleted=0 AND name LIKE '%大%' 17 AND version = 3 18 */ 19}
mybatisplus官网对条件构造器的描述也很详细可以去看看