@@ -51,8 +51,19 @@ mybatis整体架构分为三层,分别是基础支持层、核心处理层和
51
51
52
52
****
53
53
# 开个头
54
- 参考项目代码~~~
55
- [ 详细书签版-MyBatis技术内幕] ( https://pan.baidu.com/s/1-JGtoXADDjQRw5v51np4vA " 提取码是fcak ")
54
+ 参考项目代码~~~
55
+ ## 基本结构:
56
+
57
+ 全局配置文件 mybatis-config.xml
58
+ 映射配置文件 UserMapper.xml
59
+ 方法接口 UserMapper
60
+ 结果集/实体 UserEntiry
61
+
62
+ ## 几个问题:
63
+ 1 . 读写配置文件,如何封装,提取配置的SQL语句 Configuration MapperProxy MappedStatement
64
+ 2 . 接口在哪里实现,怎么实现,SQL如何执行 SqlSession Executor TypeHandler
65
+ 3 . 结果集映射返回期望的Java类型 ResultSetHandler
66
+ 4 . 对扩展开放 plugins
56
67
57
68
# XML基础知识(名称空间/文档验证/文档处理)
58
69
@@ -299,8 +310,7 @@ Class (java.lang)
299
310
300
311
# 从头开始
301
312
mybatis入口: SqlSessionFactoryBuilder读取xml文档,解析并构造Configuration,根据Configuration构造sqlSessionFactory
302
- sqlSessionFactory可以很轻易的拿到sqlSession,sqlSession提供系列操作方法,
303
- sqlSession Javadoc:Through this interface you can execute commands, get mappers and manage transactions.。
313
+ sqlSessionFactory可以很轻易的拿到sqlSession,sqlSession提供系列操作方法,
304
314
## mybatis初始化流程
305
315
mybatis初始化之后Configuration、sqlSessionFactory均已构造完成。
306
316
@@ -319,10 +329,77 @@ MapperProxyFactory仅仅只是代理方法,由于接口不提供实现,所
319
329
`final MapperMethod mapperMethod = cachedMapperMethod(method);
320
330
return mapperMethod.execute(sqlSession, args); `
321
331
322
- 具体实现在SqlSession中,SqlSession用到了缓存的MappedStatement执行真实的sql字符串;这是接口和实现分离思想的体现。
323
- 同时这里用到了命令模式。
332
+ 具体实现在SqlSession中,SqlSession用到了缓存的MappedStatement执行真实的sql字符串;这是接口和实现分离思想的体现。
333
+ 同时这里用到了命令模式。
334
+ sqlSession javadoc:Through this interface you can execute commands, get mappers and manage transactions.。
335
+ SqlSession接口对JDBC封装通过Executor接口实现,SqlSession类型负责提供高层对外访问接口。
336
+ ### Executor
337
+ Executor Class Diagram:
338
+ ![ Executor Class Diagram] ( ./Executor.png " Executor Class Diagram ")
339
+
340
+ #### BaseExecutor
341
+ BaseExecutor的基本实现提供内置的一级缓存管理和事务管理:
342
+ ##### 一级缓存
343
+ 缓存由Cache接口定义,一级缓存是SqlSession内部缓存,Executor中localCache,localOutputParameterCache表示一级缓存:
344
+ ``` java
345
+ /**
346
+ * 为每个namespace提供缓存一个实例
347
+ * 缓存实现必须提供字符串(被定义为缓存id属性,提供getter)作为构造参数
348
+ */
349
+ public interface Cache {
350
+ String getId ();
351
+ void putObject (Object key /* {@link CacheKey}*/ , Object value );
352
+ Object getObject (Object key );
353
+ Object removeObject (Object key );
354
+ void clear ();
355
+ int getSize ();
356
+ default ReadWriteLock getReadWriteLock () {
357
+ return null ;
358
+ }
359
+ }
360
+ ```
361
+ mybatis提供很多Cache实现,PerpetualCache提供基本实现,Cache装饰器类在org.apache.ibatis.cache.decorators包下面。
362
+ ![ cache-module] ( ./cache-module.png " cache-module ")
363
+ 如何设计CacheKey,提供全局唯一的key:从上往下找config->mapper->statement(sql, args)
364
+ 在Executor.createCacheKey中还用到了RowBounds(实现通用分页,个人感觉方法设计冗余,提供插件?)的相关属性offset,limit
365
+ 对于嵌套查询,BaseExecutor实现提供一个延迟加载队列,在query()方法执行时,会查询该队列并加载命中的缓存。
366
+ (参考源码,mybatis 3.5.3在这里有几个issue):
367
+ mybatis issues列表: https://github.com/mybatis/mybatis-3/issues
368
+
369
+ 例如 #482 https://github.com/mybatis/mybatis-3/issues/482
370
+ 这个问题是一个字符编码问题,描述以前的NStringHandler不支持国家字符集类型数据~~~
371
+ Java String字符串类型与JdbcType转换
372
+ NVARCHAR(Types.NVARCHAR), // JDK6
373
+ NCHAR(Types.NCHAR), // JDK6
374
+ NCLOB(Types.NCLOB), // JDK6
375
+ 具体转换的类型会根据参数字符串长度和驱动定义的NVARCHAR值来确定
376
+ TypeHandler完成单个参数/列值的类型转换
377
+ NStringTypeHandler会在TypeHandlerRegistry中注册,这是已经修复问题了吧,注释没删掉吗???
378
+ FAQ. 自行查阅关于char varchar NCHAR NVARCHAR 区别
379
+ ``` java
380
+ if (queryStack == 0 ) {
381
+ for (DeferredLoad deferredLoad : deferredLoads) {
382
+ deferredLoad. load();
383
+ }
384
+ // issue #601
385
+ deferredLoads. clear();
386
+ if (configuration. getLocalCacheScope() == LocalCacheScope . STATEMENT ) {
387
+ // issue #482
388
+ clearLocalCache();
389
+ }
390
+ }
391
+ ```
392
+ 这里不再详述,读者可以结合JDBC自身情况来设计一个查询缓存,Cache接口已为你定义好了...
393
+
394
+ ##### 事务管理
395
+ Mybatis定义Transaction事务操作接口,它有两个实现JdbcTranscation、ManagedTransaction;
396
+
397
+ #### sql操作具体实现
398
+
399
+ #### CachingExecutor 二级缓存
324
400
325
-
401
+ 二级缓存是事务级别缓存,是一个全局缓存,被所有SqlSession(ref -> sqlSession javadoc)共享。
402
+ CachingExecutor通过装饰模式组合Executor添加新功能,提供二级缓存功能。当然Cache的线程安全由自身保证。
326
403
327
404
328
405
@@ -343,7 +420,7 @@ MapperProxyFactory仅仅只是代理方法,由于接口不提供实现,所
343
420
> - [x] [ XML揭秘 入门·应用·精通 Michael Morrison 陆新年] ( https://pan.baidu.com/s/1M3HSfL3VQgpVvHa_ekUjvQ " 提取码是9mfm ")
344
421
> - [x] [ 《XML简明教程》2009年清华大学出版社出版 张欣毅]
345
422
> - [x] [ Java与XML] ( https://www.baidu.com " java访问xml ")
346
- > - [x] [ Java编程思想] ( https://pan.baidu.com/s/1Tz4rpgEwFg6Rcq9UqWTNOw " m912 ")
423
+ > - [x] [ Java编程思想 第四版 ] ( https://pan.baidu.com/s/1Tz4rpgEwFg6Rcq9UqWTNOw " m912 ")
347
424
> - [x] [ Java核心技术I/II卷] ( https://pan.baidu.com/s/1Tz4rpgEwFg6Rcq9UqWTNOw " m912 ")
348
425
> - [x] [ C++程序设计教程(第二版) 钱能]
349
426
> - [x] [ 深入理解Java虚拟机 JVM高级特性与最佳实践 第2版] ( https://pan.baidu.com/s/17mGl_Xu-dgWITfoD8V90HA " 3tv9 ")
0 commit comments