【mybatis-高级篇】
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【mybatis-高级篇】相关的知识,希望对你有一定的参考价值。
参考技术A Mybatis的四大对象
Executor
ParameterHandler
ResultSetHandler
StatementHandler
一个MappedStatement代表一个增删改查的详细信息
Configuration包含全局配置,所有映射文件信息,接口信息
MappedStatement:一个sql对应一个MappedStatement
MapperProxyFactory:生成MapperProxy实例
Executor:执行增删改查,其中调用StatementHandler处理
原理分析
1、获取SqlSessionFactory对象
把配置文件的信息解析并保存在Configuration对象中(包含所有的映射文件信息、接口信息等),返回包含了Configuration的DefaultSqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2、获取SqlSession
返回SqlSession的实现类Default对象,包含了Executor和Configuration;会有拦截器链(interceptChain.pluginAll(executor))对Executor进行插入修饰。
3、getMapper
getMapper使用MapperProxyFactory创建一个MapperProxy的代理对象,包含了DefaultSqlSession(Executor)
4、执行方法
创建MapperMethodInvoker(接口,有invoke方法),PlainMethodInvoker写入本次方法查询相关信息(MapperMethod),MapperMethod包括SqlCommand和MethodSignature。调用MapperMethodInvoker.invoke方法执行操作=>PlainMethodInvoker中调用MapperMethod.excute方法。MapperMethod.excute是真正执行方法。调用MapperStatment
通过调用代理类执行方法,创建StatementHandler(ParameterHandler,ResultSetHandler)处理器对象,使用处理器调用底层JDBC执行SQL返回结果。
总结:
责任链模式+动态代理+反射机制
插件编写
https://github.com/abel533/MyBatis-Spring-Boot
方法一:
设置全局步骤defaultExecutorType=BATCH,表示所有的查询都使用批量处理
方法二:
获得批量处理的sqlSession进行处理 SqlSession sqlSessin = sqlSessionFactory.openSession(Executor.BATCH)
方法三:
整合注入sqlSession,class=SqlSessionTemplate,类型executorTyepe=BATCH,然后aurowired使用
1、实现TypeHandler接口,或者继承BaseTypeHandler
2、配置使用自定义TypeHandler
方式一:全局配置
方式二:独立配置
每天玩转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
表结构如下:
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来查询
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/
关于作者:专注于移动开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
悟空聊架构
关注我,带你每天进步一点点!
以上是关于【mybatis-高级篇】的主要内容,如果未能解决你的问题,请参考以下文章
每天玩转3分钟 MyBatis-Plus - 3. 高级查询(条件构造器)