前言
最近园子整天为了不是技术的东西在讨论,我就调节一下气氛。介绍一下我开发的ORM框架。还有基本的实现原理。
条条大路通罗马,源码等就不公开了,还是那句,思想才是最重要的。
代码例子
实体类的设计
只要继承了OrmBase,就实现了orm操作,不需要写任何的配置文件
public
class
OrmUser : OrmBase
{
string
userName;
OrmRole temprole;
List
<
string
>
addresses;
List
<
OrmRole
>
roleList;
[OrmPrimaryKey]
public
string
UserName
{
get
{
return
userName; }
set
{ userName
=
value; }
}
public
OrmRole Temprole
{
get
{
return
temprole; }
set
{ temprole
=
value; }
}
public
List
<
string
>
Addresses
{
get
{
return
addresses; }
set
{ addresses
=
value; }
}
public
List
<
OrmRole
>
RoleList
{
get
{
return
roleList; }
set
{ roleList
=
value; }
}
}
public
class
OrmRole : OrmBase
{
string
name;
public
string
Name
{
get
{
return
name; }
set
{ name
=
value; }
}
}
目前支持了所有的值类型,还有string类型,自定义的class,List类型,Array类型;至于Dictionary其他的不是很通用我就不支持了。
部署过程
OrmManager.Schema.Commit
<
OrmUser
>
(config);
只要操作Commit,就可以把ORM映射到数据库,至于怎么映射的,这个不是用户考虑的,因此我的ORM操作起来非常的顺手。没有任何多余的代码、多余的配置。
普通调用过程
for
(
int
i
=
0
; i
<
100
; i
++
)
{
OrmUser user
=
new
OrmUser();
user.UserName
=
"
helloworld
"
+
i;
OrmRole role
=
new
OrmRole();
role.Name
=
"
role
"
+
i;
}
过程中,每一步包括创建、赋值都已经直接操作了数据库,所以我的orm和普通的OO代码没有任何区别。
但是这样调用性能是很低的,每次赋值都会插入数据库,因此,我提供了缓存功能。
缓存操作
IOrmBufferion buffer
=
OrmManager.Instance.Bufferion;
for
(
int
i
=
0
; i
<
100
; i
++
)
{
OrmUser user
=
buffer.Create
<
OrmUser
>
();
user.UserName
=
"
helloworld
"
+
i;
OrmRole role
=
buffer.Create
<
OrmRole
>
();
role.Name
=
"
role
"
+
i;
}
buffer.Commit();
如果使用了缓存,那么在Commit之前,所有操作都在内存,这样极大的提高了速度!
当然,在commit里面使用了一定的优化算法,比如合并同类数据等等,减少操作数据库的次数。
ORM的关键——查询问题
ORM是否成功,关键就是查询的实现,我自己编写了一套面向对象的查询语法,非常的简单(不要和Hibernate的HQL对比哦)
先展示一个简单的查询例子
User user
=
OrmManager.Instance.Query.SelectByUpk
<
User
>
(
"
[email protected]
"
);
IOrmRightQuery query
=
OrmManager.Instance.RightQuery;
query.Obj
=
user;
query.Position
=
"
USER.ROLELIST
"
;
List
<
OrmRole
>
list
=
query.Select
<Orm
Role
>
();
这个是向右查询。意思是:我知道了User的对象,想查询他的RoleList的所有值。
使用起来顾名思义,所以我的查询语法是非常简单的,就是【对象】的【属性】的【属性】,
例如User有个属性ROleList,那么查询就是User.RoleList。
复杂的向右查询
IOrmRightQuery query
=
OrmManager.Instance.RightQuery;
query.Position
=
"
user.roleList.Permission.ResList.Value = :VALUE
"
;
query.Paras.Add(
"
VALUE
"
, resName);
return
query.Select
<
string
>
().Count
>
0
;
这个查询是我的权限框架里面经常用到的,就是查询:
当前用户的 角色列表里面的 授权项目里面的 资源名 是否包含输入的资源resName
User RoleList Permission ResList.Value
绝对的顾名思义,估计什么人都很快上手的。
向左查询实例
IOrmLeftQuery query
=
OrmManager.Instance.LeftQuery;
query.Condition
=
"
PROJECTNAME = :PROJECTNAME AND STATUS = :STATUS
"
;
query.Paras.Add(
"
PROJECTNAME
"
, projectName);
query.Paras.Add(
"
STATUS
"
, WorkflowStatus.Running);
return
query.Select
<
WfProjectInstance
>
();
这个是个向左查询的例子,是我的工作流框架里面常用的查询。
1. 我要查询一个对象叫做WfProjectInstance
2. 这个对象的projectName = projectName、状态=WorkflowStatus.Running
混合查询
User user
=
OrmManager.Instance.Query.SelectByUpk
<
User
>
(
"
[email protected]
"
);
IOrmAdvanceQuery
<
PageRole
>
advance
=
OrmManager.Instance.GetAdvanceQuery
<
PageRole
>
();
IToLeftQuery left
=
advance.CreateToLeftQuery();
left.Condition
=
"
PageRole.RoleName= :ROLENAME
"
;
left.Paras.Add(
"
ROLENAME
"
,
"
MERCHANT_LEVEL_03
"
);
IToRightQuery right
=
advance.CreateToRightQuery();
right.Obj
=
user;
right.Position
=
"
USER.PAGEROLELIST
"
;
List
<
PageRole
>
list
=
advance.Select(right, left);
最后一个是我最精华的查询:混合查询;结合了向右查询和向左查询。
具体解释我就不说了,由于混合查询的sql性能比较低,我用的还是比较少的。其实设计合理,一般是不用混合查询的。
设计思路
现在简单介绍一下我的ORM的一些技术思路。
1. AOP
用了.net提供的AOP思路,本质就是一个基于Message模型的调用。因此对实体类所有操作,会被AOP拦截,然后判断用户需要操作的对象、返回类型;然后转化为SQL获取数据。
2. Reflect
用了反射,这个也是必然的,除了对值类型(Valuetype)反射,还有自定义的class的反射,获取元数据,然后组成sql
3. ORM的理论
比如 User {List<Role> list;}
这个类,会被映射为三张表
A:TB_USER表
B:TB_USER_LIST的链接表
C:TB_ROLE 表
其实掌握了基本的ORM理论,知道对象如何映射为表之后,就能够实现大部分功能了。这个还多亏了Oracle的ORm资料,写的非常详细,让我少走了很多弯路。
4. 一些自定义的表名、主键值生成
要使用方便,那么就要把很多灵活的操作变得不灵活,比如表名的命名、主键的生成,这些我都会让ORM自己完成,不需要程序员手动设置。
是牺牲了一些代价,但是只要你使用了我的orm,换回来的是非常良好的操作和维护。
5. OO的设计模式和理论
良好的设计模式事半功倍,在我的ORM框架里面
1)所有自定义对象会被映射为一个ObjProxy对象,这个称为对象代理;因此对自定义类的操作,会变成ObjProxy的操作
2)结合一些设计模式,能够使缓存操作、事务操作变得非常简单,只需要做几个切换,用一些接口的方法之类的。
总而言之,良好的设计模式是必须的。
后续
本人自不量力,在此发出一份挑战书,希望有牛人觉得他的作品比我的更优秀,拿出来晒晒,好让我惭愧惭愧。
其实我更多的是希望能够获得新的思想,而不是激起矛盾。
那么,在心平气和的前提下,我敬候挑战者的到来!