每天玩转3分钟 MyBatis-Plus - 4. 高级查询(条件构造器)

Posted 7年一线互联网经验,超爱图解底层原理,全栈一枚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天玩转3分钟 MyBatis-Plus - 4. 高级查询(条件构造器)相关的知识,希望对你有一定的参考价值。

每天玩转3分钟 MyBatis-Plus - 1. 配置环境

每天玩转3分钟 MyBatis-Plus - 2. 普通查询

每天玩转3分钟 MyBatis-Plus - 3. 高级查询(一)

每天玩转3分钟 MyBatis-Plus - 4. 高级查询(二)

代码下载:https://github.com/Jackson0714/study-mybatis-plus.git

mybatis-plus的查询功能非常强大, 上一篇,我们通过例题的方式讲解了mybatis-plus的高级查询功能:条件查询,这一篇我们继续以例题的方式讲解mybatis-plus的高级查询功能。

准备数据

 1 DROP TABLE IF EXISTS user;
 2 
 3 CREATE TABLE user (user
 4     id BIGINT(20) PRIMARY KEY NOT NULL COMMENT \'主键\',
 5     name VARCHAR(30) DEFAULT NULL COMMENT \'姓名\',
 6     age INT(11) DEFAULT NULL COMMENT \'年龄\',
 7     email VARCHAR(50) DEFAULT NULL COMMENT \'邮箱\',
 8     manager_id BIGINT(20) DEFAULT NULL COMMENT \'直属上级id\',
 9     create_time DATETIME DEFAULT NULL COMMENT \'创建时间\',
10     CONSTRAINT manager_fk FOREIGN KEY (manager_id)
11         REFERENCES user (id)
12 )  ENGINE=INNODB CHARSET=UTF8;
13 
14 DELETE FROM user;
15 
16 INSERT INTO user (id, name, age, email,manager_id,create_time) VALUES
17 (1, \'Jone\', 18, \'test1@baomidou.com\', null, \'2020-01-01 14:20:20\'),
18 (2, \'Jack\', 20, \'test2@baomidou.com\', 1, \'2020-01-20 14:20:20\'),
19 (3, \'Tom\', 28, \'test3@baomidou.com\', 2, \'2020-01-15 14:20:20\'),
20 (4, \'Sandy\', 21, \'test4@baomidou.com\', 2, \'2020-01-12 14:20:20\'),
21 (5, \'Billie\', 24, \'test5@baomidou.com\', 2, \'2020-01-22 14:20:20\');

 

User 表结构如下:

idnameageemailmanager_idcreate_time
1 Jone 18 test1@baomidou.com null
2020-01-01 14:20:20
2 Jack 20 test2@baomidou.com 1
2020-01-20 14:20:20
3 Tom 28 test3@baomidou.com 2
2020-01-15 14:20:20
4 Sandy 21 test4@baomidou.com 2
2020-01-12 14:20:20
5 Billie 24 test5@baomidou.com 2
2020-01-22 14:20:20

 

 

一、案例汇总(第二波)

1.1 查询创建日期为2020年1月15日并且直属上级的名字为J开头的

难度系数 ★★★★

二、案例讲解

1.1 查询创建日期为2020年1月15日并且直属上级的名字为J开头的

难度系数 ★★★★

考察 apply 和 inSql的用法

(1)先用sql 语句来试下怎么写

这里需要用到子查询,先查询出name为“J”开头的集合1,然后再查询出manger_id 与集合1中的id相等的集合

SELECT * FROM demo.user
WHERE date_format(create_time, \'%Y-%m-%d\') =\'2020-01-15\' 
AND manager_id in (SELECT id FROM demo.user WHERE name LIKE \'J%\');

(2)我们还可以用INNER JOIN来查询

1 SELECT user1.* FROM demo.user AS user1
2 INNER JOIN demo.user AS user2 ON user1.manager_id = user2.id 
3 WHERE date_format(user1.create_time, \'%Y-%m-%d\') =\'2020-01-15\' 
4 AND user2.name LIKE \'J%\' 

(3)在mabatis-plus中可以用“apply” 来实现动态拼接sql

apply有两种用法:

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)

第一种有SQL注入的风险,稍后我们再介绍,先介绍第二种用法

queryWrapper.apply("date_format(create_time, \'%Y-%m-%d\')={0}","2020-01-15")

(4)子查询我们可以用inSql

1 inSql
2 inSql(R column, String inValue)
3 inSql(boolean condition, R column, String inValue)
4 字段 IN ( sql语句 )
5 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
6 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
例题中的写法:
.inSql("manager_id", "select id from user where name like \'J%\'");

(5)完整示例

 1     /*
 2      * 描述:例1.4 查询创建日期为2020年1月15日并且直属上级的名字为“J”开头的
 3      * SQL语句方案一:SELECT * FROM demo.user where date_format(create_time, \'%Y-%m-%d\') =\'2020-01-15\' AND manager_id in (select id from user where name like \'J%\');
 4      * SQL语句方案二:SELECT user1.* FROM demo.user AS user1 INNER JOIN demo.user AS user2 ON user1.manager_id = user2.id WHERE date_format(user1.create_time, \'%Y-%m-%d\') =\'2020-01-15\' AND user2.name LIKE \'J%\'
 5      * 作者:博客园-悟空聊架构
 6      * 时间:2019-01-29
 7      * Github:https://github.com/Jackson0714/study-mybatis-plus.git
 8      * 博客园:https://www.cnblogs.com/jackson0714
 9      * */
10     @Test
11     public void testSelectByQueryWrapper4() {
12         System.out.println(("----- 查询创建日期为2020年1月15日并且直属上级的名字为“J”开头的 ------"));
13         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
14         //queryWrapper.apply("date_format(create_time, \'%Y-%m-%d\')=\'2020-01-15\' or true or true") // SQL注入
15         queryWrapper.apply("date_format(create_time, \'%Y-%m-%d\')={0}","2020-01-15")
16                 .inSql("manager_id", "select id from user where name like \'J%\'");
17         List<User> userList = userMapper.selectList(queryWrapper);
18         userList.forEach(System.out::println);
19     }

 

 查询日志:

SQL语句执行结果

 

 (6)动态拼接中的SQL注入

apply的第一种写法,传入的参数是 \'2020-01-15\'

queryWrapper.apply("date_format(create_time, \'%Y-%m-%d\')=\'2020-01-15\'")

如果传入的是 "\'2020-01-15\' or true or true",则apply写法如下:

queryWrapper.apply("date_format(create_time, \'%Y-%m-%d\')=\'2020-01-15\' or true or true")

 则拼接后的SQL语句如下:

SELECT id,name,age,email,manager_id,create_time FROM user 
WHERE (date_format(create_time, \'%Y-%m-%d\')=\'2020-01-15\' or true or true AND manager_id IN (select id from user where name like \'J%\'))

 

执行该SQL语句,可以查询出所有user数据,造成隐私泄露。

 

 

 

每天玩转3分钟 MyBatis-Plus - 1. 配置环境

每天玩转3分钟 MyBatis-Plus - 2. 普通查询

每天玩转3分钟 MyBatis-Plus - 3. 高级查询(一)

每天玩转3分钟 MyBatis-Plus - 4. 高级查询(二)

 

关注公众号:悟空聊架构,回复pmp,领取pmp资料!回复悟空,领取架构师资料!


作  者:悟空聊架构 
出  处:http://www.cnblogs.com/jackson0714/ 
关于作者:专注于移动开发。如有问题或建议,请多多赐教! 
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力! 

悟空聊架构 

关注我,带你每天进步一点点!

以上是关于每天玩转3分钟 MyBatis-Plus - 4. 高级查询(条件构造器)的主要内容,如果未能解决你的问题,请参考以下文章

每天玩转3分钟 MyBatis-Plus - 3. 高级查询(条件构造器)

每天玩转3分钟 MyBatis-Plus - 1. 配置环境

每天5分钟玩转容器技术 整理目录

创建 Pool & VIP - 每天5分钟玩转 OpenStack(122)

每天5分钟玩转Kubernetes | Dashboard典型使用场景

每天5分钟玩转Kubernetes | Kubernetes架构