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

时间:2022-11-13 15:10:43

每天玩转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的高级查询功能。

准备数据

 DROP TABLE IF EXISTS user;

 CREATE TABLE user (user
id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主键',
name VARCHAR(30) DEFAULT NULL COMMENT '姓名',
age INT(11) DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
manager_id BIGINT(20) DEFAULT NULL COMMENT '直属上级id',
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
CONSTRAINT manager_fk FOREIGN KEY (manager_id)
REFERENCES user (id)
) ENGINE=INNODB CHARSET=UTF8; DELETE FROM user; INSERT INTO user (id, name, age, email,manager_id,create_time) VALUES
(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');

User 表结构如下:

id name age email manager_id create_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来查询

 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%'

(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

 inSql
inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
字段 IN ( sql语句 )
例: 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)
例题中的写法:
.inSql("manager_id", "select id from user where name like 'J%'");

(5)完整示例

     /*
* 描述:例1.4 查询创建日期为2020年1月15日并且直属上级的名字为“J”开头的
* 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%');
* 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%'
* 作者:博客园-悟空聊架构
* 时间:2019-01-29
* Github:https://github.com/Jackson0714/study-mybatis-plus.git
* 博客园:https://www.cnblogs.com/jackson0714
* */
@Test
public void testSelectByQueryWrapper4() {
System.out.println(("----- 查询创建日期为2020年1月15日并且直属上级的名字为“J”开头的 ------"));
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//queryWrapper.apply("date_format(create_time, '%Y-%m-%d')='2020-01-15' or true or true") // SQL注入
queryWrapper.apply("date_format(create_time, '%Y-%m-%d')={0}","2020-01-15")
.inSql("manager_id", "select id from user where name like 'J%'");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}

查询日志:

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

SQL语句执行结果

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

(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 - 4. 高级查询(二)(条件构造器)

每天玩转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. 高级查询(二)(条件构造器)

悟空聊架构 

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