| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> MyBatis SQL执行过程与其他理论总结 -> 正文阅读 |
|
[大数据]MyBatis SQL执行过程与其他理论总结 |
目录 Xml 映射文件中,除了常见的 select|insert|update|delete 标签之外,还有哪些标签? MyBatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不? MyBatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复? MyBatis 映射文件中,如果 A 标签通过 include 引用了 B 标签的内容,请问,B 标签能否定义在 A 标签的后面,还是说必须定义在 A 标签的前面? MyBatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式? MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么? 简述 MyBatis 的插件运行原理,以及如何编写一个插件。 ?注意:本文参考? ?MyBatis 常见面试总结 | JavaGuide SQL执行过程Xml 映射文件中,除了常见的 select|insert|update|delete 标签之外,还有哪些标签?还有很多其他的标签,? MyBatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?MyBatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能,MyBatis 提供了 9 种动态 sql 标签?
MyBatis 里面的动态 Sql 一般是通过 if 节点来实现,通过 OGNL 语法来实现,但是如果要写的完整,必须配合 where,trim 节点,where 节点是判断包含节点有内容就插入 where,否则不插入,trim 节点是用来判断,如果动态语句是以 and 或 or 开始,那么会自动把这个 and 或者 or取掉。 使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。 MyBatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。 原因就是 namespace+id 是作为? MyBatis 映射文件中,如果 A 标签通过 include 引用了 B 标签的内容,请问,B 标签能否定义在 A 标签的后面,还是说必须定义在 A 标签的前面?虽然 MyBatis 解析 Xml 映射文件是按照顺序解析的,但是,被引用的 B 标签依然可以定义在任何地方,MyBatis 都可以正确识别。 原理是,MyBatis 解析 A 标签,发现 A 标签引用了 B 标签,但是 B 标签尚未解析到,尚不存在,此时,MyBatis 会将 A 标签标记为未解析状态,然后继续解析余下的标签,包含 B 标签,待所有标签解析完毕,MyBatis 会重新解析那些被标记为未解析的标签,此时再解析 A 标签时,B 标签已经存在,A 标签也就可以正常解析完成了。 模糊查询like语句该怎么写?第1种:在Java代码中添加sql通配符。 ?第2种:在sql语句中拼接通配符,会引起sql注入 MyBatis 一对一关联查询有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配association节点配置一对一的类就可以完成; 嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。 MyBatis 一对多关联查询有联合查询和嵌套查询。 联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成; 嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。 关联对象查询,有两种实现方式,一种是单独发送一个 sql 去查询关联对象,赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用 join 查询,一部分列是 A 对象的属性值,另外一部分列是关联对象 B 的属性值,好处是只发一个 sql 查询,就可以把主对象和其关联对象查出来。 那么问题来了,join 查询出来 100 条记录,如何确定主对象是 5 个,而不是 100 个?其去重复的原理是? 同样主对象的关联对象,也是根据这个原理去重复的,尽管一般情况下,只有主对象会有重复记录,关联对象一般不会重复。 举例:下面 join 查询出来 6 条记录,一、二列是 Teacher 对象列,第三列为 Student 对象列,MyBatis 去重复处理后,结果为 1 个老师 6 个学生,而不是 6 个老师 6 个学生。
传入sql参数 获取结果为什么需要预编译SQL 预编译指的是数据库驱动在发送 SQL 语句和参数给 DBMS 之前对 SQL 语句进行编译,这样 JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化SQL 的执行。预编译之后的 SQL 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的 还有一个重要的原因,防止SQL注入 #{}和${}的区别是什么?
在mapper中如何传递多个参数?方法1:顺序传参法 #{}里面的数字代表传入参数的顺序。 这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。 方法2:@Param注解传参法? #{}里面的名称对应的是注解@Param括号里面修饰的名称。 这种方法在参数不多的情况还是比较直观的,(推荐使用)。 方法3:Map传参法? #{}里面的名称对应的是Map里面的key名称。 这种方法适合传递多个参数,且参数易变能灵活传递的情况。(推荐使用)。 方法4:Java Bean传参法? #{}里面的名称对应的是User类里面的成员属性。 这种方法直观,需要建一个实体类,扩展不容易,需要加属性,但代码可读性强,业务逻辑处理方 MyBatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?第一种是使用? 第二种是使用 resultType,和sql 列的别名功能,将列别名书写为对象属性名 比如 T_NAME AS NAME,对象属性名一般是 name,小写,但是列名不区分大小写,MyBatis 会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成 T_NAME AS NaMe,MyBatis 一样可以正常工作。 有了列名与属性名的映射关系后,MyBatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。? 他们两个的区别就是,sql返回结果字段a,b。 resultType就是直接找到某个java的pojo M,利用反射将M的a字段设置成sql结果字段a的值。 resultMap就是有一个额外的映射,结果字段a,b映射成A,B,再把sql映射结果映射到某个java的pojo M,利用反射将M的a字段设置成sql结果字段A,B的值。 MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么?MyBatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 MyBatis 配置文件中,可以配置是否启用延迟加载? 它的原理是,使用? 当然了,不光是 MyBatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。 MyBatis 是否可以映射 Enum 枚举类?MyBatis 可以映射枚举类,不单可以映射枚举类,MyBatis 可以映射任何对象到表的一列上。映射方式为自定义一个? 如何获取自动生成的(主)键值?insert方法总是返回一个int值,这个值代表的是插入的行数。如果采用自增长策略,自动生成的键值在insert方法执行完后可以被设置到传入的参数对象中。示例:? MyBatis 执行批量插入,能返回数据库主键列表吗?能,JDBC 都能,MyBatis 当然也能。 当实体类中的属性名和表中的字段名不一样 ,怎么办 ?其他简述 MyBatis 的插件运行原理,以及如何编写一个插件。MyBatis 仅可以编写针对? MyBatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是? 实现 MyBatis 的 Interceptor 接口并复写? MyBatis 是如何进行分页的?分页插件的原理是什么?1?MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页; 2 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能 3 也可以使用分页插件来完成物理分页。 分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。 举例:? Mybatis的一级、二级缓存一级缓存 基于PerpetualCache 的HashMap本地缓存,其存储作用域为Session,当Sessionflush 或 close之后,该Session 中的所有Cache就将清空,默认打开一级缓存。 在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。 每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis 根据当前执行的语句生成 MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。具体实现类的类关系图如下图所示: 1. MyBatis一级缓存的生命周期和 SqlSession一致。 2. MyBatis 一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。 3. MyBatis 的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。? 二级缓存 在上文中提到的一级缓存中,其最大的共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存。开启二级缓存后,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,先在CachingExecutor进行二级缓存的查询,具体的工作流程如下所示。 二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存被多个SqlSession共享,是一个全局的变量。 当开启缓存后,数据的查询执行的流程为: 二级缓存->一级缓存->数据库 1 MyBatis 的二级缓存相对于一级缓存来说,实现了SqlSession 之间缓存数据的共享,同时粒度更加细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。 2 MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。 3 在分布式环境下,由于默认的MyBatis Cache 实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis, Memcached 等分布式缓存可能成本更低,安全性也更高。? 4 二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache, HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ; 5 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear. |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 11:29:26- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |