博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从零开始实现一个简单的 ibatis SQL 热部署
阅读量:5938 次
发布时间:2019-06-19

本文共 2556 字,大约阅读时间需要 8 分钟。

在 ibatis 配置文件修改后生效这个问题上,小朋友我尝试了很多不科学和科学的方式,通过单元测试 or 各种插件。

单元测试这一方式我比较推荐,不需花费额外的很多时间,可靠和简单。

至于后者呢,前有JRebel、HotCode,后有HotCode2,各种折腾。你要问我为什么不换成 MyBatis,我也不知道。

所以小朋友我决定自己做一个,或者说是尝试,哈哈。

空想

我们在调用 ibatis 的时候,它在背后是如何工作的?

例如最常见的一个 delete 操作:

(List<DogeDO>) sqlMapClientTemplate.delete(NAMESPACE + “delete", dogeQuery)

在developworks上找到了这样一张时序图 [1]

clipboard.png

显然,在 SqlMapExecutorDelegate 14 号环节,ibatis 从 MappedStatement 中获得 DeleteStatement,这里的 Statement,可以粗鄙的视作真实的 SQL语句,即

delete * from database;

MappedStatement 是如何初始化的?

clipboard.png

学习参考文件[2],了解到经过一系列的解析之后,通过如下过程

addStatementNodelets {     statementParser.parseGeneralStatement {          newMappedStatementConfig {               delegate.addMappedStatement(mappedStatement)          }     }}

添加到 mappedStatements 时,进行了键值的重复判断

delegate.addMappedStatement(mappedStatement) {     if (mappedStatements.containsKey(ms.getId())) {      throw new SqlMapException("There is already a statement named " + ms.getId() + " in this SqlMap.");    }}

如果想在 SQL XML 更改之后重新解析并写入到 mappedStatements,要把这个重复判断干掉,需要通过以下的这些空想步骤。

  • 重写 addMappedStatement

  • 就需要能介入 delegate

  • 就需要能介入 delegate 初始化的地方,即介入 SqlMapClientImpl

  • 就需要能介入 SqlMapClientImpl 初始化的地方,即介入 SqlMapClientFactoryBean

Google和Stackoverflow一通后,发现可以通过重写 delegate 等类的方式解决上述问题的,[3]是一个完整的实现,大神啊。

已有的方案

先正向的看看别人做了什么,可以用来抄袭

DySqlMapClientFactoryBean

在 SqlMapClientFactoryBean 的基础上进行了如下扩展:

  • 初始化时将 configLocation、configLocations 保存下来,有何用?

  • 重写了 buildSqlMapClient 方法,返回重写后的 DySqlMapClient

DySqlMapClient

对 SqlMapClientImpl 进行了如下扩展:

  • 将超类初始化为 重写后的 DySqlMapExecutorDelegate

  • 自行解析 configLocation || configLocations 对应的配置文件,生成 SQL.XML -> SQL_ID 映射关系

DySqlMapExecutorDelegate

对 SqlMapExecutorDelegate 进行了如下扩展:

  • addMappedStatement,ID值重复时 remove 掉

  • 增加了 checkAndRefreshSqlMap 方法,用来检查和刷新 Map

  • 重写各操作实现接口,增加 checkAndRefreshSqlMap 调用

DySqlMapParser

对 SqlMapParser 进行了如下扩展:

  • 增加 resetSqlNodeLets,对 XmlParserState 进行重置。可能会引起 State 混乱

SqlMapConfigUtils

  • readSqlMapFileMapping,解析包含的 SQL XML 文件列表

  • readSqlMap,解析每个 SQL XML 中的 SQL ID

改进的方案

对[3]进行了测试,发现了一个比较重大的不同。我们的工程将 SQL XML 打包成了 jar,并且,即便是现成的文件 ,流程也变成了修改部署 war 包中的 XML 文件,而不是修改源文件,然后直接生效。所以现在面临了两个问题。

  • 如何解决 jar 带来的文件操作

  • SqlMapFile 直接与源文件关联

编不下去了

周末撩妹时思考了一下之前遇到的两个问题

clipboard.png

晚间溜达的时候想到的一出,回家实现勉强能用。

中心思想是搭个HTTP服务,将源文件doge.xml资源化为,iBatis刷新时通过文件名构造URL,读取HTTP资源并进行解析。

clipboard.png

改造了一个http server

./http-server /src/main/resources/storage/sqlmap -p 59999 -j true

其实你也可以用

python -m SimpleHTTPServer 59999

弊端就是每次打开不同的工程得自己切到目录下敲命令启动服务器

事实上,如果你用 Intellij,默认配置下它会在 63342 端口下启动一个静态服务器

路径在

http://localhost:63342/your-project-home-/very-long-module-path/doge.xml

打完收工

[1] 深入分析 iBATIS 框架之系统架构与映射原理,

[2] ibatis源码学习(二)初始化和配置文件解析,

[3]

转载地址:http://enttx.baihongyu.com/

你可能感兴趣的文章
有序的双链表
查看>>
程序员全国不同地区,微信(面试 招聘)群。
查看>>
【干货】界面控件DevExtreme视频教程大汇总!
查看>>
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
linux 笔记本的温度提示
查看>>
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>