功夫 、Persistore 及其它
功夫看了枪版(为自己汗颜一下,实在是等不及了,而电影院多少年没有进去了已经),然后开始在网上找相关评论,就好像是自己的东西一样,期待着人们有好的反应,结果大家也知道,毁誉参半,或者说批评还要多一些,说星爷放弃了擅长的无厘头,玩起来了特效,失去了自我。
Persistore是什么? 一个我正在开发的for .Net的O/R Mapping框架,大家可能奇怪了,现在成熟半成熟的.Net下的O/RM都已经多得让人眼花缭乱了,为什么还要自己开发一个?! 难道我这么喜欢无意义的重复开发,并且想依靠这个东西来证明自己的能力?
再回到功夫上来,可以说,我一向欣赏的是香港电影讲故事的能力和星爷无厘头的表演,对于国产大片(以英雄、埋伏为代表)和好莱坞大片却并不感冒,因为我需要的不是视觉的冲击而是看电影时的放松和快乐,哈哈一笑,仅此而已,然而功夫在这方面带给我的这些东西非常少,可以说让我很“失望”,但是同时我们应该知道,功夫是星爷的再一次尝试,为了圆一个儿时的梦,用三年时间,换来一部风格迥异的电影,当然他自然也会从票房着想,为了国际化,更多地简化语言,强调动作。
我不喜欢功夫,但是我欣赏星爷的这种尝试和努力,同时Persistore也是我自己的尝试和努力,因为我一直以来就想开发我所希望的O/RM,.Net出现已经4年了,而我现在才正式开始进入.Net开发,然而我这个想法一直以来就没有改变过。
那么Persistore有哪些特性?它凭什么可以让我不选择其它的成熟解决方案?就像黑客帝国、指环王中的特效已经这么好了,为什么功夫还要玩特效?
1、纯实体类
这是我对自己的O/RM最重要的一个要求,纯实体类不仅轻,而且可以便于移植(有人说了,谁会去移植?!),可能是我太偏执的原因吧。
2、自动映射
Persistore不需要自定义属性和XML文件的支持便可实现映射。 我们已经有了数据库模型了,我们已经有了实体类了,为什么还需要再去维护映射?!
3、关系维护
OnetoOne、OnetoMany、ManytoMany、SelfAssociate支持,正如yyanghhong所说,不支持关系的O/RM还不如直接用typed-dataset.
4、自动创建数据库结构(需要自定义属性支持)
Class->Database已经成为潮流了,本来不准备支持的,但同事AdamBear说得很对,在早期的迭代式开发中,难以建立完整的数据库模型,所以实体类是优先考虑的。和其它框架不一样的是,Persistore不需要创建额外的字典信息表,同时可以在主键不改变的情况下动态添加、删除、更新字段的定义。
5、lazy-loading
在支持关系维护后,没有迟加载的话,那么对于性能就是致命的下降。Persistore可以迟加载对象属性、实体集合,并且对于迟加载的实体集合只使用一次查询完成。
6、实体继承
Persistore完全支持实体继承,可以同时支持JoinTable和UnionTable两种持久化方案,即分表保存和单表保存。
7、对象化查询
现有的O/RM中只有极少数的(如ECO)支持真正的对象化查询(即UML2.0中的OCL),hibernate的HQL实际上还是sql的变种,Dataobjects.Net里的也还是sql,不过比sql还难理解,Persistore的OCL支持同样也是有限的(扩充了函数,但减弱了集合操作,因为OCL最终将解析成SQL),它的形式如下:
Department.Employees->Sum(salary) > 100
重要的是对关系的查询,而不仅仅是属性的过滤。
8、跨数据库平台和SqlBroker
从一开始,Persistore的设计就是要支持多数据库平台的,各大数据库厂商对标准SQL的支持越来越好,同时标准SQL本身的功能也在增强,这使得平台无关的SQL语句已经可以完成绝大多数功能。通过Persistore执行的sql只能是被其支持的标准SQL。
9、View、Store Procedure支持
这是一个数据库应用程序必不可少的,同时弥补上面SqlBroker的不足。
10、其它特性
Criteria查询构造、NULL处理、事务支持(transaction和savepoint)、不完全实体对象查询、多种"脏"标志获取方法(default value、snapshot value、dynamic proxy)、延迟更新和批量更新。。。
还需要多久?
目前差的是OCL和ANSISQL的解析(语法分析已经完成)、Store Procedure的封装以及最重要的实体类自动生成工具(CodeDG已经够灵活了,但它还不能提供Persistore最需要的外键约束信息)
如何使用?
一个简单的例子:
Address a1 = new Address();
a1.id = "001";
a1.street = "any";
Class c1 = new Class();
c1.id = "01";
c1.name = "grade1";
Student s1 = new Student();
s1.Class = c1;
s1.address = a1;
s1.id = "0001";
s1.name = "progame";
Assert.IsTrue(s.Save(s1));
Student s2 = (Student)s.Load(typeof(Student), "0001");
Assert.AreEqual(s1.name, s2.name);
Assert.AreEqual(s1.Class.name, s2.Class.name);
Assert.AreEqual(s1.address.street, a1.street);
Student s3 = new Student();
s3.id = "0001";
s.Load(s3);
最后说点什么
写代码真的好累,有时候真的不想写了,但想想星爷,想想功夫,即使做出一个被人批评的东西,但至少事后我可以无悔地说:我做过了!