很久没有写文章了。

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

今天主要是来吐槽下那些设计很复杂的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==)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(-,"SELECT USER_NAME ,USER_ID FROM T_BASE_USERS T WHERE T.USER_NAME LIKE :user_name");
sqls.Add(,"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.不承认我上边说的的,还执迷不悔的,就当我啥都没说,我没有在说你哈!

所有设计复杂的ORM都是浮云的更多相关文章

  1. 各种U启网启什么的都是浮云

    对于支持BIOS的电脑,优盘启动,网络启动的各种方案感觉都是浮云,从硬盘启动PE进行维护才是最可靠的.不点在开发wee的过程中给了我们很多维护的灵感,不用费劲地折腾fbinst/U+/量产/PXE/I ...

  2. 所有的代码生成器都是浮云,如果可以用aspx文件作为模板

    首先申明:标题中的如果是可以去掉的. 想写这篇文章很长时间了,一来是跟大家分享一下,别浪费时间在写代码生成器上面了,什么CodeSmith,XXCodeGenerator等等,都是浮云:二来想跟大家交 ...

  3. oracle第一招之神马都是浮云

    oracle: 一款关系型(二维表)数据库,可以用来存储海量数据.在大数据量并发检索的情况下,性能要高于其他的同类数据库产品.一般运行环境是Linux和Unix操作系统上! 目前最流行的商业数据库,主 ...

  4. 1. 连接字符串的创建 - Lazy.Framework从零开始设计自己的ORM架构

    开发初衷 注册了博客园已经有几个月了,却从来都没有上来过,本人大概从2010年开始就开始做.NET 方向的开发. 这个是我在博客园发布的第一个帖子. 主要就是说说最近在写的一个ORM架构. 本人接触的 ...

  5. 轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)

    hey,guys!我们一起总结一下JS预解析吧! 首先,我们得搞清楚JS预解析和JS逐行执行的关系.其实它们两并不冲突,一个例子轻松理解它们的关系: 你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解 ...

  6. 思科恶意加密TLS流检测论文记录——由于样本不均衡,其实做得并不好,神马99.9的准确率都是浮云啊,之所以思科使用DNS和http一个重要假设是DGA和HTTP C&C(正常http会有图片等)。一开始思科使用的逻辑回归,后面17年文章是随机森林。

    论文记录:Identifying Encrypted Malware Traffic with Contextual Flow Data from:https://songcoming.github. ...

  7. 神马都是浮云,unity中自己写Coroutine协程源代码

    孙广东   2014.7.19 无意之间看到了,Unity维基上的一篇文章,  是关于自己写协程的介绍. 认为非常好,这样能更好的了解到协程的执行机制等特性.还是不错的. 原文链接地址例如以下: ht ...

  8. PCB设计中新手和老手都适用的七个基本技巧和策略

    本文将讨论新手和老手都适用的七个基本(而且重要的)技巧和策略.只要在设计过程中对这些技巧多加注意,就能减少设计回炉次数.设计时间和总体诊断难点. 技巧一:注重研究制造方法和代工厂化学处理过程 在这个无 ...

  9. CYQ.Data 从入门到放弃ORM系列:开篇:自动化框架编程思维

    前言: 随着CYQ.Data 开始回归免费使用之后,发现用户的情绪越来越激动,为了保持这持续的激动性,让我有了开源的念头. 同时,由于框架经过这5-6年来的不断演进,以前发的早期教程已经太落后了,包括 ...

随机推荐

  1. spring boot 单元测试

    Java新手 纯记录 @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = OutDemoApplication.clas ...

  2. shell脚本-2

    http://www.runoob.com/linux/linux-shell-variable.html 字符串可以用单引号,也可以用双引号,也可以不用引号.单双引号的区别跟PHP类似. 单引号字符 ...

  3. Oracle 批量增加 / 批量跟新

    在使用oracl过程中踩到好多坑,在此记录,也分享给大家. 第一:批量插入 代码一(在为明确表和字段的情况下,动态批量增加): @Insert("<script> " ...

  4. java-多线程(下)&GUI

    ###25.01_多线程(单例设计模式)(掌握) * 单例设计模式:保证类在内存中只有一个对象. * 如何保证类在内存中只有一个对象呢?     * (1)控制类的创建,不让其他类来创建本类的对象.p ...

  5. 学习笔记CB002:词干提取、词性标注、中文切词、文档分类

    英文词干提取器,import nltk,porter = nltk.PorterStemmer(),porter.stem('lying') . 词性标注器,pos_tag处理词序列,根据句子动态判断 ...

  6. 查看celery 队列长度

    BROKER_URL = 'redis://127.0.0.1:6379/2' quque 名称:celery 查询队列长度命令: redis-cli -n 2 llen celery 注释: -n: ...

  7. Python基础:六、变量和常量

    一.变量 1. 变量: 将运算的中间结果暂存到内存,以便后续程序调用 2. 变量的作用: 代指内存里某个地址中保存的内容 3. 变量的命名规则: 1. 变量由字母.数字.下划线搭配组合而成 2. 不可 ...

  8. 易忽视的Python知识点

    1.sort和sorted (1)sort:会直接修改原始列表的序列,只是排序,不去重. >>> a=[2,5,7,8,3,5,1,3,9,6,2] >>> a.s ...

  9. 游戏编程算法与技巧 Game Programming Algorithms and Techniques (Sanjay Madhav 著)

    http://gamealgorithms.net 第1章 游戏编程概述 (已看) 第2章 2D图形 (已看) 第3章 游戏中的线性代数 (已看) 第4章 3D图形 (已看) 第5章 游戏输入 (已看 ...

  10. from组件

    目录 一.生成页面可用的 HTML标签 二.对用户提交的数据进行校验 三. form 综合示例: 四. modelform(自动根据字段生成表单) 五.modelformset 一.生成页面可用的 H ...