每天玩轉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, '[email protected]', null, '2020-01-01 14:20:20'),
18 (2, 'Jack', 20, '[email protected]', 1, '2020-01-20 14:20:20'),
19 (3, 'Tom', 28, '[email protected]', 2, '2020-01-15 14:20:20'),
20 (4, 'Sandy', 21, '[email protected]', 2, '2020-01-12 14:20:20'),
21 (5, 'Billie', 24, '[email protected]', 2, '2020-01-22 14:20:20');

 

User 表結構如下:

idnameageemailmanager_idcreate_time
1 Jone 18 [email protected] null
2020-01-01 14:20:20
2 Jack 20 [email protected] 1
2020-01-20 14:20:20
3 Tom 28 [email protected] 2
2020-01-15 14:20:20
4 Sandy 21 [email protected] 2
2020-01-12 14:20:20
5 Billie 24 [email protected] 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/ 
關於作者:專注於移動開發。如有問題或建議,請多多賜教! 
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。 
特此聲明:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我 
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力! 

悟空聊架構 

關注我,帶你每天進步一點點!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章