ORM组件XCode(十八般武艺)html
以前,XCode老是若隐若现,耐性好的同窗想知道它还有啥特色,沉不住气的则认为不过是CURD耳!程序员
XCode开发模式是灵魂,XCode组件经过具体实现对其支持!数据库
XCode的特色以下:数组
0、基本的CURD功能缓存
实在想不出来不支持CURD的ORM算不算ORM;也实在想不出来仅有CURD的ORM算不算ORM。于是,这是0号功能!服务器
XCode的CURD经过反射实体类生成查询和操做SQL实现,数据库结构信息经过特性附在实体类上。之因此选择SQL而不是DbCommand,由于XCode的实体层和数据访问层是分开的,目前是为了实现一级缓存,未来会在这里实现分布式数据访问。多线程
一、完美支持ObjectDataSource架构
XCode实现充血模型(胀血模型)的实体类,提供ObjectDataSource须要的全部方法和参数,特别支持分页和排序功能!并发
二、全面分页支持
只有从小处开始培营养页的思想,任何查询都指定所需获取数据范围,才能保证系统数据变大时系统不会拓机。
XCode的分页以任意查询语句为基础,支持统计等很是复杂的查询分页。而且会根据当前数据库类型以及版本选择最佳分页方案。
三、实体集合支持
实体集合EntityList继承自List,提供了实体的批量操做。实际上仍是经过遍历集合逐个进行实体操做,由于充血模型的实体类多是经过重载修改CURD的行为,因此不能使用一个SQL语句操做一批实体,XCode不会作这种可能会影响使用的小把戏。
实体集合还提供了一些方便查询和排序的简便方法,实体缓存中将会大量使用。
四、万能的一级缓存
一级缓存由数据访问层实现,以查询SQL为键,返回的数据集为值,查询的表名数组为依赖项,进行缓存。执行SQL时一样须要指定影响的表名数组,从而清空全部影响到的缓存。
缓存生命周期分为请求级、按期和永久三种。若是只有当前应用系统使用该数据库,而且服务器内存足够大,能够开启永久缓存,在数据没有更新时,基本缓存在内存中,适用于网站;通常设定一个缓存过时期限,按期清理缓存,适用于内存不是很足,或者容许数据更新有必定延后的分布式系统;若是上面两种均不合适,而又须要提升系统响应速度时,能够采用请求级缓存,在该次页面请求生命周期内对数据进行缓存,特别适用于在不一样地方进行相同查询的场合(有时候是程序员功力不够写错的)。
XCode的开发模式建议使用尽量简单的单表查询,实际大部分查询都是简单SQL语句,缓存命中率很高!
五、漂亮的实体缓存
实体缓存又成为二级缓存。尽管有了一级缓存,但它只是缓存了数据集而已,使用的时候仍是要加载数据集成为实体集合。
实体缓存经过指定一个查询实体集合的方法,通常是查询本表全部实体的FindAll()方法,把查询返回的实体集合缓存起来(默认缓存一分钟),供上层代码使用。取数据的过程彻底是隐式进行,实体缓存经过提供一个静态实体集合供上层代码查询,实体集合属性内部进行查询数据和缓存过时检查等操做。查询方法经过委托传递,还有参数能够指定是否异步获取缓存数据。
总之,使用实体缓存就是使用一个静态的实体集合属性(大多数时候使用默认配置,因此不须要配置),进行查询排序等操做,无需关心缓存的具体实现。固然,对实体进行修改操做时将会清空缓存,保证数据的新鲜性。
单表数据量不大(建议1000如下,不超过10000),而且极少改动的数据表使用实体缓存。好比权限、角色、菜单、系统参数等使用很是频繁的数据。实体缓存的命中率能够高达99.98%
六、飘逸的单对象缓存
单对象缓存又层三级缓存,由于它通常构建于二级缓存之上。对于数据量大(大概几万到几十万),而且查询又很是频繁的数据表,任意两行数据之间关系不大时,能够酌情使用单对象缓存。好比会员表,通常会根据帐号进行查找,而且很频繁,此时能够以帐号为键,会员对象为值,对数据进行缓存。设置与实体缓存相似。取数据时先去缓存中找,有则直接返回,没有则调用预设的方法进行查询,而且缓存起来。
单对象缓存里面的实体对象,修改数据时,如非必要,不要手工调用更新方法,单对象缓存有自动保存的功能。该特性适用于更新很是频繁的场合,好比在线用户表,可让屡次更新积累在一块儿,而后最后自动更新一下。
七、出色的性能
XCode不支持多表查询,通常的多表关联查询均可以拆分红为1+X的屡次单表查询。好比学生和班级的关联查询,能够先查10个学生信息,再分别查他们的班级信息,就成了1+10=11次单表查询。每一次单表查询确定会比多表关联查询要快,可是11次单表查询不少时候都会比一次多表关联查询慢。
回过头来看看上面的缓存,若是这10个学生是同班,那么在一级缓存的做用下,实际查询数据库将会是1+1=2,后面9次班级查询被一级缓存拦截了。在高并发的系统中,后面这个1就趋向于0了,由于缓存是全局共享的。
再来看看实体缓存,一个学校的班级不会不少,符合条件使用实体缓存。也就是一次性读取全部班级信息,缓存到实体集合中。即便在最糟糕的状况下,10个学生都处于不一样班级,实体缓存也是百分百命中,实际查询仅仅是对学生表的单表查询,此时确定比多表关联查询快。
在学生资料界面等地方,学生表查询是很是频繁的。显然,这是一个很是适用单实体缓存的场合。学生附属属性(关联表)等信息,能够经过扩展属性“挂”在学生实体对象上,“享受”到缓存的待遇。
数据库层面也有一个缓存,能够算是0级缓存吧。咱们全部的查询都是单表查询,对数据库而言很是简单,同时,由于简单的SQL,数据库缓存命中率极高,而且很是便于创建索引进行优化。
基于分页和缓存,XCode提供了一套高性能的解决方案,这种方案远胜于传统的多表关联查询,而且是系统并发越高,这种优点越明显。
八、脏数据支持
在更新数据的时候,每每业务需求是只更新咱们修改过的数据。好比会员资料修改表单,能够设置会员信息等资料,可是不能修改最后登陆时间。这个时候,咱们就须要知道哪一个属性的数据被咱们修改过!
XCode的实体类中,每一个数据属性的set方法,都会先调用OnPropertyChange方法,其实就是为了设置该字段的脏属性,说明这个字段的数据曾经被修改过。生成Update语句的时候,只修改带有脏属性的字段。
实体类中,除了直接修改属性外,还能够经过索引器进行修改,两种的区别就在于经过索引器修改属性时,不影响脏数据设置。实际上,加载数据行到实体类中,使用的正是索引器,因此刚加载完成数据的状况下脏数据是空的。
九、多数据库支持
(MSSQL2000、MSSQL2005/200八、Oracle、MySQL、Access、SQLite)
与大多数ORM同样,XCode经过接口的方式支持多种数据库。在XCode中,为每个数据库实现了一个数据库操做类,继承自数据库接口。数据访问层DAL根据数据库链接的配置识别是哪种数据库,而后建立该数据库操做类的实例,并经过操做接口来操做数据库。
数据库操做类以Access数据库为蓝本,设计了一个基类,其它数据库操做类仅须要继承该类,重载功能点不一致的属性和方法,大大减少了操做类的大小。
数据库操做接口包含的功能有:查询、执行、分页、事务、获取架构、DDL操做、数据库版本等。实际上,各个数据库的差别点均可以设计在操做接口中,而上层代码根本不须要改动。
不少ORM都为各个数据库的差别大而苦恼,XCode开发模式则否则。咱们的原则是一切从简,只使用SQL,不适用DbCommand和存储过程。而所使用的SQL,基本上也是标准SQL,不会使用数据库特性,而且都是单表操做。固然,这种方法也不是万能的,不得已的时候,能够在业务层判断当前数据库类型,根据不一样数据库编写不一样的SQL,但自XCode使用以来,还没须要这样作过。
十、获取数据库架构
(DAL.Tables)
在XCode中,数据库架构主要包含XTable和XField类,顾名思义,它们表明着表和字段信息。数据访问层DAL中有个成员属性Tables能够取得该数据库链接的全部表信息,也就是一个XTable集合。同理,每个XTable中,都会有一个XField集合。
这样设计,简单明了,使用者能够很容易的找到本身须要的东西。咱们的代码生成器XCoder就是依赖于XCode来获取数据库架构的。有了这个功能,人人均可以写本身的代码生成器了!
十一、反向生成数据库架构
(DatabaseSchema)
这是一个很另类的功能,极少有ORM提供。在开发和维护的过程当中,不免须要修改表结构,从新生成实体类(仅生成实体类数据文件部分)。在团队开发的时候,若是不是共用数据库,则还须要通知队员作相应的修改。维护的时候,还须要到生产环境作更新,若是客户不容许直接操做数据库,那就更麻烦了。
在数据库操做接口中,其中一个功能就是DDL操做,各个数据库进行重载后,可使用DDL语句操做数据库的结构。经常使用的功能有:建立表、修改字段属性、添加字段、删除字段等。
XCode除了会从数据库生成数据库架构外,还会从实体类生成一套数据库架构,而后进行对比,发现存在差别后,直接修改或者写日志提醒(由设置决定)。修改开关没打开时,仅仅写日志提醒,日志中写出了完整的用于修正数据库架构的DDL语句,拿到数据库中执行便可。
基于XCode开发的系统,在发布的时候,历来不带数据库,由于XCode会自动根据链接字符串建立数据库、数据表和字段。即便开发使用的是A数据库,发布的时候修改数据库链接字符串为B数据库,XCode将会按照B数据库的规范来建立数据库。若是系统发布还须要附带数据,那就不可能作到发布时更换数据库了,除非发布多个数据库的版本。
也许有人会说,不带数据库的话,初始化的数据怎么办?在XCode的开发理念中,建议在实体类增长静态构造函数,用于检测数据表数据,若是没有数据时,是否须要建立一个默认数据,好比在管理员表建立一个用户名和密码都是admin的管理员。
十二、动态修改链接和表名
(Meta.ConnName,Meta.TableName)
数据量增大到必定程度时,不少企业的方案都是给数据表更名或者把该表迁移到别的数据库中去,仅用于查询统计。
在XCode中,生成实体类时,就指定了实体类所对应的表名,可是咱们并不须要为多个具备相同表结构的表生成多个实体类,由于实体类能够动态修改所指向的表名,使得操做的目标表发生改变。为了不多线程环境所带来的影响,该修改仅影响当前线程。
链接名的修改方式与表名相同。
1三、弱类型访问
(IEntity,IEntityOperate)
有时候,咱们并不知道须要操做的是哪个实体类,只有在运行时才能肯定下来。经常使用的作法就是反射!
为了不没必要要的性能损耗,以及避免很不美观的编码设计方式,XCode提供了弱类型访问的能力。能够经过指定类型或者表名,反射找到实体类,建立一个IEntityOperate操做对象,从而完成对实体类的各类操做。
IEntityOperate所提供的方法跟实体类的静态方法基本一致,在使用上不会遇到任何困难。IEntityOperate进行数据查询时,返回的是IEntity集合,由于每个实体类,都实现了IEntity接口,足以完成基本的CURD操做。
1四、动态生成代码
(CodeDOM,内存实体)
在弱类型访问的支持下,有些简单的数据库操做并不必定须要生成实体类,XCode在找不到实体类时,将会根据表架构在内存中生成一个实体类,而后编译使用。
动态生成的另外一目标是让使用者经过调用一些方法来生成实体类代码,而不是必定要经过XCoder来生成。
1五、扩展加载
(把查询中的字段映射到扩展属性)
XCode支持的是充血模型,从面向对象的角度上来说,这个对象的全部特色(属性)和能力(方法)都应该在实体类上实现。除了基本的与数据库字段对应的数据属性外,还有一些跟别的实体对象关联的属性,咱们称之为扩展属性。好比:Article.Board.Manager.UserName,能够直接获得一个帖子的版主的用户名。
XCode不支持多表关联查询,可是它有扩展属性,全部的多表关联查询,均可以经过扩展属性来编码实现。Article中的Board扩展属性,是在使用的时候才去加载的,加上Board可使用实体缓存,基本上没有数据库操做。Manager不能使用实体缓存,可是它做为扩展属性“挂”在Board上,间接“享受”了缓存。
还能够编写一个普通的属性做为扩展属性,而后执行查询的时候,经过selects参数把数据映射到该扩展属性上。好比:增长一个Total的整型属性,而后执行查询Article.FindAll("BoardID=123",null,"Count(*) as Total",0,1),该查询是取得栏目编号为123的全部帖子数,而后把结果映射到Total属性上,返回的记录集只有一个实体对象,该实体对象的Total属性就是所要查询的帖子数,此时别的属性没有意义。
该功能通常用于查询统计中。使用一个实体来表现数据,比数据集方便多了。
扩展属性是充血模型所特有的东西,也是相对于贫血模型(含失血模型)的最大优点所在!
1六、泛型基类模型
(Entity)
XCode从v1.2起,就进入了第二代,关键点就在于泛型基类Entity的使用。
在第一代XCode中,由于充血模型,实体类上要附带大量的方法,而当它们的返回类型是实体类或者实体类集合时,这些方法就必须实现于实体类的代码中,其实是经过代码生成器来生成。
在第二代XCode,引入了泛型基类技术,实体类经过泛型参数TEntity指定最终返回类型,编写查询方法的时候,返回类型使用泛型参数TEntity便可。因此,第二代实体类只有属性和索引器,基本不须要生成查询和操做的方法,由于它们都在泛型基类里面实现了。
大多数状况下,实体类指定的基类泛型参数就是它本身,由于它须要以它本身做为返回类型。但XCode开发模式是面向对象的,包括实体类,也但愿可以继承,增长一些功能,该功能能够经过改变泛型参数来实现。
1七、实体类的继承与重载
(NewLife.CommonEntity)
经过改变泛型参数的具体类型,实现实体类的继承和重载,是XCode进入第三代的标志。它标志着咱们能够封装一些基础数据实体来供多个项目使用。
通用实体组件NewLife.CommonEntity就是该功能的表明,封装了地区、管理员、角色、菜单、受权等实体类。具体项目能够直接使用它们,也能够经过继承与重载来实现扩展。
以封装的地区表为例,它在静态构造函数中检测数据表行数,固然,在这以前XCode会自动检测并建立地区表。若是地区表中没有数据,则会调用一个方法进行数据初始化操做。地区表业务类代码经过硬编码方式,内置了全国几千个地区的区域编码和名称。一旦国家修改区域划分,只须要修改该类,全部使用该组件的项目都将使用上全新的区域数据。若是这些功能代码都复制到每个使用的项目中去,将造成一个很是难以维护的情况。
XCode的十八般武艺就介绍到这,更多的功能须要你去发现!欢迎感兴趣的朋友前来交流讨论,QQ群10193406
XCode就是为了让一切变得简单!学习简单、使用简单、想法简单……功能不简单!
大石头
新生命开发团队
2010-09-24 4:18
做者: 大石头 发表于 2010-09-25 09:21 原文连接
最新新闻:
· 是否该让开发人员跟客户直接交流?(2010-12-21 07:53)
· 亚马逊副总裁跳槽Groupon任CFO(2010-12-21 07:50)
· Gmail语音服务将延长至2011年末(2010-12-21 07:49)
· AOL收购我的档案网站About.me(2010-12-21 07:48)
· AT&T 19.25亿美圆购入高通 700MHz 低频频谱(2010-12-21 07:42)
编辑推荐:Mono又更新了