【挑战书】介绍一下我开发的orm框架 欢迎各位能人义士前来挑战!

前言

最近园子整天为了不是技术的东西在讨论,我就调节一下气氛。介绍一下我开发的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>("REBORNZHANG@GMAIL.COM");
IOrmRightQuery query 
= OrmManager.Instance.RightQuery;
query.Obj 
= user;
query.Position 
= "USER.ROLELIST";
List
<OrmRole> list = query.Select<OrmRole>();

这个是向右查询。意思是:我知道了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>("rebornzhang@gmail.com");

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)结合一些设计模式,能够使缓存操作、事务操作变得非常简单,只需要做几个切换,用一些接口的方法之类的。

总而言之,良好的设计模式是必须的。

后续

本人自不量力,在此发出一份挑战书,希望有牛人觉得他的作品比我的更优秀,拿出来晒晒,好让我惭愧惭愧。

其实我更多的是希望能够获得新的思想,而不是激起矛盾。

那么,在心平气和的前提下,我敬候挑战者的到来!

 

posted @ 2009-10-26 19:37    阅读(3792)  评论(55编辑  收藏  举报
IT民工