zoukankan      html  css  js  c++  java
  • 【挑战书】介绍一下我开发的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)结合一些设计模式,能够使缓存操作、事务操作变得非常简单,只需要做几个切换,用一些接口的方法之类的。

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

    后续

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

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

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

     

  • 相关阅读:
    系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式(分享二十二)
    某云数据中心网络解决方案(分享二十一)
    oracle 12c 管理(分享二十)
    Codeforces 356D 倍增优化背包
    Codeforces 360D Levko and Sets (数论好题)
    gym/102253C Colorful Tree 树上计数
    Codeforces 360E 贪心 最短路
    Codeforces 360C DP 计算贡献
    Codeforces 354B 博弈, DP,记忆化搜索
    Codeforces 354C 暴力 数论
  • 原文地址:https://www.cnblogs.com/zc22/p/1590166.html
Copyright © 2011-2022 走看看