我的ORM之十-- MyOql实现原理
ORM的功能
两个基本功能
- 翻译:对象查询转化为SQL
- 映射:把查询结果转化为实体
更多功能
如果仅仅实现这两个功能,那这两个是可以独立的,实现起来也就很简单了。但MyOql的目标还有以下部分:
- 缓存:通过配置文件,在运行时配置缓存。数据变更后(包含存储过程执行后的数据变更),自动破坏缓存对象。
- 分库:把某些表指向其它的数据库
- 分表:按一定规则,把数据拆到不同的表。这些不同的表也可以部署在不同的服务器上。MyOql叫变表。
- 权限:在用户查询时,根据用户角色,可以对表数据进行验证。
- 对表进行分组。目前只是一级分组,不能多级分组。
- 对列枚举化。
- 使MyOql读起来像SQL。
- 最大程度贴近SQL的最大实现范围。可以执行存储过程、表值函数、标量函数、系统函数、Case When、With As、分页、聚合函数。
对ORM的要求
要实现这些功能,MyOql需要做到:
- 识别用户操作:是对哪个表进行了哪些操作。不能漏。
- 执行前事件:在对象转化为SQL之前,先对操作事件进行验证控制。
- 执行后事件:如果数据是变更,去破坏缓存对象。
- 取连接事件:控制分库。
- 取表名事件:控制分表。
因为要控制用户操作,所以在MyOql的系统中,不能使用SQL!这是MyOql 和其它ORM的区别!所以MyOql设计的很灵活,可以实现任何操作(实在特殊的存储过程接着)
MyOql实现的对象翻译Sql机制
MyOql定义了以下几个动作,在这些动作中,保存着各种数据:
- Select
- Update
- Insert
- Delete
- BatchInsert
- BatchUpdate
- Proc
在翻译的时候,只要识别这些子句就OK了。其它一些很灵活的数据,我为了方便,并没有专门定义属性,而是放到了 Dna 属性里。 在翻译的时候,去Dna里查找就OK了。
如:
Select是最复杂的动作,Select动作的Dna里就包含了: 显示列,Where子句,Join子句,OrderBy子句,GroupBy子句,having子句。
Update动作的Dna里包含了: 更新实体,Where条件,关联表(多表更新)
Insert动作的Dna里包含了:插入实体,Select子句(可以执行 Insert table(列) select (列) from table2)。
Delete是最简单的动作,仅包含一个Where就可以。
这样的机制是尽量的遵循SQL的写法,而没有对写法进行强制约束,比如,你可以这样写:
dbr.Menu.Select().Where(dbr.PUser.Id > ).ToScalar();
它也可以编译成功,生成的SQL是:
select * from Menu where User.Id > 1
Lambda的支持是为了尽量的约束以上不规范的地方:
dbr.Menu.Select().Where(o => o.Id > ).ToScalar();
此时Where的参数是 Func<MenuRule,WhereClip> , o 就表示 Menu 表,程序员在写的时候,就不会写到User表里了。
基于以上动作,MyOql可以识别程序对哪些表进行了何种操作。就可以对各个时机进行控制了。
映射
这个没什么好说的,哪个快用哪个。目前使用的是 FastReflectionLib,基于Emit。总之比反射快。
缓存
缓存一直是MyOql的重点,优其是缓存破坏!
缓存数据并不困难,在数据发生变更时,破坏关联的缓存数据才是最最重要的。
MyOql在生成实体时,会从存储过程中分析出该存储过程用到了哪些表,调用了哪些存储过程(递归找出使用的表),建立 存储过程对表的依赖(哪位同学有更好的算法,请指教。我目前是用正则从源码中找的,可能不准),在执行存储过程时,把该存储过程的依赖表的关联缓存项清掉。
理论上可以对简单视图进行写操作,但是为了规范化,视图主要是用来查询的,我在视图的接口上禁用了写操作。
按ID查询流程
- dbo.Event.OnReading
- MyOqlCacheManager.GetFromCacheById
- ToCommand
- dbo.SetLastQueryedResult
- MyOqlCacheManager.SetCache
- dbo.Event.OnReaded
按SQL查询流程
- dbo.Event.OnReading
- 如果页数太靠后,则把排序倒置,把页数倒排。如果是第一页并有Take数,则进行总数查询。
- ToCommand
- MyOqlCacheManager.GetFromCacheBySql
- dbo.SetLastQueryedResult
- MyOqlCacheManager.SetCache
- dbo.Event.OnReaded
MyOqlCacheManager.GetFromCacheByXXX
取缓存时,可能会从远程服务器读取,为了进行优化,实现以下流程:
本地保存远程服务器的缓存Key,如果本地保存着远程的缓存Key,则进行查询,如果远程查不到,则删除本地缓存Key项。
变表
如果数据库表定义了大括号,MyOql会认为它是变表。 如: T_Fees_{CorpID},它是变表模板,在生成表名的时候,我会用 CorpID 这个变量,来替换=》 T_Fees_{1} , T_Fees_{2} 表示1号公司的收费表,2号公司的收费表,我们称它为分表。
变表需要在某个时机,根据变表模板生成分表。 如创建新公司信息的时候,就把该公司的收费表创建好。
在理解了以上部分之后,参考示例,其它的也就很好理解了。
我的ORM之十-- MyOql实现原理的更多相关文章
- Linux学习之CentOS(二十八)--RAID原理基础及Linux下软件RAID配置
一.RAID的原理基础 在 讲解RAID的原理基础之前,我们首先来了解一下传统磁盘的劣势.我们知道一台PC机种都会包含CPU.内存.主板.硬盘.网卡等硬件,影响计算机性能的 组建包括:CPU.主板总线 ...
- java web学习总结(十四) -------------------JSP原理
一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...
- 我的ORM之十二 -- 支持的数据库及差别
我的ORM索引 支持最好的是SqlServer2005,Sqlserver2008,SqlServer2012 ,后续将支持:MySql,Sqlite,Oracle. 1.分页差别 MsSql 200 ...
- selenium-webdriver(python) (十四) -- webdriver原理
之前看乙醇视频中提到,selenium 的ruby 实现有一个小后门,在代码中加上$DEBUG=1 ,再运行脚本的过程中,就可以看到客户端请求的信息与服务器端返回的数据:觉得这个功能很强大,可以帮助理 ...
- JavaWeb---总结(十四)JSP原理
一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...
- javaweb学习总结(十四)——JSP原理
一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- javaweb(十四)——JSP原理
一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...
- selenium-webdriver(python) (十四) -- webdriver原理(转)
之前看乙醇视频中提到,selenium 的ruby 实现有一个小后门,在代码中加上$DEBUG=1 ,再运行脚本的过程中,就可以看到客户端请求的信息与服务器端返回的数据:觉得这个功能很强大,可以帮助理 ...
随机推荐
- 【笔记】android sdk集成的eclipse中导入项目
android sdk集成的eclipse中导入项目 想要把旧的ADT项目,一模一样的导入进来,需要: 1.把项目放到,非当前ADT的workspace目录下: 2.从Project中Import,选 ...
- 2、C语言关键字-auto register static
文件限定符的作用: 1.auto : 局部变量,修饰的变量在栈中定义.动态内存,随着函数的结束,变量占用的内存空间也随之释放. 2.register : 寄存器变量,请求编译器将此变量存于cpu寄存器 ...
- factory service provide自定义服务
1.factory factory , 就是你提供一个方法, 该方法返回一个对象的实例, 对于 AngularJS 的 factory 来说, 就是先定义一个对象, 给这个对象添加属性和方法, 然后返 ...
- 第二章 jQuery数组和字符串
章节内容: 1.利用数组在列表中显示名字 (1)利用数组显示名字列表--join()方法 (2)从数组中获取名字并追加到有序列表--each()方法 (3)利用HTML元素创建数组和计算数组长度--g ...
- net软件自动生成开发编程框架编程机器人
有一个.net自动生成平台(编程机器人)推荐给大家,常规几天十几天的工作,机器人几分钟搞定,不写一行代码,留下大把休闲时光,适应于聪明人:不想太累的程序员(看看风景泡泡妞),不想多请人的老板(有限资金 ...
- 海量数据相似度计算之simhash和海明距离
通过 采集系统 我们采集了大量文本数据,但是文本中有很多重复数据影响我们对于结果的分析.分析前我们需要对这些数据去除重复,如何选择和设计文本的去重算法?常见的有余弦夹角算法.欧式距离.Jaccard相 ...
- iptables示例
[root@iZ23um2lv3tZ ~]# more /etc/sysconfig/iptables # Generated by iptables-save v1. :: *filter :INP ...
- Extjs 表单验证后,几种错误信息展示方式
今天要求对form表单验证,进行系统学习一下,故做了几个示例: Ext.onReady(function(){ var panel=Ext.create('Ext.form.Panel' ...
- [转]SQL Server字符串处理函数大全
select语句中只能使用sql函数对字段进行操作(链接sql server), select 字段1 from 表1 where 字段1.IndexOf("云")=1;这条语句不 ...
- 【转】linux yum命令详解
yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RP ...