面试官问 ,Mybatis SELECT 查询, 集合或者单个对象,如果数据库不存在数据,需要判空吗?
前言
于昨日下班时段,本人正在与生活作斗争,收到了金三银四一线作战小队成员紧急反应的战况问题。
不熟悉的或者是不知道怎么去看源码的看官,上车了。
正文
这面试题问的, 考察的是什么?
① mybatis框架的应用掌握情况,如果经常用,也许是会踩坑的。
② mybatis框架源码的掌握情况,其实如果稍微看过一下源码,那这个问题还是非常明了的。
那么我们怎么去针对这个事,去了解清楚呢? 一起看看源码。
最简单的就是情景复现,debug进源码里面了。
现在就以这种最贴切的方式,带大家一块玩玩。
结论先放在最前面:
查询单条数据, 实体类接收,数据库如果没数据, 返回 的是 null , 这时候用的时候就需要判断返回值是否为null了,否则很容易报空指针。
查下多条数据, List、set集合接收, 数据库如果没数据, 返回 的是 一个size为0的 list , 这时候list不是null,但是里面的size确实没数据。
随手找到个整合了mybatis的项目, 直接写2个查询:
①查下单个数据,用实体类接收返回值
②查询多个数据,用list接收返回值
既然是针对数据库没有值的情况,看看mybatis返回的是null 还是 空值对象 。
所以我们在复现debug的时候,需要故意查询数据库没有数据的值,这样看源码的同时最后也能看结果。
我先给大家整理出这一轮源码的走向,当然这是熟悉整个mybatis执行sql过程之后就比较清晰的,如果不熟悉也没关系的,下面也是给大家一步步debug一起探索。
执行走向:
MybatisMapperProxy -> MybatisMapperMethod->SqlSessionTemplate->DefaultSqlSession->CachingExecutor->BaseExecutor->PreparedStatementHandler->DefaultResultSetHandler
不啰嗦,开整,先执行第一个,查询单个数据的。
首先进入到的是 MybatisMapperProxy.java
位置 :com.baomidou.mybatisplus.core.override.MybatisMapperProxy
接下来是 execute方法 ,MybatisMapperMethod.java :
位置 : com.baomidou.mybatisplus.core.override.MybatisMapperMethod
进一步简析:
其实到了这里,细看可以看到 在经历过第一步的invoke 之后, 已经是知道当前执行的mapper函数 是增删改查啥类型 ,同时也知道 returns 是 many 还是map还是单个等等。
我们现在是查下单个,debug就可以看到其实会走到下面的
result = sqlSession.selectOne(command.getName(), param);
直接点进去源码,继续看看怎么个事。
来到DefaultSqlSession.java 的 selectOne 方法 :
位置: org.apache.ibatis.session.defaults.DefaultSqlSession
到这其实已经非常明了,如果查询单个数据, 不存在? 那就是返回null 。
到这里,我们针对查下单个数据 ,数据库不存在的情况,其实已经水落石出,后续的debug源码感兴趣可以继续看,其实就是执行器怎么把数据处理转换设置返回了。
ps: 看源码,原来也不难啊?!
是的,特别是mybatis的源码,我个人是非常推荐大家看的,不止是排查问题和熟悉代码,还有整个mybatis框架的代码编写、设计模式,都是很nice的,非常推荐。
跟我有过沟通的小伙伴,我都是比较推荐mybatis框架源码的,听腻了的兄弟就当我啰嗦。
继续! 看看查询集合的情况。
开始!
看到我圈出来的东西没 ?
final MybatisMapperMethod mapperMethod = cachedMapperMethod(method);
通过invoke这第一步, 拿到的 mapperMethod , 其实就已经对当前执行的mapper函数,起底了。
无论是method的类型, returnMany=true ;
还是returnType的类型,是个List ;
又或是当前sql的类型,type是 SELECT .
那么接下来的流程,还是一样,继续看,到了 MybatisMapperMethod.java的 execute函数:
位置 com.baomidou.mybatisplus.core.override.MybatisMapperMethod
显然就算不debug走读,粗略一看你就可以知道是会执行
result = executeForMany(sqlSession, args);
继续debug进去看看这个 executeForMany :
来到了SqlSessionTemplate、 DefaultSqlSession 的 selectList 函数:
继续,然后是到了 CachingExecutor、BaseExecutor的 query 函数:
继续点,看看这个queryFromDatabase函数:
来到了 PreparedStatementHandler的 query函数:
位置 org.apache.ibatis.executor.statement.PreparedStatementHandler
即将水落石出!
看看这个DefaultResultSetHandler.java的 handleResultSets 函数 :
抓关键:
final List<Object> multipleResults = new ArrayList<>();
handleResultSet(rsw, resultMap, multipleResults, null);
collapseSingleResultList(multipleResults);
handleResultSet、collapseSingleResultList都是针对这个list做数据转换处理等操作(就算没数据,也是返回list,一个size为0的list),感兴趣的自己点进去,我已经收队了,有疑问看看警官怎么说。
好了,该篇就到这。
面试官问 ,Mybatis SELECT 查询, 集合或者单个对象,如果数据库不存在数据,需要判空吗?相关推荐
- 面试官问:select......for update会锁表还是锁行?
欢迎关注方志朋的博客,回复"666"获面试宝典 select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁 ...
- 【154期】面试官问:请你说说 B 树、B+ 树的原理及区别?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:35 更新文章,每天进步一点点... 之前在 ...
- 【067期】面试官问:说说常见的加密算法、原理、优缺点及用途?
>>号外:关注"Java精选"公众号,回复"面试资料",免费领取资料!"Java精选面试题"小程序,3000+ 道面试题在线刷, ...
- java执行sql文件_面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他
初识 MyBatis MyBatis 是第一个支持自定义 SQL.存储过程和高级映射的类持久框架.MyBatis 消除了大部分 JDBC 的样板代码.手动设置参数以及检索结果.MyBatis 能够支持 ...
- 【263期】面试官问:假设有一千万数据,怎么快速查询?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 前言 面试 ...
- 【255期】面试官问:MyBatis 二级缓存,如何实现关联刷新功能?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 1.MyB ...
- 面试官问:在读多写少的情况下,如何优化 MySQL 的数据查询方案
作者 | 面试官问 责编 | 张文 来源 | 面试官问(ID:interviewer_asked) 面试官问:假设你负责的某业务在双十一期间要搞运营活动,公司投入了大量的营销费用进行推广,此举 ...
- 【020期】面试官问:Java 遍历 Map 集合有几种方式?效率如何?
>>号外:关注"Java精选"公众号,回复"2021面试题",领取免费资料!"Java精选面试题"小程序,3000+ 道面试题在 ...
- 【266期】面试官问:为什么 SQL 要尽量避免使用 IN 和 NOT IN?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... IN 和 ...
- 【267期】面试官:Mybatis 如何实现流式读取 MySQL 大数据量记录?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 背景 最近 ...
最新文章
- HTML 特殊符号编码对照表
- Windows server 2008 R2 登录密码恢复
- 开始测试React Native App(下篇)
- 12 岁开始学编程,17 岁总结了 7 个重要教训!
- voc_eval.py:41: RuntimeWarning: invalid value encountered in greater_equal if np.sum(rec = t) ==
- AR头显要上天!欧洲太空总署或用HoloLens维修太空站
- JDK1.8下载安装(Windows版)
- torch.manual_seed(args.seed) torch.cuda.manul_seed_all(args.seed)和numpy.random.seed()
- xyplorer设置备忘
- html超酷图片墙特效代码,超酷超绚精美图片展示效果代码(一)
- 利用轻量级js插件Beer Slider实现新老图片的实时对比
- 两种远程桌面连接方法--远程桌面连接工具
- AI简史--从1308到2016
- bert 中文 代码 谷歌_BERT系列文章汇总导读
- python3[爬虫基础入门实战] 爬取豆瓣电影排行top250
- 利用Element UI的滑块Slider实现刻度尺
- 数据分析项目——深圳二手房价分析及价格预测
- P7960 [NOIP2021] 报数 埃氏筛法
- NISP一级模拟题(七、八)
- 支付宝和手机QQ春节红包热战正酣,百度终于出手了