zoukankan      html  css  js  c++  java
  • 所有设计复杂的ORM都是浮云

    很久没有写文章了。

    一直很忙,不是很有时间整理。

    今天主要是来吐槽下那些设计很复杂的ORM的。

    项目做的越多,越觉得ORM这个东西设计的太复杂实在是没什么意义。

    比较推崇Dapper这样比较简单,效率比较给力的是ORM。

    他其实什么都没做,只是把数据库的字段映射到对象的字段上,我觉得就这一个功能就OK了。

    其他的功能对ORM来说基本上都是没什么用的。

    待我慢慢道来!

    一行只写一句话,是因为写C#代码习惯了,不是诗, 不要误会!

    你说你的ORM支持全数据库。

    啊哈,一般来说项目开始的时候数据库就已经选好型了。

    只要你不是非常二逼或傻逼,选一些非常不入流,而且能力不是很强的数据库。

    后面基本上是不会更换数据库的。

    所以,为毛要支持啊。

    在通用和性能之间,有一条沟,你要么站在沟左边,要么在沟右边。

    站中间,哈哈,掉下去了。

    你说你开始的没想到后面会有这么大的数据。

    啊哈,你的架构师不给力么!

    好,不是架构师的问题。

    穷逼的,牛逼的MYSQL。

    苦逼的,牛逼的MSSQL。

    二逼的,牛逼的ORACLE。

    傻逼的,牛逼的DB2。

    大家一开始都是在考虑当前的需求。

    并且稍稍的考虑的下未来几年的可能,或者没有考虑。

    所以不能怪架构师,谁让甲方刚开始只给那么点钱。

    好了,时间越来越久,数据库越来越慢。

    肿么办?

    升级数据库哈!

    这不,你看还是有换数据库的需求的吧。

    啊哈,怎么说呢?

    总觉得换一种数据库就能解决问题?

    世界上著名的数据库就那几种!

    在一些特定的领域

    ORACLE比MSSQL牛逼多少?

    MSSQL比MYSQL牛逼多少?

    牛逼不了多少的哈

    没见上边么,每一种数据库都有牛逼的人在用么

    你觉得你的数据库不行!

    你调优了么?你优化业务了么?你还在用奔腾时代的机器来挑战这大数据时代么?

    所以,换数据库是最最坏的打算。

    而且你就算想换,现在的ORM也解决不了100%的问题啊。

    数据迁徙,要专业工具!数据库管理,要专业人员!

    所以你想用一套东西来解决所有问题。

    上帝尚不能造一块自己搬不起的石头,何况是你!

    你说用了ORM,妈妈再也不用担心的我SQL了!

    啊哈,怎么吐槽你呢?

    好的开发人员有四个技术基本功,知道么!

    开发语言,SQL,抽象能力和自嘲!

    不会任何一样,你都不是一个好的开发。

    会拿开发语言写函数,会自定义对象,会拿语言表述一套完整的业务流程。

    不错!很不错!

    但是你还差三样!

    你起码要会写函数吧!知道怎么拿SQL自定义类型吧(对不起,主流数据库都支持的哈)!会用存储过程来表述一套完整的流程吧!

    但是你差两样!

    你说你已经写了一套ORM可以通吃所有数据库啦!

    呵呵,不错!来,学着星爷的腔调来一句,“其实我是一个程序员”!

    哦也,你功德圆满,随你师父和大师兄,三师兄以及小白马回大唐去吧!

    什么!

    你说不要把业务放到数据库里面,换数据库不方便!

    骚年,从头看看。

    好,你已经看过了,但是你还是觉得放到数据库里不放心,你还是可能换数据库!

    各种主流数据库的表主流的字段类型基本可以通用哈。

    各种主流数据库的函数和存储过程的调用都差不多哈。

    各种主流数据库的你有的基本大家都有哈。

    只要不使用太特殊的东西,换个库神马的,小case啦。

    你说你用了!

    你说你用了ORACLE的包,Java Source!你想换!

    你说你用了MSSQL的表变量,C# UDT,花了好几千大洋装上了R2!你想换!

    你说你用了MYSQL的枚举,对InnoDB疼爱有加!但是你想换!

    .......

    少年,为什么要放弃治疗!

    都这样了,都沧海桑田了,你还是好好珍惜你们的感情吧。

    换啥!换一种思维来解决问题吧,坑挖的越来越深的时候,就该想想是不是改往宽挖挖了!

    就算非得换数据库,你真的以为,自定义的那套别扭的语法能为你新的数据库带来很好的性能么?

    说我了解的,只说最简单的,而且通用的语法层面!

    CTE这么好用的东西,你来,用ORM生成一条试试看。

    MERGE这么好用的东西,你来,用ORM生成一条试试看。

    SQL BLOCK这么好用的东西,你来,用ORM生成一条试试看。

    (注:SQL BLOCK是ORACLE的叫法,MSSQL原生支持所以没有太V587的名字)

    为什么非要各种数据库的方言上做痛苦的挣扎?

    你确实练就了一身无敌的抽象能力,你确实碉堡了!

    但是,呵呵,别忘了那句,“我是程序员,你叫我序员就好了”,生亦何欢死亦何苦哈,何必非要和自己过不去呢,是不!

    你说你是处女座的,而且你还是个苦逼的后端程序员!

    你是说你见不了后台代码里,被SQL玷污的满目疮痍的开发代码!

    啊哈,SQLSHOP听过么,把SQL全部放到外置文件里进行统一管理,所有的查询都是按照绑定变量的方式进行。

    从不拼SQL,从不把SQL写到代码里,复杂的业务写成存储过程或函数。

    SQLSHOP让你的代码一尘不染。

    SQLSHOP让你担心的注入问题,执行计划问题轻松解决。

    SQLSHOP让你在写代码的岁月里幸福的像花儿一样。

    那什么地方有SQLSHOP呢?

    啊哈,刚好本仙身上带了一包,暂给元帅尝尝鲜,涉及一些不太方便的代码,请自行脑补。

    public class SQL 
    {
        private Dictionary<int,string> Sqls{get;  set;}
        private Dictionary<string,object> Parameters{get;  set;}
        
        public SQL(Dictionary<int,string> sqls)
        {
            if (sqls==null||sqls.Count==0)throw new NotSupportedException("sql can't empty");
            this.Sqls=sqls;
            Parameters=new Dictionary<string,object>();
        }
        
       public void AsyncExecute<T>(Action<Exception> error,Action<T> back)
       {
            //...查询数据库返回数据并映射到对象上
       }
       
       public void Add(string pname,object value)
       {
               Parameters.Add(pname,value);
       }
       
       
       public void Clear()
       {
               Parameters.Clear();
       }
    }
    SQL class
    public class SQLPath:DynamicObject
    {
         private StringBuilder builder=new StringBuilder();
         
         public override bool TryGetMember(GetMemberBinder binder, out object result)
         {
               var name = binder.Name;
               builder.Append('\');
               builder.Append(name);
               result=this;
               return true;
         }
         
         private SQLPath(){}
         
         public static dynamic RootPath
         {
             get
            {return new SQLPath();}
         }
         
         public SQL ToSQL()
         {
             return SQLShop.ReadSQL(this);
         }
         
         public string Path
         {
            get{
             return builder.ToString();
            }
         }
    }
    SQLPath class
    public static class SQLShop
    {
        public static SQL ReadSQL(SQLPath sqlpath)
        {
           var path=sqlpath.Path;
           Dictionary<int,string> sqls=new Dictionary<int,string>();
           //...按照文件组织或xml文件或者其他方式来读取这种查询下的全部sql,并做缓存
           //...获取全部SQL,并取出每个SQL的SQL参数的生成hash值存入到sqls的键种
           sqls.Add(-1581397123,"SELECT USER_NAME ,USER_ID FROM T_BASE_USERS T WHERE T.USER_NAME LIKE :user_name");
           sqls.Add(24307103,"SELECT USER_NAME ,USER_ID FROM T_BASE_USERS T WHERE T.USER_NAME LIKE :user_name and T.ADDRESS LIKE :address");
           return new SQL(sqls);
        }
        
    }
    SQLShop class
    void Main()
    {
        var root=SQLPath.RootPath.UserManager.UserPower.QueryUser;//用户管理-》权限管理-》查询用户
        var sql=(root as SQLPath).ToSQL();
        
        sql.Add("user_name","%王");
        sql.AsyncExecute<User>(
        ex=>
        {
            //发生异常
            Console.WriteLine(ex);
        },
        User=>
        {
           //取到正确数据
        });
        sql.Clear();
        
        sql.Add("user_name","王__");
        sql.Add("address","%西安%");
        sql.AsyncExecute<User>(
        ex=>
        {
            //发生异常
            Console.WriteLine(ex);
        },
        User=>
        {
           //取到正确数据
        });
    }
    demo

    (SQLSHOP的思想不是做一个ORM,而是做一个SQL的管理器,统一管理这些SQL,而不是凌乱的散落在各个class文件里面。)

    你说我总算发现了,你对我们这些功能齐全的ORM有偏见!

    啊哈,你说对了!

    不过我的偏见是有理由的哈!

    关系本来就是该数据库来处理,RDBMS的第一个R就是指关系,这个关系是说数据之间的数据关系。

    OO语言里面也有关系,不过是对象关系,虽然可以将数据关系按照某个原则转换到对象上!

    但是为了按照数据关系来组织数据对象总感觉不是那么美好!

    NH已经不是那么火热了!

    LINQ TO SQL也已经在慢慢消失。

    EF虽然活着,但只是活在很多小的项目,或者懒的开发人员那里。

    要想一套很好的ORM,想想NOSQL吧!

    只需要单表映射,不要再把复杂的关系组织到OO上了。

    就算某天觉得关系型数据库不给力了,想换NOSQL。

    噢耶,程序里面全是单表操作,so easy!

    珍爱生命,远离复杂的ORM!

    那怎么判断一个ORM是否复杂呢?

    1.全部使用对象的方式来操作数据库。(按理说,所有的开发人员应该都是见不到物理表的,所见的只能是视图,函数,或存储过程)

    2.由机器自动生成SQL并执行。(EF生成的SQL好么,你用一张C#的内存表关联一张数据库的一张表试试看,那长长的SQL,那淡淡的忧伤)

    3.包含复杂的查询语法,企图用一套自己的语法来通吃所有数据库。(你明白的,通吃有用?学习啥语法都不如学好SQL,数据库就那几种,SQL都差不多的)

    4.不承认我上边说的的,还执迷不悔的,就当我啥都没说,我没有在说你哈!

  • 相关阅读:
    I.MX6 2014 u-boot 测试修改
    I.MX6 新版、旧版u-boot不兼容问题
    I.MX6 NXP git 仓库
    I.MX6 2G DDR3 16G eMMC
    I.MX6 不一定要设置BOOT_MODE进入烧录模式
    拖动滚动条时某一处相对另一处固定不动(position:fixed)
    layer弹出层
    js设置全局变量ajax中赋值
    spring多个数据源配置
    JS学习之动态加载script和style样式
  • 原文地址:https://www.cnblogs.com/wushilonng/p/3346539.html
Copyright © 2011-2022 走看看