一、性能分析
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
SQL 性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题
1、配置插件
(1)参数说明
参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
参数:format: SQL是否格式化,默认false。
(2)在 MybatisPlusConfig 中配置
1 2 3 4 5 6 7 8 9 10 11 12
|
@Bean @Profile({"dev","test"}) public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(100); performanceInterceptor.setFormat(true); return performanceInterceptor; }
|
(3)Spring Boot 中设置dev环境
1 2 3
|
spring.profiles.active=dev
|
可以针对各环境新建不同的配置文件application-dev.properties、application-test.properties、application-prod.properties
也可以自定义环境名称:如test1、test2
2、测试
(1)常规测试
1 2 3 4 5 6 7 8 9 10 11
|
@Test public void testPerformance() { User user = new User(); user.setName("我是Helen"); user.setEmail("helen@sina.com"); user.setAge(18); userMapper.insert(user); }
|
输出

(2)将maxTime 改小之后再次进行测试
1
| performanceInterceptor.setMaxTime(5);
|
如果执行时间过长,则抛出异常:The SQL execution time is too large,
输出:

二、条件构造器
2.1 Wapper介绍

Wrapper : 条件构造抽象类,最顶端父类
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper : Entity 对象封装操作类,不是用lambda语法
- UpdateWrapper : Update 条件封装,用于Entity对象更新操作
- AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
- LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
1 2 3 4 5 6 7
| @RunWith(SpringRunner.class) @SpringBootTest public class QueryWrapperTests { @Autowired private UserMapper userMapper; }
|
2.2 AbstractWrapper
注意:以下条件构造器的方法入参中的 column 均表示数据库字段
1、ge、gt、le、lt、isNull、isNotNull
1 2 3 4 5 6 7 8 9 10 11
| @Test public void testDelete() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper .isNull("name") .ge("age", 12) .isNotNull("email"); int result = userMapper.delete(queryWrapper); System.out.println("delete return count = " + result); }
|
1
| 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 2 3 4 5 6 7 8 9
| @Test public void testSelectOne() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name", "Tom");
User user = userMapper.selectOne(queryWrapper); System.out.println(user); }
|
1
| SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ?
|
3、between、notBetween
包含大小边界
1 2 3 4 5 6 7 8 9
| @Test public void testSelectCount() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.between("age", 20, 30);
Integer count = userMapper.selectCount(queryWrapper); System.out.println(count); }
|
1
| SELECT COUNT(1) FROM user WHERE deleted=0 AND age BETWEEN ? AND ?
|
4、allEq
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void testSelectList() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); Map<String, Object> map = new HashMap<>(); map.put("id", 2); map.put("name", "Jack"); map.put("age", 20);
queryWrapper.allEq(map); List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println); }
|
1 2
| SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ? AND id = ? AND age = ?
|
5、like、notLike、likeLeft、likeRight
selectMaps返回Map集合列表
1 2 3 4 5 6 7 8 9 10 11
| @Test public void testSelectMaps() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper .notLike("name", "e") .likeRight("email", "t");
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper); maps.forEach(System.out::println); }
|
1 2
| SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name NOT LIKE ? AND email LIKE ?
|
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)
1 2 3 4 5 6 7 8 9 10
| @Test public void testSelectObjs() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.inSql("id", "select id from user where id < 3");
List<Object> objects = userMapper.selectObjs(queryWrapper); objects.forEach(System.out::println); }
|
7、or、and
注意:这里使用的是 UpdateWrapper
不调用or则默认为使用 and 连
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Test public void testUpdate1() {
User user = new User(); user.setAge(99); user.setName("Andy");
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like("name", "h") .or() .between("age", 20, 30);
int result = userMapper.update(user, userUpdateWrapper);
System.out.println(result); }
|
1
| UPDATE user SET name=?, age=?, update_time=? WHERE deleted=0 AND name LIKE ? OR age BETWEEN ? AND ?
|
8、嵌套or、嵌套and
这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Test public void testUpdate2() {
User user = new User(); user.setAge(99); user.setName("Andy");
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like("name", "h") .or(i -> i.eq("name", "李白").ne("age", 20));
int result = userMapper.update(user, userUpdateWrapper);
System.out.println(result); }
|
9、orderBy、orderByDesc、orderByAsc
1 2 3 4 5 6 7 8 9
| @Test public void testSelectListOrderBy() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc("id");
List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println); }
|
1 2
| SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 ORDER BY id DESC
|
10、last
直接拼接到 sql 的最后
注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
1 2 3 4 5 6 7 8 9
| @Test public void testSelectListLast() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.last("limit 1");
List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println); }
|
1 2
| SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 limit 1
|
11、指定要查询的列
1 2 3 4 5 6 7 8 9
| @Test public void testSelectListColumn() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.select("id", "name", "age");
List<User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::println); }
|
1
| SELECT id,name,age FROM user WHERE deleted=0
|
12、set、setSql
最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void testUpdateSet() {
User user = new User(); user.setAge(99);
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper .like("name", "h") .set("name", "老李头") .setSql(" email = '123@qq.com'");
int result = userMapper.update(user, userUpdateWrapper); }
|
1
| UPDATE user SET age=?, update_time=?, name=?, email = '123@qq.com' WHERE deleted=0 AND name LIKE ?
|
三、代码生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、 Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率
添加 代码生成器 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.1.tmp</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency>
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency>
|
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
| @SpringBootTest public class CodeGenerator {
@Test public void genCode() {
String moduleName = "mp";
AutoGenerator mpg = new AutoGenerator();
GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("zzxx"); gc.setOpen(false); gc.setFileOverride(true); gc.setServiceName("%sService"); gc.setIdType(IdType.ID_WORKER_STR); gc.setDateType(DateType.ONLY_DATE); gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/xueyuan_edu?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); dsc.setDbType(DbType.MYSQL); mpg.setDataSource(dsc);
PackageConfig pc = new PackageConfig(); pc.setModuleName(moduleName); pc.setParent("com.zzxx"); pc.setController("controller"); pc.setEntity("entity"); pc.setService("service"); pc.setMapper("mapper"); mpg.setPackageInfo(pc);
StrategyConfig strategy = new StrategyConfig(); strategy.setInclude("edu_teacher"); strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true);
strategy.setLogicDeleteFieldName("is_deleted"); strategy.setEntityBooleanColumnRemoveIsPrefix(true); TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT); TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE); ArrayList<TableFill> tableFills = new ArrayList<>(); tableFills.add(gmtCreate); tableFills.add(gmtModified); strategy.setTableFillList(tableFills);
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true); strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute(); } }
|
执行

