好久没有写文章了。程序员
一直很忙,不是颇有时间整理。sql
今天主要是来吐槽下那些设计很复杂的ORM的。数据库
项目作的越多,越以为ORM这个东西设计的太复杂实在是没什么意义。后端
比较推崇Dapper这样比较简单,效率比较给力的是ORM。缓存
他其实什么都没作,只是把数据库的字段映射到对象的字段上,我以为就这一个功能就OK了。架构
其余的功能对ORM来讲基本上都是没什么用的。app
待我慢慢道来!ide
一行只写一句话,是由于写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(); } }
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(); } } }
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); } }
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=> { //取到正确数据 }); }
(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.不认可我上边说的的,还执迷不悔的,就当我啥都没说,我没有在说你哈!