请选择 进入手机版 | 继续访问电脑版

12360技术网 - 专业IT技术发表平台

 立即注册  找回密码
查看: 4641|回复: 6

一文搞定 MyBatis,经典问题集锦

[复制链接]

23

主题

31

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2020-1-24 08:23:14 | 显示全部楼层 |阅读模式
1、啥是 MyBatis?

MyBatis 是一个半自动 ORM 持久层框架,她内部对 JDBC 做了封装,并使用 XML 或注解来配置和映射数据库信息,开发人员只需要关注 SQL 语句本身,避免了处理繁琐的数据库映射过程,使 Java 代码和 SQL 完全分离,有利于分层开发,提高开发效率和灵活性。
2、MyBatis 的优缺点和适用场景?

1)优点

  • 基于SQL语句编程,非常灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除SQL与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。       
  • 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;       
  • 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。       
  • 能够与Spring很好的集成;       
  • 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
2)缺点

  • SQL语句的编写工作量较大,尤其当字段多、关联表多时。       
  • 不支持方言,数据库移植性差。       
  • SQL存在XML文件中,调试不方便。       
  • 对动态SQL的支持不是很好,提供的标签过于简单。       
  • 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。
3)适用场景
MyBatis 解耦了 SQL 和 程序代码,适合业务逻辑相对复杂或者变动频繁的场景,可以使开发人员专注于 SQL 逻辑的修改。目前,在互联网、金融等项目中,MyBatis 是不错的选择。
3、MyBatis 与 Hibernate 的区别?


  • Hibernate 是全自动 ORM框架,而 MyBatis是一个 半自动 ORM 框架,MyBatis 需要程序员自己编写 SQL 语句。       
  • MyBatis 直接编写原生态 SQL,可以严格控制 SQL执行性能,灵活度高,适合需求变化频繁的项目,但是对数据库的依赖较大,移植性差。Hibernate 的灵活度相对较低,但是做到了数据库的无关性,移植性较好。
总结:MyBatis 半自动,SQL分离,灵活度高,移植性差。Hibernate 全自动,SQL不分离,灵活度差,移植性好。
4、#{} 和 ${} 的区别,防注入?(重点)

#{} 是预编译处理,${}是字符串替换。

  • MyBatis 在处理#{}时,会将 sql 中的#{}替换为?号,sql语句解析会加上"",调用 PreparedStatement 的 set 方法来赋值,使用#{}可以有效的防止 SQL 注入,提高系统安全性。       
  • MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。${} 方式一般用于传入数据库对象,例如传入表名或配置信息。但是一般能用#的就别用$。
5、XML 映射文件中的常见标签?

除了最常见的 select|insert|updae|delete 外,还有、、、、,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。
6、MyBatis 的核心组件?


  • SqlSessionFactoryBuilder(构造器),根据代码或配置生成SqlSessionFactory,采用分布构建的 Builder 模式。       
  • SqlSessionFactory(工厂接口),生成SqlSession,采用的是工厂模式。       
  • SqlSession(会话),既可以发送SQL去执行并返回结果,也可以获取Mapper的接口。       
  • SQL Mapper(映射器),由一个Java接口和一个XML文件(或注解)构成,需要给出对应的SQL和映射规则,负责发送SQL并返回结果。
7、MyBatis 如何分页?

MyBatis 本身提供了 RowBounds 对象进行分页,她是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

  • RowBounds 对象进行分页,针对ResultSet结果集执行的内存分页,非物理分页。       
  • 插件分页,实现Mybatis提供的插件接口,如 PageHelper,物理分页,在插件的拦截方法内拦截待执行的sql,然后重写sql,添加对应的物理分页语句和物理分页参数。
8、MyBatis 都有哪些 Executor 执行器?

MyBatis有四种常见的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor  CachingExecutor

  • SimpleExecutor:单次执行。每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。       
  • ReuseExecutor:重复使用。执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。       
  • BatchExecutor:批量操作。执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。       
  • CachingExecutor:启用二级缓存。启用于二级缓存时的执行器,采用静态代理,代理一个 Executor 对象。执行 update 方法前判断是否清空二级缓存,执行 query 方法前先在二级缓存中查询,命中失败再通过被代理类查询。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。
9、MyBatis 的一级缓存和二级缓存?


  • 一级缓存:SqlSession 级别的缓存。基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。       
  • 二级缓存:Mapper 级别的缓存。与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 。
对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
10、MyBatis 的插件运行原理,如何编写一个插件?

Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
编写插件:实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
11、最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。在Mybatis中,每一个、、、标签,都会被解析为一个MappedStatement对象。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。
12、MyBatis 执行批量插入,能返回数据库主键列表吗?

能,JDBC都能,Mybatis当然也能。

  • 对于支持生成自增主键的数据库:增加 useGenerateKeys和keyProperty ,标签属性。       
  • 不支持生成自增主键的数据库:使用。
  1.   insert into Author (username, password, email, bio) values      (#{item.username}, #{item.password}, #{item.email}, #{item.bio})  
复制代码
13、MyBatis 动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
14、MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
15、MyBatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?

虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。
原理是,Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。
16、 ResultMap 和 ResultType 的区别?

resultType和resultMap功能类似 ,都是返回对象信息,区别在于resultMap要手动配置一下,表和类的对应关系当实体类和数据库表字段一一对应的时候,resultType会自动建立对应关系;当实体类和数据库表字段不一致的时候,使用resultMap手动建立对应关系。
在MyBatis进行查询映射时,查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。
1.resultType,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当提供的返回类型属性是resultType的时候,MyBatis会自动的给把对应的值赋给resultType所指定对象的属性
2.当提供的返回类型是resultMap时,因为Map不能很好表示领域模型,就需要自己再进一步的手动把它转化为对应的对象,这常常在复杂查询中很有作用。
17、MyBatis 是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用 标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
                                                                                                                        
                                                    
  • 点赞                        1                        
  • 收藏                        
  • 分享                                                                                                                        
  •                                                         
                                      
    • 文章举报                           
                                                
                                                                        
                                            
                                                        技术大咖秀                                                                发布了133 篇原创文章 · 获赞 131 · 访问量 4万+                                                                                            私信                                                            关注
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x




上一篇:华为IoT首席架构师王启军:全栈工程师“养成记”
下一篇:大数据框架HBase教程大汇总全集(附详细的图文解读和学习目录)
回复

使用道具 举报

0

主题

15

帖子

325

积分

中级会员

Rank: 3Rank: 3

积分
325
发表于 2020-1-24 17:18:33 | 显示全部楼层
楼主,大恩不言谢了![www.12360.co]
回复

使用道具 举报

0

主题

18

帖子

388

积分

中级会员

Rank: 3Rank: 3

积分
388
发表于 2020-2-3 23:39:19 | 显示全部楼层
既然你诚信诚意的推荐了,那我就勉为其难的看看吧![www.12360.co]
回复

使用道具 举报

0

主题

13

帖子

283

积分

中级会员

Rank: 3Rank: 3

积分
283
发表于 2020-2-6 02:23:44 | 显示全部楼层
这东西我收了!谢谢楼主![www.12360.co]
回复

使用道具 举报

0

主题

6

帖子

136

积分

注册会员

Rank: 2

积分
136
发表于 2020-2-9 03:04:03 | 显示全部楼层
楼主发贴辛苦了,谢谢楼主分享![www.12360.co]
回复

使用道具 举报

0

主题

18

帖子

388

积分

中级会员

Rank: 3Rank: 3

积分
388
发表于 2020-2-10 00:46:28 | 显示全部楼层
其实我一直觉得楼主的品味不错!呵呵![www.12360.co]
回复

使用道具 举报

0

主题

18

帖子

388

积分

中级会员

Rank: 3Rank: 3

积分
388
发表于 4 天前 | 显示全部楼层
楼主太厉害了!楼主,I*老*虎*U![www.12360.co]
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

12360技术网

GMT+8, 2020-2-22 11:21 , Processed in 0.109755 second(s), 25 queries .

本网站内容收集于互联网,Www.12360.Co不承担任何由于内容的合法性及健康性所引起的争议和法律责任。 欢迎大家对网站内容侵犯版权等不合法和不健康行为进行监督和举报。

© 2019-2020 Www.12360.Co

快速回复 返回顶部 返回列表