相关文章内容索引:

ORM查询语言(OQL)简介--概念篇
ORM查询语言(OQL)简介--实例篇
ORM查询语言(OQL)简介--高级篇:脱胎换骨
ORM查询语言(OQL)简介--高级篇(续):庐山真貌

一、SQL与ORM

  关系数据库(RDBMS)的查询有SQL(Structured Query Language)结构化查询语言,相比高级程序语言(命令式语言)而言,SQL主要描述想要做什么,而不是命令式语言的具体如何做,因此,SQL也被称为第四代语言(4GL),它为现代大多数的关系数据库系统所支持。SQL的核心是对“关系”的操作,数据库理论研究证明,SQL是关系上完备的,但是当代大多数高级语言都是面向对象的,高级语言程序要跟关系数据库进行交互,SQL就成了必须的桥梁,由于SQL基于的“关系”和程序语言的“对象”是不同的体系,它们之间要完成很好的交互,就得有一个“映射”过程,实现这个过程的程序,就是ORM(Object/Relation Mapping)。

  应用程序调用ORM的方法,ORM自动生成相应的SQL语句到数据库进行查询,然后ORM将接收到的关系数据映射成实体对象。如果没有使用ORM,那么通常应用程序会拆分出一个数据访问层(DAL)来生成SQL语句并执行相应的查询。所以,ORM出现后,在一定程度上,它可以取代DAL,这使得你少了一个层的工作量,对于提高工作效率是很重要的。

  下图是应用程序使用ORM和使用传统的DAL的一个示意图。

(图1:两种数据访问架构)

二、ORM带来的问题

  使用ORM后,再也不用去写那些枯燥的DAL代码了,不用拼接那些可能存在安全问题或者敲错字段名的SQL语句,但是我们发现,仅仅使用ORM它反而丧失了SQL的灵活性,这也是不少人拒绝使用ORM的理由。我们看看很多人的ORM是怎么定义数据操作接口的,他们常常把这些接口方法由实体类去实现,从而制造一个个充血的实体类:

public interface IEntity<T> where T:class
{
void Add();
void Update();
void Delete();
List<T> GetAll();
T GetOne(int id);
}

  使用充血实体类,在使用上还是比较方便的,但是Insert \Update\Delete 都只能操作一条数据,GetAll 方法不仅仅把全部数据拿出来了,而且还可能把不需要的字段值也拿了出来,那个GetOne方法,也许实际上表的主键并不是int 类型的,那么这些定义就会有问题。。。

  所以,我们见到很多使用了ORM的项目,不管数据是否全部需要,先拿出来再说,不管主键是不是int 类型,先定一个方法在那里,大不了是个空方法,不管当前实体是否需要Delete功能(比如某些系统用户数据是不能删除的),都基类给直接实现了。。。。。。

三、ORM查询语言

1,分离关注点

  那么,这些问题ORM能够解决吗?ORM本来是完成“对象-关系映射”的,但这里大多数的ORM都包含了“生成SQL”的功能,而要实现SQL那样的灵活性,那么我们必须分离出ORM这个关注点,将“生成SQL”的功能从ORM中抽取出来,这样我们就能够有更多的精力致力于发明一个面向对象的,用于ORM查询的语言,(ORM Query Language) ,这就是OQL。

  ORM查询语言,其实早就有了,从早期的Hibernate的HQL,到MS的Linq(Linq2SQL,EF其实内部都是使用Linq生成的SQL),它们都可以生成复杂的SQL语句,它们都是直接作用于ORM框架的。几乎在与Linq同一时期,PDF.NET也发明了自己的ORM查询语言,称为OQL。下面提到的OQL,都是指的PDF的OQL。

2,PDF.NET的ORM框架

  PDF.NET的ORM框架包括4个部分:

  1. Entity Object :PDF.NET实体类,它继承于基类 EntityBase,使得每一个实体类都成为一个“数据容器”;
  2. OQL:ORM查询语言,以实体类对象为操作对象,生成查询表达式,供实体查询对象使用。
  3. AdoHelper:数据访问提供程序抽象类,封装了对ADO.NET的各种访问,包括事物操作;框架默认提供了OledbProvider、OdbcProvider、AccessProvider、SqlServerProvider、OracleProvider等,要支持更多的数据库,只需要继承AdoHelper即可。
  4. EntityQuery<T> :实体查询对象,它是一个O/R Mapping对象,它操作涉及的对象类型是一个实体类(类型T);在对象内部,它会把OQL转换成SQL,然后调用AdoHelper完成查询。

(图2:PDF.NET OQL 架构)

  如果仅从查询调用端来观察,我们发现OQL,跟SQL逻辑上是等价的,一个是“对象化”的查询,一个是“结构化”的查询:

对象化查询:OQL->ORM-> Entity Objects

等于

结构化查询:SQL ->DB-> DataSet

  如果最终效果Entity Object==DataSet,那么OQL==SQL。

  所以,OQL的设计目标,就是要它生成的SQL语句效果基本达到手写的SQL语句一样。由于SQL的具体实现又有很多不同的版本,所以很多时候SqlServer用的SQL语句在Oracle 上不一定能够使用,只有那些完全标准的SQL语句才是通用的,因此,OQL的设计,也必须是这样标准的SQL规范,目前,实现的是SQL92标准规范。

3,OQL查询范式

  下面是OQL支持的查询范式举例,注意下面的定义里面使用了“BNF”范式,为了避免大家误会,这里补充下BFN的内容,详细内容请参考这个链接:http://baike.baidu.com/view/1137652.htm

巴科斯范式的内容

  在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。

  在双引号外的字(有可能有下划线)代表着语法部分。

  尖括号( < > )内包含的为必选项。

  方括号( [ ] )内包含的为可选项。

  大括号( { } )内包含的为可重复0至无数次的项。

  竖线( | )表示在其左右两边任选一项,相当于"OR"的意思。

  ::= 是“被定义为”的意思。

1,数据查询:

OQL q=OQL.From(entityObject)

[.[InnerJoin|LeftJoin|RightJoin](entityObject2).On(entityObject.PK,entityObject2.FK)]

[.[InnerJoin|LeftJoin|RightJoin](entityObject3).On(entityObject.PK,entityObject3.FK)]

.Select([entityObjectX.Property1][,entityObjectX.Property2][{,…}])

.Where([<entityObject.Property1>[,entityObject.Property2][,…]]|[OQL2]|[OQLCompare])

.GroupBy(entityObjectX.PropertyN,<"asc">|<"desc">)

.HavingBy(entityObjectX.PropertyM)

.End;

 如果需要分页,仅需要这样操作:

q.Limit(分页大小[,页码[,总记录数]]);

 执行该方法,会生成特定数据库平台的分页SQL语句。

2,数据统计:

OQL q=OQL.From(entityObject)

.Select().Count(entityObject.PropertyX,<””>|<"CountAsName">)

.Where([<entityObject.Property1>[,entityObject.Property2][,…]]|[OQL2]|[OQLCompare])

.End;

3,数据更新:

OQL q=OQL.From(entityObject)

.Update([entityObject.Property1][,entityObject.Property2][{,…}])

.Where([<entityObject.Property1>[,entityObject.Property2][,…]]|[OQL2]|[OQLCompare])

.End;

4,数据删除:

OQL q=OQL.From(entityObject)

.Delete()

.Where([<entityObject.Property1>[,entityObject.Property2][,…]]|[OQL2]|[OQLCompare])

.End;

下篇我们将使用实例来讲解OQL的具体使用,敬请期待。

注:PDF.NET现在已经开源,有关框架的详细信息,请看官网介绍:http://www.pwmis.com/sqlmap

开源信息介绍:

节前送礼:PDF.NET(PWMIS数据开发框架)V4.5版开源
---------------------分界线-----------------------------------------
文章发布后,热心网友 对我提了一些意见,由于不涉及个人隐私,这里贴上他的原文,如果他看到有异议的话请及时跟我联系。在此感谢他提出的下列意见!
另外大家觉得好请点个推荐,反对的话请留个理由,谢谢。
---------------------分界线-----------------------------------------

shawn(630235793) 1:10:46
大体浏览了一下,感觉还不错

shawn(630235793) 1:14:32
只是博文过于技术细节化而缺少了框架解决的具体问题域、面向的使用者类型,以及整体架构思想与基于关系数据访问框架的差异性描述,让读者一上来很难理解ORM框架的意图。

回复:

这些问题的确没有表述清楚,也是因为我的撰文水平有限,没有想到这些问题,也不知道该怎样来表述。

PDF.NET的OQL要解决的主要问题就是让ORM操作能够有SQL那样的灵活性,现有大多数ORM框架都是基于CRUD方法级别的操作,还没有像SQL那样具有语言级别的操作,要不然它怎么会被称为4GL呢?现在,我觉得LINQ也具有了这样的能力,而我框架中的OQL,也有这样的能力,所以我大胆的称呼它是一个“ORM Query Laguage”,就像SQL是提供给RDBMS的查询引擎使用一样,OQL是提供给ORM使用的。

所以,OQL面向的使用者是那些喜欢ORM方式来访问数据库,又喜欢SQL的灵活性的技术人员,或者是提供给喜欢其中一种(ORM或者SQL)而不太喜欢另外一种方式的人,让他们有机会体会到另一种方式的优势。

整体思想就是,用面向对象的方式来操作数据库,用OO的方式来写SQL!

PS:OQL与LINQ相比,它更接近于SQL风格,用惯了SQL的人,第一次接触LINQ是很不习惯的,至少我是如此。

shawn(630235793) 2012-10-6 1:39:15
数据访问框架设计的初始设想,首先应该是满足调用层的使用要求,换句话说请求是事务性的,还是非事务性的。如果用户的请求是事务性的,在访问层应该提供事务性的处理机制。而不是应用层自己来对是否事务性进行处理。这些应该放在访问层的对外交互接口处提供给用户来选择比较合理。
所以,框架内部的分层,我感觉还应该再多考虑一下比较好。

回复:

实体层的接口是有的,只是这个图里面不好放置而且不是重点,省略了。
是否使用事物,是放在访问层的对外交互接口处提供给用户来选择的。

shawn(630235793) 2012-10-6 1:47:13
毕竟数据访问框架对于用户来讲就应该屏蔽所有数据库之间操作的差异性,所有与数据库相关的一切操作都封装于内部。对于用户来讲这些都是完全不必去考虑的,只需要提出具体请求是什么就可以了。对于如何解读用户请求、如何根据用户选择的具体数据库,而将请求翻译成底层数据库操作指令等等,这些都是访问层内部机制完成的。

回复:

正如你所说,框架正是这样去做的,OQL屏蔽了SQL不同数据库之间的差异,它会根据具体使用的数据库,去生成本地化的SQL。

广州-海華²º¹²<harvey.cai@qq.com>  17:04:10
跟 linq 有什么相似/区别?
广州-海華²º¹²<harvey.cai@qq.com>  17:05:45
这篇博文里主推的理念,让人想到 linq。

pdf.net 主推的应该是:linq 般好用,但是性能卓越

回复:

LINQ是.NET独有的特性,“语言集成查询”,它是集成在.NET语言中的,这是它的先天优势。LINQ基于表达式树,所以它要求必须是.NET平台而且框架版本要求在.NET3.5及以上。

PDF.NET的OQL跟LINQ一样都是ORM框架使用的语言,但是OQL语法更接近于SQL,很容易上手,而且,OQL没有使用.NET的高级特性,这使得它只要是面向对象的语言而且支持泛型即可实现,因此将它移植到C++、Java是完全可能的,而且在.NET平台上,它也仅需.NET2.0版本的支持。

转载于:https://www.cnblogs.com/bluedoctor/archive/2012/10/06/2712699.html

ORM查询语言(OQL)简介--概念篇相关推荐

  1. 车联网大数据框架_大数据基础:ORM框架入门简介

    作为大数据开发技术者,需要掌握扎实的Java基础,这是不争的事实,所以对于Java开发当中需要掌握的重要框架技术,也需要有相应程度的掌握,比如说ORM框架.今天的大数据基础分享,我们就来具体讲一讲OR ...

  2. Linux负载均衡软件LVS(概念篇)

    Linux负载均衡软件lvs(概念篇) 一.LVS简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器,是一个由章文嵩博士发起的自由软件项目,它的官方站点是(www ...

  3. 【软件测试】基础-概念篇

    软件测试基础-概念篇 记录 - 慕课网 imooc 软件测试基础-概念篇 简介:系统介绍什么是软件测试,从软件测试的定义.原则以及测试阶段.测试模式.测试手段和测试类型分别详细说明软件测试中的各种测试 ...

  4. mysql 二级什么意思_MySQL二级等级考试归纳——概念篇

    准备考计算机二级了,归纳以复习,归纳下也方便自己以后看~也希望能对其他看这篇东东的人有帮助啦~ 打字快但是又渣,可能会有打错 按书本的章节归纳一遍,好像内容好多,分开概念篇和指令篇吧,以后会一边复习过 ...

  5. android 电容屏(二):驱动调试之基本概念篇

    关键词:android  电容屏 tp 工作队列 中断 多点触摸协议 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0  平台:S5PV310(sams ...

  6. 人工智能 | 自动驾驶与人工智能前沿研究报告(概念篇)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 ================= ...

  7. 人工智能 | 人脸识别研究报告(概念篇)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 ================= ...

  8. 人工智能 | 自然语言处理研究报告(概念篇)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 ================= ...

  9. JavaScript高级程序设计之基本概念篇

    日子天天过,啥都能忘,学习不能忘.<JavaScript高级程序设计>这本书之前看过,但是只看了js的部分,其余部分并没有看.当时想,看看js部分应该够用了,但最近看了篇文章,受到了很深的 ...

最新文章

  1. tpcc mysql 基准测试_使用tpcc-mysql 对mysql进行基准测试
  2. 《智源社区周刊:预训练模型》第2期:Facebook用“预微调”改进预训练性能、再议GPT-3中的东方主义偏见...
  3. 迁移到阿里云后,NTKO控件报存word 报文件存取错误,请检查网络传输。
  4. 安装Orcale 10g SP3时报oui.exe异常错误
  5. java应用系统正确的连接DM主备集群
  6. LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  7. Linux网络模式及远程连接出错排障
  8. C# WinForm中获取当前程序运行目录的方法
  9. 【HDU - 5934】Bomb (强连通分量Tarjan + 缩点)
  10. 关于Exchange管理控制台报“您的权限不足,无法此查看数据”的解决办法
  11. 《代码大全》阅读笔记-5-软件构建中的设计
  12. Pattern Recognition for Cell-free DNA - Github
  13. 20155334 2016-2017-2 《Java程序设计》第三周学习总结
  14. leetcode 336. Palindrome Pairs
  15. springboot 网页聊天室
  16. ios点击推送闪退_iOS 13.4 Beta 4 发布,闪退问题修复
  17. 纯干货:分享一些跨境电商客服经常会用到的话术(含中英文)
  18. DS18B20的使用介绍
  19. 个人日记:XML追加和覆盖内容,将XML某位置的子标签或者属性,文本删除
  20. CSDN写博客字体颜色、大小怎么写?

热门文章

  1. Spring Boot与Redis的集成
  2. 另一个.java文件调用_java - 如何调用另一个类“写文件”的方法? - SO中文参考 - www.soinside.com...
  3. static interface method calls are not supported at language level 1.6
  4. 零基础能学好UI设计吗
  5. Nancy in .Net Core学习笔记 - 初识Nancy
  6. 30秒或更短的时间内弄懂的有用CSS代码片段
  7. win10 spark+scala+eclipse+sbt 安装配置
  8. Xtrabackup实现数据的备份与恢复
  9. 【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法
  10. 使用最小堆优化Dijkstra算法