mybatis基础简介
1.mybatis的加载过程?
程序首先加载mybatis-config.xml文件,根据配置文件创建SQLSessionFactory对象;
然后通过SQLSessionFactory对象创建SQLSession对象,SQLSession接口中定义了执行SQL语句的方法;
之后通过SQLSession对象执行mapper.xml映射文件中定义的SQL语句;
最后通过SQLSession对象提交事务,关闭SQLSession对象
2.mybatis的整体架构?
架构分为三层:接口层(SqlSession),核心处理层,基础支持层。
3.xml常见解析方式
DOM(Document Object Model):树型解析,一个标签对应一个节点,标签中的文本是文本节点。好处:易于编程。缺点:当xml文件数据过大,会造成大量资源消耗
SAX(Simple API for XML):基于事件解析,只将部分XML文档加载到内存解析,不会记录文档中的数据,占用资源小。缺点:内存中不存储数据,只能开发人员自己负责维护业务逻辑涉及的多层节点之间的关系;另一方面,因为流式处理,只能从前到后单向进行,不能自由切换节点。采用“推模式”,即事件是由解析器产生并通过回调函数发送给程序的
StAX(Streaming API for XML):采用“拉模式”,应用程序通过调用解析器推进解析的过程。可以决定随时停止解析和处理多个XML文档。
==mybatis使用DOM解析方式解析xml映射文件,XPath是专为查询XML文档设计的语言。与DOM配合使用。==
4. 使用数据库连接池的好处?
实现数据库连接的重用
提高响应速度
防止数据库连接过多造成数据库假死
避免数据库连接泄露等
5.数据库连接池介绍?
数据库连接池在初始化时,一般创建一定数量的数据库连接添加的连接池备用。当程序需要连接时,直接在池中请求;不再使用该链接时,又返回到池中缓存,等待下次使用,不直接关闭。当然,也会控制==连接总数==的上限和==空闲连接数==的上限,如果连接总数达到上限且都被占用,则后续请求线程进入阻塞队列等待。如果连接池中的空闲连接数较多,达到上限,则后续返回的空闲连接直接关闭。注意:设置这两个数值大小要适当,不然当总连接数上限设置过大,可能数据库僵死,如果过小,无法发挥性能,浪费数据库资源。当空闲连接数上限过大,浪费系统资源来维护;如果过小,出现峰值请求时,系统的响应变弱。
6.在dao层只写了mapper接口,接口怎么实现的?
基础支持层中binding模块的问题,Binding模块有几个核心组件,
这里写图片描述
在Mybatis初始化过程中,读取映射文件以及mapper接口中的注释信息,并调用MapperRegistry.addMapper()方法填充MapperRegistry.knownMapper集合,该集合key值是Mapper接口对应的Class对象,value为MapperProxyFactory对象,为Mapper接口创建代理对象。要执行SQL语句时,调用MapperRegistry.getMapper()方法获取代理对象。MapperProxy实现Invocationhandler接口(代理对象的核心逻辑),MapperProxy.invoke()方法是执行的主要逻辑。MapperMethod中封装了Mapper接口中对应方法的信息,以及SQL语句信息,其中最主要的方法是execute()方法,根据SQL语句的类型调用SQLSession对应的犯法实现数据库操作。
7.mybatis中的缓存机制?
mybatis作为ORM框架,提供了两层缓存结果。
* 一级缓存是会话级别的缓存,在mybatis中没创建一个SQLSession对象,就表示开启一次数据库会话。在一次会话中可能会反复执行完全相同的查询语句,如果没有缓存,会造成数据库资源浪费。mybatis的SQLSession通过Executor对象完成数据库的操作,所以在Executor对象中建立了一个简单的缓存,即一级缓存。它每次将查询结果对象缓存起来,在执行查询操作时,先找缓存中是否存在一样的查询语句,找到的话直接取出相应结果对象返回。第二个功能,如果一级缓存中缓存了嵌套查询的结果对象,则可以直接加载结果对象;如果一级缓存中记录的嵌套查询结果对象并未完全加载,在可以通过DeferredLoad(BaseExcutor内部类)实现类似延迟加载的功能。
一级缓存的生命周期与SQLSession相同,其实就是与Executor对象生命周期相同。当Excutor对象调用close()方法时,一级缓存就不可用了。一级缓存默认开启。
* 二级缓存是应用级别的缓存,它的生命周期与应用程序相同。CachingExcutor是Excutor接口的装饰器,为Excutor对象增加了二级缓存功能。二级缓存配置有三个。
配置:(1) 在mybatis-config.xml配置中CacheEnabled配置,它是二级缓存总开关,只有它为true时,后2个配置才有效;
<settings>
<setting name="cacheEnabled" value="true" />
...
</settings>
(2)映射配置文件中可以配置和节点,配置任何一个节点都表示二级缓存开启。
(3)在节点中的useCache属性,该属性表示查询操作产生的对象是否要保存的二级缓存中。默认值为true。
当执行查询时,先查询二级缓存,再查询一级缓存,二级缓存中的结果对象被所有命名空间namespace共享。
一级缓存是直接将查询结果写入;
二级缓存是要在事务提交的时候才将TransactionalCache.entriesTAddOnCommit集合中缓存的数据写入。
8. mybatis的分页插件?
mybatis本身可以通过RowRounds方式进行分页,但是它并没有转换成分页相关的SQL语句,而是通过调用ResultSet.absolute()方法或循环调用ResultSet.next()方法定位到指定的记录行。当表中数据较大时,这种分页仍然会查询全表数据,性能不行。
@Intercepts({@Signature(type = Excutor.class, method="query", args= {
MappedStatment.class, Object.class, RowBounds.class, Resulthandler.class})})
public class PageInterceptor implements Interceptor{...}
一个常用的插件PageInterceptor插件类,它还依赖了Dialect接口(Dialect是策略模式实现)。
PageInterceptor中通过@Intercepts注解信息和Singnature注解信息,拦截Excutor.query(MappedStatmen,Object,RowBounds,ResultHandler)方法进行分页。如果要拦截其他方法,可自行定义修改@Signature注解。
-- mysql 的分页是limit实现的 offset,length offset代表从那儿开始,length代表查询几个
select * from t_user limit 10,10
-- Oracle 的分页是通过RowNum 实现的
select * from (
select u.* ,RowNum row from (select * from t_user) u where RowNum <= 20
) where rn > 10
正是因为不同数据库的分页方式不同,所以才为PageInterceptor添加Dialect策略。
注意:当mysql分页时,limit offset,length 中的offset值特别大时,查询性能会很差。例如:
select * from t_user limit 1000000,100;
意思是扫描满足条件的1000100行,扔掉前面的1000000,只要后面的100行。
-- 通过索引进行优化。本例中user_id为user主键,存储引擎为InnoDB,所以user_id自带聚集索引。
select * from t_user where user_id>=(select user_id from t_user limit 1000000,1) limit 100;
10.#{}和${}的区别?
${}是==properties文件中的变量占位符==,它可以用于标签属性值和sql内部,属于静态文本替换。它在这里应用,如下:
执行SQL:select * from user where user_name = ${userName}
参数:employeeName传入值为:Smith
解析后执行的SQL:Select * from emp where name =Smith
这样的话,就很容易被注入攻击,如userName=“or 1=1” ,就可以随意访问了。
#{}是==sql的参数占位符==,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值。如下:
如上,不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了==预编译==功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。
11.mybatis是怎么实现预编译的?
其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。
mybatis基础简介的更多相关文章
- mybatis基础系列(一)——mybatis入门
好久不发博客了,写博文的一个好处是能让心静下来,整理下之前学习过的一些知识一起分享,大神路过~ mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. ...
- 现代3D图形编程学习-基础简介(2) (译)
本书系列 现代3D图形编程学习 基础简介(2) 图形和渲染 接下去的内容对渲染的过程进行粗略介绍.遇到的部分内容不是很明白也没有关系,在接下去的章节中,会被具体阐述. 你在电脑屏幕上看到的任何东西,包 ...
- 现代3D图形编程学习-基础简介(1) (译)
本书系列 现代3D图形编程学习 基础简介 并不像本书的其他章节,这章内容没有相关的源代码或是项目.本章,我们将讨论向量,图形渲染理论,以及OpenGL. 向量 在阅读这本书的时候,你需要熟悉代数和几何 ...
- myBatis 基础测试 表关联关系配置 集合 测试
myBatis 基础测试 表关联关系配置 集合 测试 测试myelipse项目源码 sql 下载 http://download.csdn.net/detail/liangrui1988/599388 ...
- MyBatis基础:MyBatis缓存(5)
1. MyBatis缓存简介 MyBatis提供支持一级缓存及二级缓存. 一级缓存: 2.MyBatis一级缓存
- JAVA之Mybatis基础入门--框架搭建与简单查询
JAVA中,操作数据库有JDBC.hibernate.Mybatis等技术,今天整理了下,来讲一讲下Mybatis.也为自己整理下文档: hibernate是一个完全的ORM框架,是完全面向对象的.但 ...
- MyBatis基础入门《二十》动态SQL(foreach)
MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...
- mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存
关本文是Mybatis基础系列的第四篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(三)——动态sql mybatis基础系列(二)——基础语法.别名.输入映射.输出映射 mybat ...
- mybatis基础系列(三)——动态sql
本文是Mybatis基础系列的第三篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(二)--基础语法.别名.输入映射.输出映射 mybatis基础系列(一)--mybatis入门 动态 ...
随机推荐
- HTML连载23-属性选择器(上)
一.属性选择器 1. (1)定义:根据指定的 属性名称找到对应的标签,然后设置属性 (2)格式:标签[属性=值]:{属性:值:] 注意:前一个值是不带引号的 (3)例子: <style> ...
- ServiceFabric极简文档-3. 发布脚本
web: Trap { Write-Host $_.Exception.Message; Continue }; Connect-ServiceFabricCluster Remove-Service ...
- 【CodeForces - 1167C 】News Distribution(并查集)
News Distribution 题意 大概就是分成几个小团体,给每个人用1 - n编号,当对某个人传播消息的时候,整个小团体就知道这个消息,输出 分别对1 - n编号的某个人传递消息时,有多少人知 ...
- [leetcode] 300. Longest Increasing Subsequence (Medium)
题意: 求最长增长的子序列的长度. 思路: 利用DP存取以i作为最大点的子序列长度. Runtime: 20 ms, faster than 35.21% of C++ online submissi ...
- [leetcode] 543. Diameter of Binary Tree (easy)
原题 思路: 题目其实就是求左右最长深度的和 class Solution { private: int res = 0; public: int diameterOfBinaryTree(TreeN ...
- 地图组件demo
高德地图API(demo未完善) 1:声请JSAPI的key值:http://lbs.amap.com/dev/#/(已声请key名称:demo-javascipt key:7cbbed2d9a0c0 ...
- 【Arduino】66种传感器模块系列实验(2)---光敏电阻模块
实验二:光敏电阻传感器模块我手里这块是三针版的,挺秀气吧 光敏电阻是用硫化隔或硒化隔等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应.光照愈强,阻值就愈低,随着光照强度的升高,电阻值迅速降低, ...
- 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关
重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...
- spark 源码分析之三 -- LiveListenerBus介绍
LiveListenerBus 官方说明如下: Asynchronously passes SparkListenerEvents to registered SparkListeners. 即它的功 ...
- 转 java - java基础知识点
转 https://www.cnblogs.com/xdp-gacl/p/3641769.html 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可 ...