二、MyBatis体系结构源码解读

1、MyBatis源码正确姿势

  • 技术本质
技术本质
  • 从宏观到微观
宏观理解

(1) mybatis数据源的源码解析 xml(environment) > java Environment
>org.apache.ibatis.session.SqlSessionFactoryBuilder.build(java.io.InputStream)
>org.apache.ibatis.builder.xml.XmlConfigBuilder
>org.apache.ibatis.builder.xml.XmlConfigBuilder.parseConfiguration
>org.apache.ibatis.builder.xml.XmlConfigBuilder.environmentsElement
>org.apache.ibatis.builder.xml.XmlConfigBuilder.dataSourceElement
>org.apache.ibatis.datasource.DataSourceFactory.getDataSource

mybatis获取数据源

(2) mybatis sql源码解析 sql > MappedStatement
>org.apache.ibatis.builder.xml.XmlConfigBuilder.mapperElement
>org.apache.ibatis.builder.xml.XmlMapperBuilder
>org.apache.ibatis.builder.xml.XmlMapperBuilder.parse
>org.apache.ibatis.builder.xml.XmlMapperBuilder.buildStatementFoemContext
>org.apache.ibatis.builder.xml.XmlStatementBuilder
>org.apache.ibatis.builder.xml.XmlStatementBuilder.parseStatementNode

mybatis获取sql

(3) mybatis 如何操作数据库 SimpleExecutor 执行器
>org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession
>org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFormDataSource
>org.apache.ibatis.session.Configuration.newExcetor
>org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne
>org.apache.ibatis.session.Configuration.getMappedStatement
>org.apache.ibatis.executor.BaseExecutor.queryFormDatabase
>org.apache.ibatis.executor.SimpleExecutor.doQuery

① SimpleExecutor是Mybatis执行Mapper语句时默认使用的Executor。它提供最基本的Mapper语句执行功能,没有过多的封装的
② ReuseExecutor,顾名思义,是可以重用的Executor。它重用的是Statement对象,它会在内部利用一个Map把创建的Statement都缓存起来,每次在执行一条SQL语句时,它都会去判断之前是否存在基于该SQL缓存的Statement对象,存在而且之前缓存的Statement对象对应的Connection还没有关闭的时候就继续用之前的Statement对象,否则将创建一个新的Statement对象,并将其缓存起来。因为每一个新的SqlSession都有一个新的Executor对象,所以我们缓存在ReuseExecutor上的Statement的作用域是同一个SqlSession。
③ BatchExecutor的设计主要是用于做批量更新操作的。其底层会调用Statement的executeBatch()方法实现批量操作。

MyBatis处理流程

2、MyBatis整体架构理解

  • myBatis 体系结构图
mybatis体系结构图
  • myBatis 应用知识结构图
myBatis应用知识结构图
  • config上下文配置

(1) 属性配置
<properties resource="app.properties">
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
</properties>
三种设置方式:
①构建sessionFactory 时传递 (优先级:高)
②基于resource 属性加载 或 url 加载 (优先级:中)
③基于 <propertite> 属性设置 (优先级:低)

(2) 全局参数设置
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
具体参考:http://www.mybatis.org/mybatis-3/zh/configuration.html#settings

(3) 环境配置
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED" >
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
事物管理器:JDBC|MANAGED

(4) 数据源
unpooled 普通连接,每次获取时都会重新建立一个新的连接.属性下如下:
• driver :数据库驱动类
• url: URL地址
• username:用户名。
• password :登录数据库的密码。
pooled: 连接池模式,所有连接从连接池当中获取,由连接池来来进行连接的建立与回收关于等操作,除支持unpooled属性外还支持属性如下:
• poolMaximumActiveConnections : 最大活跃数,默认值:10
• poolMaximumIdleConnections :最大空闲连接数
• poolMaximumCheckoutTime :获取连接超时等待最大(checked out)时间,默认值:20000 毫秒
• poolTimeToWait : 单次获取连接 最大等待时间 默认:20000 毫秒(即 20 秒)。
• poolMaximumLocalBadConnectionTolerance 获取连接重试次数 默认:3
• poolPingQuery 用于检测连接是否断开的测试 语句
• poolPingEnabled 是否通过执行poolPingQuery 语句做检测,默认值:false。
• poolPingConnectionsNotUsedFor 连接检测间隔时间 ,默认60000。

(5) typeAliases 别名配置
<typeAliases>
<typeAlias type="com.niuh.dao"/>
<typeAlias type="com.niuh.dao.UserInfo" alias="UserInfo"/>
</typeAliases>

(6) mappers 文件引入
<mappers>
<mapper resource="userInfo.xml" />
<package name="com.niuh.dao"/>
</mappers>
基于 mapper 引入指定资源文件: resource| url |class
基于package 引入:扫描指定包路径当下的url

  • mapper 映谢文件配置

(1) mapper 常用元素
select – 映射查询语
insert – 映射插入语句
update – 映射更新语句
sql – 可被其他语句引用的可重用语句块
delete – 映射删除语句
resultMap 用来描述如何从数据库结果集中来加载对象
cache – 给定命名空间的缓存配置
cache-ref – 其他命名空间缓存配置的引用

(2) <select > 查询标签
其表示一个查询语句映谢,其简单示例如下:
示例
<select id="selectUser" resultType="com.niuh.mybatis.test.UserInfo">
select * from user_info where id = #{id}
</select>
其支持属性如下:
<select
id="selectUser" // statement id
parameterType="int" // 参数类型
resultType="hashmap"// 返回结果类别
resultMap="personResultMap" // 返回结果映射
flushCache="false" //
useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED">
参数的引用的办法
#{id, mode=in, jdbcType=INT, jdbcTypeName=MY_TYPE}

(3) <insert> <update> <delete> 示例 标签
<insert id="addUser"
parameterType="com.niuh.mybatis.test.UuserInfo">
INSERT INTO user_info (user_name,nick_name,password) VALUES
(#{userName},#{nickName},#{password})
</insert>

<update id="updateUser"
parameterType="com.niuh.mybatis.test.UuserInfo" >
update user_info set user_name=#{userName} where id=#{id}
</update>

<delete id="deleteUser" parameterType="int">
DELETE from user_info where id=#{id}
</delete>

属性说明:
<insert
id="insertUuser"
parameterType="com.niuh.mybatis.test.UuserInfo"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">

<update
id="updateUuser"
parameterType="com.niuh.mybatis.test.UuserInfo"
flushCache="true"
statementType="PREPARED"
timeout="20">

<delete
id="deleteUuser"
parameterType="com.niuh.mybatis.test.UuserInfo"
flushCache="true"
statementType="PREPARED"
timeout="20">

(4) <sql> 标签
将重复的sql 语句定文为一个字段
<sql id="base_colume"> id,user_name,nick_name</sql>
可通过 <include > 进行引入 如:
<include refid="base_colume"/>

(5) <resultMap> 标签
resultMap 是myBatis 对象的映射

  • 动态SQL配置

<if> 标签
trim (where, set) 标签
foreach 标签

4、数据库访问层的4种实现方案对比

  • jdbc 执行时序图
  • JdbcTemplate 执行时序图
  • hibernate 执行流程
  • myBatis 执行流程
总结:
myBatis 的定位

myBatis 专注于sql 本身,其为sql 映谢而非完整的ORM,需要自己编写sql 语句,这是其优点也是缺点。优点是:优化方便,可更好利用sql编写经验。缺点是当数据修改之后调整麻烦耗费时间长.

试用场景:适用于对性能要求较高,有大批量的查询修改,并且业务实现没有过多依懒数据关系模型,比如:电商、O2O等互联网项目。

互联网项目对DAO层的要求:

1、对数据库的访问更新纯粹

2、尽可能不要使用数据库做运算

3、SQL语句可以针对性的优化(减少查询字段、查条件排序例 、查询条件尽可能命中索引)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容