欧博开户:“造轮运动”之 ORM框架系列(一)~谈谈我在现实营业中的增删改查

admin 5个月前 (11-19) 科技 112 3

  想想结业已经快一年了,也就是约莫两年以前,怀着满腔的热血正式跨入程序员的天下,那时刻的自己想象着所热爱的手艺生涯会是何等的厚实多彩,天天可以与大佬们坐在一起讨论解决各种牛逼的手艺问题,喝着咖啡,翘着二郎腿,大致就是下面这幅场景:

  

 

  可是现实却总是那么不尽如人意,现实的所谓手艺生涯是永远写不完的增删改查,另有那日渐稀薄的头发,哎,难...

  

 

    话说回来,若是连增删改查都做欠好,还谈何手艺生涯。

     以是,我一直以为:若是你以为自己是一个优异的程序员,那就应该从最基础的增删改查中就能体现出来

     有人可能会说,增删改查?很难吗?

     实在,说难,也不难,无非就是写SQL,Add、Delete、Update、Select,仅此而已;然则若是只是从SQL的角度以为这很容易,而对其不懈一顾,那你可能就和当初刚刚开始增删改查大业的我一样,太无邪了。

    首先,我和人人分享一下我在事情这将近两年中在增删改查这条路上的心路历程。

 

一、初出茅庐——原生sql走天下,sql写到手抽筋

    某年某月某日,大三尾声,翘课在宿舍睡大觉的我刚从床上艰难地爬起来,打开手机,发现刚事情的老学长阿威给我发来了一条信息:

   "阿森,来活了,帮我搞个网站,会弄吗?"

   "网站?没弄过诶。。"

     "这个项目给的银两还挺多的。。"

   "可以,可以,这个可以搞,没问题,阿威哥"

     

  就这样,我就走上了Web开发的门路。初入坑,首先遇到的问题就是数据库的操作,然则经由自己的旁门左道的学习也大致摸清了使用ADO.NET操作数据库的方式:

  第一步,使用DBConnection确立与数据库之间的毗邻,打开毗邻

  第二步,然后建立DBCommand工具,初始化你想要执行的SQL语句

  第三步,挪用DBCommand的方式,执行SQL语句

  第四步,使用DataReader逐条读取sql执行的效果,或者使用DataAdapter类将效果填充(Fill)到DataSet中,最后关闭Connection毗邻

  到此为止,就实现了在.net中操作数据库执行sql语句返回执行效果的操作。

  固然,我以为任何一个低级的程序员也都会给自己封装一个叫做SQLHelper的辅助类,我也不破例,它可以辅助你节约频仍简直立数据库毗邻(DBConnection)、初始化DBCommand工具、读取sql执行效果等重复的代码量。以是,封装一个自己的SQLHelper工具类是一个低级程序员必备的素质。

  我把一个当初自己封装的SQLHelper类贴出来献献丑:

   
  1     public static class SqlServerHelper
  2     {
  3         //数据库毗邻字符串,从设置文件的设置字段中读取
  4         private static readonly string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
  5 
  6         /// <summary>
  7         /// 建立新的数据库毗邻
  8         /// </summary>
  9         public static SqlConnection CreateSqlConnection()
 10         {
 11             SqlConnection conn = new SqlConnection(connStr);
 12 
 13             conn.Open();   //打开数据库毗邻
 14 
 15             return conn;
 16         }
 17 
 18         /// <summary>
 19         /// 执行无效果返回的sql语句(共用同一个毗邻)
 20         /// </summary>
 21         /// <param name="sqlConn"></param>
 22         /// <param name="sqlStr"></param>
 23         /// <param name="sqlParamters"></param>
 24         /// <returns>返回受影响的数据总条数</returns>
 25         public static long ExecuteNoQuery(SqlConnection sqlConn, string sqlStr, params SqlParameter[] sqlParamters)
 26         {
 27             using (SqlCommand cmd = sqlConn.CreateCommand())
 28             {
 29                 cmd.CommandText = sqlStr;
 30                 cmd.Parameters.AddRange(sqlParamters);
 31 
 32                 long sum = cmd.ExecuteNonQuery();
 33 
 34                 return sum;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 执行无效果返回的sql语句(不共用一个毗邻)
 40         /// </summary>
 41         /// <param name="sqlStr"></param>
 42         /// <param name="sqlParamters"></param>
 43         /// <returns>返回受影响的数据总条数</returns>
 44         public static long ExecuteNoQuery(string sqlStr, params SqlParameter[] sqlParamters)
 45         {
 46             using (SqlConnection sqlConn = CreateSqlConnection())
 47             using (SqlCommand cmd = sqlConn.CreateCommand())
 48             {
 49                 cmd.CommandText = sqlStr;
 50                 cmd.Parameters.AddRange(sqlParamters);
 51 
 52                 long sum = cmd.ExecuteNonQuery();
 53 
 54                 return sum;
 55             }
 56         }
 57 
 58         /// <summary>
 59         /// 执行只有一行一列返回数据的sql语句(共用同一个毗邻)
 60         /// </summary>
 61         /// <param name="sqlConn"></param>
 62         /// <param name="sqlStr"></param>
 63         /// <param name="sqlParamters"></param>
 64         /// <returns>返回效果的第一行第一列数据</returns>
 65         public static object ExecuteScalar(SqlConnection sqlConn, string sqlStr, params SqlParameter[] sqlParamters)
 66         {
 67             using (SqlCommand cmd = sqlConn.CreateCommand())
 68             {
 69                 cmd.CommandText = sqlStr;
 70                 cmd.Parameters.AddRange(sqlParamters);
 71 
 72                 object res = cmd.ExecuteScalar();
 73 
 74                 return res;
 75             }
 76         }
 77 
 78         /// <summary>
 79         /// 执行只有一行一列返回数据的sql语句(不共用同一个毗邻)
 80         /// </summary>
 81         /// <param name="sqlStr"></param>
 82         /// <param name="sqlParamters"></param>
 83         /// <returns>返回效果的第一行第一列数据</returns>
 84         public static object ExecuteScalar(string sqlStr, params SqlParameter[] sqlParamters)
 85         {
 86             using (SqlConnection sqlConn = CreateSqlConnection())
 87             using (SqlCommand cmd = sqlConn.CreateCommand())
 88             {
 89                 cmd.CommandText = sqlStr;
 90                 cmd.Parameters.AddRange(sqlParamters);
 91 
 92                 object res = cmd.ExecuteScalar();
 93 
 94                 return res;
 95             }
 96         }
 97 
 98         /// <summary>
 99         /// 执行有查询效果的sql语句(共用同一个毗邻)
100         /// </summary>
101         /// <param name="sqlConn"></param>
102         /// <param name="sqlStr"></param>
103         /// <param name="sqlParamters"></param>
104         /// <returns></returns>
105         public static DataTable ExcuteQuery(SqlConnection sqlConn, string sqlStr, params SqlParameter[] sqlParamters)
106         {
107             using (SqlCommand cmd = sqlConn.CreateCommand())
108             {
109                 cmd.CommandText = sqlStr;
110 
111                 cmd.Parameters.AddRange(sqlParamters);
112 
113                 //把sql语句的执行效果填充到SqlDataAdapter中
114                 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
115 
116                 DataTable dt = new DataTable();
117                 adapter.Fill(dt);    //将执行效果填充到dt工具中
118 
119                 return dt;
120             }
121         }
122 
123         /// <summary>
124         /// 执行有查询效果的sql语句(共用同一个毗邻)
125         /// </summary>
126         /// <param name="sqlStr"></param>
127         /// <param name="sqlParamters"></param>
128         /// <returns></returns>
129         public static DataTable ExcuteQuery(string sqlStr, params SqlParameter[] sqlParamters)
130         {
131             using (SqlConnection sqlConn = CreateSqlConnection())
132             using (SqlCommand cmd = sqlConn.CreateCommand())
133             {
134                 cmd.CommandText = sqlStr;
135 
136                 cmd.Parameters.AddRange(sqlParamters);
137 
138                 //把sql语句的执行效果填充到SqlDataAdapter中
139                 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
140 
141                 DataTable dt = new DataTable();
142                 adapter.Fill(dt);    //将执行效果填充到dt工具中
143 
144                 return dt;
145             }
146         }
147 
148         /// <summary>
149         /// 批量插入数据到数据库
150         /// </summary>
151         /// <param name="insertTable"></param>
152         /// <param name="dataTableName"></param>
153         public static void BatchInsert(DataTable insertTable, string dataTableName)
154         {
155             using (SqlBulkCopy  *** c = new SqlBulkCopy(connStr))
156             {
157                  *** c.DestinationTableName = dataTableName;
158 
159                 for (int i = 0; i < insertTable.Columns.Count; i++ )
160                 {
161                      *** c.ColumnMappings.Add(insertTable.Columns[i].ColumnName, insertTable.Columns[i].ColumnName);
162                 }
163 
164                  *** c.WriteToServer(insertTable);
165             }
166         }
167 
168     }
SQLHelper

    于是在那段开发的岁月里,是这个SQLHelper类陪我走完了全程,向它说声辛苦了... 

 

二、EF框架真香,Lambda表达式我更爱

  大三暑假,由于抑制不住想要出去试一试的感动,我来到了一家小型互联网公司实习,公司也是用.net开发网站的手艺栈。

   当上岗的第一天,我准备掏出我自以为牛逼的SQLHelper的时刻,却被项目经理叫停了,项目经理阿勇对我说:

   “小伙子,21世纪了,还在傻傻地用SQLHelper?来,试试EF吧,让你欲罢不能...”

   于是,一脸懵逼的我,一头埋进了EF的天下中,不得不说,简直香。

   EF全名EntityFramework,是微软官方的一款ORM框架,支持Object(工具)与数据库之间的数据映射,支持Linq的操作语法,受宽大.NET程序员青睐。

   实在在接触EntityFramework之前我就使用过Dapper,Dapper相对与EF来说是轻量的多的一款ORM框架,近乎于原生sql的写法,让它处于性能之最,也提供工具与数据库表之间的映射。

   但正是由于用过了EF,我才知道了原来另有 Lambda to SQL 这种器械,信赖大多数程序员都和我一样经历过写原生SQL的痛苦

   无论是何等简朴的一条sql,你都要在表设计文档和sql编辑器中频频切换比对字段,生怕自己打错一个字母;而且我们在基础的营业中的大部分增删改查实在都是相当简朴的单表操作sql,正是使用了Lambda to SQL 的代码编写方式,你可以在VsStudio厚实的代码提醒下飞快地完成一条简朴的SQL语句。

   为什么说简朴的SQL编写才使用Lambda表达式的形式去编写呢,庞大的sql就不行了吗?

   理由是,你要明了不管是Lambda照样Linq的语句,最终都是在EF的SQL语句解析器中被翻译成可供数据库执行的sql语句,不得不说EF的Linq To SQL 的解析器简直壮大,然则究竟照样机器翻译的sql,当你让它给你转化一个庞大的linq语句时,它是一定思量不到sql性能的优化。

   就像你去用金山词霸翻译一个单词,它可以给你翻译的很准确;然则你让它去帮你翻译一个长句,可能你读着就以为别扭了;更有甚者把一篇论文粘贴复制到金山词霸里,那可能比你直接看英文原文还费劲,这是同样一个原理,有些器械照样需要人工来做,就好比优化sql语句。不能奢求什么都扔给Lambda和Linq,它帮我们做的已经足够多了。

   总之一句话,Lambda很香,但绝对不能替换SQL

 

三、所有都是存储历程,调试太难

  结业后的我来到了一家大型制造业企业从事IT行业,说的这么体面,实在照样一个苦逼敲代码的。

   上岗的第一天我就问旁边的程序媛,对,你没看错,是“媛”,不是“猿”,嘿嘿。想我代码生涯一年以来,第一次见这么多程序媛,低调低调,不要张扬,否则让隔邻的程序猿听到了会嫉妒的。

   

  “姐姐,我们这用EF吗?”

   “EF?是啥...”,姐姐一脸懵逼。。。

   “那你们用什么操作数据库啊?自己封装SQLHelper吗?”

   “用存储历程啊,都用了7、8年了”

   “哦,这样啊”,我心想,都用了7、8年了,这个姐姐是个狠人。

   入乡随俗,咱也不能坏了礼貌,那就照着用吧,存储历程以前用过几回,然则那是在sql的逻辑比较庞大的时刻才会写存储历程挪用的,要是所有的sql都放在存储历程内里去挪用的话,那就太繁琐了吧。

   经由一段时间的使用,证实我的挂念是对的。

   所有使用存储历程后,发现,就是一条简朴的Delete、Insert语句都要写在存储历程中,简直不要太贫苦。

   首先的问题就是,欠好编写,对于一个刚上手存储历程语法的程序员来说这简直就是灾难,现在的SQL编辑器没有语法提醒功效而造成异常欠好的代码编写体验,严重拖慢开发历程;

   更要命的是,太难调试!当你在c#代码中挪用完存储历程后,你发现程序平安无事地执行完,然则并没有获得你想要的效果,于是你找啊找,找啊找,最后,你只能嫌疑是不是存储历程有问题,然则运行历程中存储历程一点消息也没有啊,这就是使用存储历程更大的坏处,悄无声息地失足,完全不知道内里发生了什么,只能默默地把存储历程的参数记下,然后输入到sql的调试其中执行一遍才可以发现错误。

   然后你的项目经理跑过来问你昨天的代码敲完了吗,心累...

   于是,我对存储历程留下了异常欠好的印象。然则存储历程的利益是显而易见的:当你的营业逻辑用一条sql解决不了的时刻你会思量使用多条sql来配合完成查询,可是若是执行每一条sql语句都要与数据库确立毗邻然后再执行的话似乎有点繁琐不说,主要是重修数据库毗邻的历程也是需要时间与资源的,以是这个时刻存储历程就派上用场了,把你的sql都扔到存储历程内里去吧,何等令人心旷神怡的操作,这个时刻你就不要去想存储历程失足难找的问题了,由于你想要获得利便总要有点牺牲精神。

 

四、没有哪一种是完全适合自己的,若是有,那就是自己造的

  想要有Dapper的神速,又想要有EF中使用lambda表达式的便捷,然则二者似乎并不能兼得。

   Dapper虽然是效率之王,然则它没有EF中可以使用的便捷的lambda表达式;

   EF虽然可以使用便捷的lambda、linq语法,可是由于EF的太过壮大(EF还具有工具追踪的功效),让它显得稍微有点臃肿,属于重量级的ORM框架。

   于是我就在想,有没有一款轻量级的ORM,既有不低的执行效率,又有简朴适用的Lambda TO SQL?

   谜底固然是,有的,现在开源的国产sqlSuger、freeSql,触目皆是。然则,我就是想自己试试造轮子的感受,目的并不是说造出何等好的ORM框架去逾越他们,而是在这个历程中学到的器械和获得的历练是异常可观的。

 

   没办法,有观众说“裤子都脱了,就给我看这个?”,我决议照样先把藏的货先摆出来,也好有个交接...

   源码地址:https://gitee.com/xiaosen123/CoffeeSqlORM

   本文为作者原创,转载请注明出处:https://www.cnblogs.com/MaMaNongNong/p/12884871.html

,

欧博网址开户

www.chinadsn9.com欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、 *** 开户、电脑客户端下载、苹果安卓下载等业务。

allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博开户:“造轮运动”之 ORM框架系列(一)~谈谈我在现实营业中的增删改查

网友评论

  • (*)

最新评论

  • 联博 2020-11-11 00:01:21 回复

    AllbetGmaing电脑版下载欢迎进入AllbetGmaing电脑版下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。顶起来啊朋友们

    1
  • 环球UG注册 2020-11-19 00:01:24 回复

    欧博亚洲官网开户网址欢迎进入欧博亚洲官网开户网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。现已加入我的最爱

    2
  • AllbetGaming代理 2021-01-17 00:00:36 回复

    通告显示,刘颖川1995 年参加工作,历任广州科学城房地产开发有限公司工程技术部部门经理,保利(重庆)投资实业有限公司设计治理部部门副经理、副总经理、常务副总经理,保利(福建)房地产投资有限公司总经理,广东保利房地产开发有限公司总经理,河南保利发展有限公司董事长、河北保利房地产开发有限公司董事长、陕西保利房地产开发有限公司董事长、保利(甘肃)实业投资有限公司董事长。帅呆酷毙

    3

站点信息

  • 文章总数:1231
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1579
  • 评论总数:1247
  • 浏览总数:111231