`
ak478288
  • 浏览: 73432 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

分布式访问框架halo-dal设计思想及原理

阅读更多

 


halo-dal原帖 地址 http://www.iteye.com/topic/1123284


近期刚刚完成halo-dal的代码,一些iteye的朋友通过qq问我设计思路。由于在qq上写的语言组织不是很完整,特此开一帖,详细写一下halo-dal的一些心得与技巧,希望大家能从中获得灵感,或者能指出我设计的不足之处。


halo-dal的雏形在2009年中旬的时候就已经存在了,当时看了手机之家 许超前 设计的 dal 相关的ppt,那时对此很好奇,工作之余设计了 hkframe。这个是建立在jdbc基础之上的一个分布式访问框架以及一个快速开发的web框架,当时没有开源的原因在于自认为没有做到很好,不是我理想的代码。后来一直在我自己的项目上使用。没有再进行更新。


到2011年时,又由于工作需要,再次捡起以前的代码翻看了2天,决定重新设计hkframe,用了2个星期完成了halo 框架,使用全新的思想进行设计。为什么叫halo,由于当时在玩一个游戏 halo,非常喜欢,在玩完游戏之余,非常兴奋的状态下完成的代码,所以起名的时候就写了halo。halo中还是包括一个jdbc访问框架和web框架。当时的框架是一个分布式访问和轻量级orm的结合体,进行开发,效率非常高。由于使用了asm来解决使用反射的问题,所以性能也很不错。唯一缺憾的地方就是只能用jdbc来写,而且必须是我提供的api。


设计halo-dal的原因为公司开发需要,发现没有合适的解决方案,公司内部jdbc hibernate ibatis 都在使用,而且很多设计方案代码入侵性较强,耦合度高。搜索发现hibernate share 只解决了分表问题,无法解决分库问题。ibatis没有多加搜索。后来就有一个想法,能不能设计一种简单的框架能支持各种现有的数据库访问框架呢。由此出现了halo-dal的设计。主要利用五一假期时间完成了代码。



进入正题:::


halo-dal 分布式数据访问设计 


功能主要解决的问题是 :

如何能方便的选择 datasource 和真正的 tablename


顺便要做到:

尽量使用jdbc原有接口,做到最小化的代码入侵。(旨在能使用大家各自喜欢的hibernate ibatis mybatis 也能解决分布式访问问题)


那么所有设计的入口就只能在Connection以下。


为了简化第一个版本的开发,我只想支持PreparedStatement方式,不支持普通的Statement 以及批处理使用的BatchPreparedStatement


什么是我需要的信息?

我的关注点放到了sql上,因为根据jdbc使用经验来说,操作数据库离不开2个最主要的参数sql ,以及sql中赋值的参数 Object[] values。也就是说我只需要拦截到sql以及alues就可以进行分析。sql中包含最显而易见的一个信息,那就是tablename,那么datasource从哪里获得?没有别的东西,只能是靠sql 与values。


每个模块完全独立设计,只靠接口传递信息:

第一个要解决的问题就是解析sql与values获得我需要的信息,对于sql解析,我使用的就是最普通的字符串indexof substring这些api。解析后,我需要的信息就清楚了tablename、条件表达式、赋值表达式。 


以下解释用到的例子

sql: select * from user where level=?

Object[] values =new Object[]{1};


tablename是什么?

在此的table name 不是真正的表名称。而是一个逻辑表明称:我称他为logicTableName,这个逻辑表名。最终会把sql中的tablename 替换成真正的表名。


条件表达式、赋值表达式是什么:

level=? 真正的值是1 那么表达式 就是 level、=、1,组合就成为了SQLExpression。


分表分库的路由解析器:

分析完sql,那就该进行分表分库信息的获取了,这个信息的解析,就在PartitionParser中,在此类的方法中传入tablename 以及表达式等有效信息。


例如level,这个是对user表进行分区的条件,那么我们只需要对level以及他的值进行相关运算即可。这个时候就用到了SQLExpression的数据.

通过解析,最终会获得 dsKey(datasource对应的key) 和 真正的表名称 realTableName,返回的对象PartitionTableInfo包含了这些信息。


如何使用解析的结果?

上面的步骤完成了sql解析以及获得真正datasource key和真正的表名,那么接下来就是如何组织上面2段程序。

既然要解析sql,那么就要找到能获得sql的位置。在Connection中与sql有关的几个主要接口就是


public PreparedStatement prepareStatement(String sql) throws SQLException;
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
            throws SQLException;
......

 


因此,我只能通过自定义DALConnection implements Connection 来实现一个虚拟的Connection,这样就可以截取sql信息。


DALDataSource DALConnection DALPreparedStatement

DataSource.getConnection方法是获得链接的入口,为了获得DALConnection,我就需要自定义DALDataSource implements DataSource.所有真实的DataSource全部由DALDataSource来掌管,这些真实的DataSource全部都通过一个map来保存key为 dsKey(程序中会用到),value就是DataSource。


使用了DALDataSource DALConnection的好处就是能延迟开启真正的DataSource,这样才能保证先解析,再定位。例如,在使用spring 进行事务管理时,

假设 service.methodTX这个方法是需要开启事务,通常只有获得了Connection,才能setAutoCommit(false);,但是我们在这个步骤还没有获得sql,就无法进行解析,只有通过DALDataSource来获得一个DALConnection,这个DALConnection在此时是与任何真实的Connection无关的。因此并不会开启真正的Connection,以及真正的执行setAutoCommit(false);,所有对Connection进行的设置,都会通过DALConnection进行记录,直到获取真正的Connection时,才全部设置到真身。


通过DALConnection.prepareStatement,我们也无法获取真正的PreparedStatement,只有继续造假,创建了DALPreparedStatement.代码的重点就是DALPreparedStatement,因为通过PreparedSatement才可以设置sql需要的参数。DALPreparedStatement,会记录所有对本身的操作,直到获得了真正的PreparedStatement,才把记录的操作设置到真身。

在执行PreparedStatement.execute*()系列方法之前,我们都已经传递了sql,并进行参数赋值,那么我们就可以进行真正的分析了。通过调用prepare()方法就可以进行进行数据访问路由分析。



public boolean execute() throws SQLException {
        this.prepare();
        return ps.execute();
    }

 


prepare这个方法会调用上面讲述的sql分析器 访问路由器,获得dsKey 、realTableName接下来 再次通过sql解析器替换sql中对应的表名。dsKey会存储到一个ThreadLocal类型的对象中,通过DALConnection.getCurrentConnection就可以获得真正的Connection,并开启PreparedStatement,最终执行的execute就落到了指定的数据库上。


整个halo-dal的设计思想就是以上这些了,有不妥之处请大家指出。


希望大家能做出更好的框架供我参考。





分享到:
评论

相关推荐

    halo-dev-halo-master_java_

    【标题】"halo-dev-halo-master_java_" 指的是一个名为 "halo" 的开发项目,其主分支可能是 "master",并且是用 Java 语言编写的。这个项目可能是一个开发框架或者是一个管理系统的代码库,尤其适合用于构建基于 ...

    halo-dal:java 分布式数据库访问框架,可以结合任何使用PreparedStatement操作的框架。在java jdbc api层实现 分表分库 路由解析的 框架 可以单独或者与用hibernate ibatis spring-jdbc 等框架结合使用,屏蔽api层使用差异,能实现 jdbc 单数据库事务,目的是为了方便的进行分表分库程序的开发

    谢谢大家的关注#halo-dal使用说明#####使用场景:数据库分布式访问#####使用语言:java#####使用条件:支持PreparedStatement处理的任何jdbc框架,最好配合spring管理数据库连接池.#####sql语句必须使用小写字符#####jdk...

    PyPI 官网下载 | halo-app-0.10.33.tar.gz

    “halo-app”这个名字听起来像是一个应用程序框架,可能专为构建云原生(Cloud Native)分布式系统设计。云原生是一种开发和管理软件应用程序的方法,它强调利用微服务、容器、声明式API以及持续交付与部署,来促进...

    Python库 | halo-app-0.10.58.tar.gz

    《Python库Halo-app-0.10.58详解》 在信息技术的海洋中,Python作为一门强大的编程语言,以其简洁的语法和丰富的库支持,深受开发者的喜爱。今天我们要探讨的是Python的一个特定库——Halo-app,具体版本为0.10.58...

    halo-dev-halo-master_java_源码.zip

    通过分析`halo-dev-halo-master_java_源码.zip`中的源代码,我们可以深入了解这个系统的架构设计、功能实现以及Java编程的实践应用。 一、整体架构 Halo Dev Halo Master 的架构基于MVC(Model-View-Controller)...

    halo-1.4.2.jar

    halo-1.4.2.jar版本,防止halo官方突然被封

    halo-dev-halo-comment-normal-master_java_

    标题"halo-dev-halo-comment-normal-master_java_"可能指的是一个项目或教程,它旨在教用户如何在Katalon Recorder的基础上开发和定制自动化测试脚本,特别是针对Selenide框架。"master"通常代表这是项目的主要分支...

    halo-2[1].0游戏破解

    halo-2[1].0游戏破解 java pao jie but some cannot

    halo-comment-sakura:halo-theme-sakura主题的配套comment

    适用于 halo-theme-sakura 的评论组件。可能也适用于其他主题,但不确保完全适配。使用指南进入后台 -> 系统 -> 博客设置 -> 评论设置将 评论模块 JS 修改为:...

    halo-java-快速建网工具

    1、halo-java-快速建网工具 2、快速开始 docker run -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.13

    Python库 | halo-app-0.10.68.tar.gz

    标题中的“Python库 | halo-app-0.10.68.tar.gz”表明这是一个与Python相关的库,名为“halo-app”,版本号为0.10.68,且已经打包成tar.gz格式的压缩文件。这种格式是Linux和Unix系统中常用的归档和压缩方式,通常...

    halo-1.4.11.jar

    halo-1.4.11.jar

    halo-main.zip 强大易用的开源建站工具

    快速开始 docker run -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.15 以上仅作为体验使用,详细部署文档请...可访问 官方应用市场 或 awesome-halo 仓库 查看适用于 Halo 2.x 的主题和插件。

    halo-theme-xue-1.4.4.zip

    标题中的“halo-theme-xue-1.4.4.zip”表明这是一款名为“Halo Theme Xue”的主题软件的压缩包,版本号为1.4.4。这个主题可能是针对某个特定平台或应用程序设计的,例如网站、操作系统或者桌面环境。在IT领域,主题...

    Python库 | halo-0.0.7.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:halo-0.0.7.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    halo-1.3.2.jar

    halo-1.3.2.jar,本地查看halo博客系统,采用了应用与用户配置分离的模式。你仅仅只需要一条命令即可运行成功,同时也支持 Docker/Docker Compose 部署。完善的主题系统,支持在线安装和更新。开发主题也十分方便,...

    halo-theme-vno

    复制 https://github.com/halo-dev/halo-theme-vno。 进入后台 -> 外观 -> 主题。 点击右下方按钮选择安装主题,随后选择 远程拉取。 粘贴复制的链接到远程地址,点击下载即可。 更新方法 方法一 进入后台 -> 外观 -...

    88287106#halo-doc#附: 框架内置的REST服务清单1

    附1:框架内置的REST服务清单缓存管理服务缓存刷新操作地址:http://XXXX:XX/services/rest/cache/refresh?响应报文:B

    halo-theme-sakura:Halo 版本的樱花:cherry_blossom:主题

    Sakura | | | :face_with_monocle: 说明 该主题的基础版为 ,非常感谢将基础版主题移植过来,给了我后续补充内容的条件。 本主题参照 WordPress 主题 制作,在原有的 主题上添加了 Sakura 的内容,并优化了部分内容...

    halo-theme-xue.zip

    【标题】"halo-theme-xue.zip" 是一个与博客相关的主题文件,它采用的是“雪”这一设计概念,旨在为用户提供清新、简洁且具有冬日雪景般美感的界面体验。这个压缩包包含了构建一个博客网站所需的基本模板和配置文件...

Global site tag (gtag.js) - Google Analytics