每天玩转 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 | manager_id | create_time | ||
---|---|---|---|---|---|---|
1 | Jone | 18 | test1@baomidou.com | null |
| |
2 | Jack | 20 | test2@baomidou.com | 1 |
| |
3 | Tom | 28 | test3@baomidou.com | 2 |
| |
4 | Sandy | 21 | test4@baomidou.com | 2 |
| |
5 | Billie | 24 | test5@baomidou.com | 2 |
|
一, 案例汇总 (第二波)
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);
- }
查询日志:
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 资料! 回复悟空, 领取架构师资料!
悟空聊架构
关注我, 带你每天进步一点点!
来源: https://www.cnblogs.com/jackson0714/p/study-mybatis-plus4.html