SOD让你的旧代码焕发青春

  最近接手了一个旧的系统,各种陈旧的问题比较多,其中最棘手的就是操作数据库的部分,具体如下:

  1、核心库是一个最后修改时间为2008年的库,先不说有多陈旧,现在这个库只是一个DLL文件,没有源码,也已经没人知道里面都实现了些啥功能,就算你怀疑数据库读写有问题,也无法验证和调试,反编译出来的源码也没法用。

  2、这个库用的是System.Data.OracleClient操作Oracle,问题很明显,依赖于Oracle客户端,区分32位和64位,一旦客户的Oracle客户端出点问题,系统就歇菜了,而且部署起来也不方便。

  3、操作数据库用的全是拼写SQL语句,对我这种习惯了ORM的人,实在太痛苦了,而且对JSON和流数据的支持也不是很好,这两种数据都需要单独处理,无形中增加了操作数据库的次数。

  明确了问题,也就知道了最终想要达到的效果,具体如下:

  1、有源码,风险可控。

  2、不依赖于Oracle客户端,不区分32位和64位,这个其实Oracle官方已经提供了解决方案,就是ODP.NET,最新版本已经快可以达到前面两个要求,而且提供了NUGET包,引用简单。

  3、既要兼容旧有的DbHelper的操作方式,也要支持ORM的操作方式,一是因为原来代码量过大,不可能快速完全转到ORM,所以必须兼容旧有的操作方式,同时,ORM也是必须的,毕竟自己用着顺手。

  知道了自己想要什么,于是,我就开始找可以做到这个库,功夫不负有心人,最终我找到了深蓝医生的SOD,完全满足我的要求,具体如下:

  1、SOD完全开源,并提供使用指导。

  2、SOD支持最新版本的ODP.NET,并提供了NUGET的获取方式,相当方便。

  3、SOD不仅是一个ORM,还提供了DBHelper形式的数据库操作方式,不仅如此,更神奇的是,SOD支持执行SQL得到实体的操作方式,是不是很像Dapper.NET?

  4、SOD支持现在大部分主流的数据库,以后要换库也是无缝对接。

  5、客户反馈旧系统如果打开十几分钟没有操作,界面就会卡死,关了重新开,软件依然用不了,必须重启操作系统才能恢复正常,换了SOD之后,这个问题神奇的被修复了,看来真的是数据库读写有问题。不过也从侧面说明旧系统的异常处理和日志机制有些问题,这么严重的问题,既没有抛出异常,也没有记录日志,看来需要填的坑还是有一些的。

  说了这么多废话,还是要来点干货,把我写的兼容旧系统的基于SOD的DbHelper给大家看看,写的不好,还希望多多指教,最后总结一句:

  人生苦短,我用SOD,蜜!

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using Oracle.ManagedDataAccess.Client;
  5 using PWMIS.DataMap.Entity;
  6 using PWMIS.DataProvider.Adapter;
  7 using PWMIS.DataProvider.Data;
  8
  9 namespace Db
 10 {
 11     /// <summary>
 12     ///     数据库访问类
 13     /// </summary>
 14     public static class StaticDbHelper
 15     {
 16         private static AdoHelper _defaultDataBase;
 17
 18         /// <summary>
 19         ///     获取或者设置默认的数据库操作对象,如果未设置将采用默认的配置进行实例化数据库操作对象。
 20         ///     支持读写分离模式
 21         /// </summary>
 22         public static AdoHelper DefaultDataBase
 23         {
 24             get
 25             {
 26                 var dataConInfomation = new DcicDbConnInfo();
 27                 DcicComnLib.Sys_GetOracleSetting(ref dataConInfomation);
 28
 29                 return _defaultDataBase ??
 30                        MyDB.GetDBHelperByProviderString(
 31                            "PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient",
 32                            $"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={dataConInfomation.Ip})(PORT={dataConInfomation.Port}))                    (CONNECT_DATA=(SID={dataConInfomation.Sid})));User Id={dataConInfomation.UserId};Password={dataConInfomation.Pwd};");
 33             }
 34             set { _defaultDataBase = value; }
 35         }
 36
 37         #region ORM
 38
 39         /// <summary>
 40         ///     获取查询结果数量
 41         /// </summary>
 42         /// <param name="goql"></param>
 43         /// <returns></returns>
 44         public static int Count<T>(GOQL<T> goql) where T : EntityBase, new()
 45         {
 46             return goql.ToList(DefaultDataBase).Count;
 47         }
 48
 49         /// <summary>
 50         ///     判断是否存在查询结果
 51         /// </summary>
 52         /// <param name="goql"></param>
 53         /// <returns></returns>
 54         public static bool Exists<T>(GOQL<T> goql) where T : EntityBase, new()
 55         {
 56             var count = Count(goql);
 57             return count > 0;
 58         }
 59
 60         /// <summary>
 61         ///     增加一条记录
 62         /// </summary>
 63         /// <typeparam name="T"></typeparam>
 64         /// <param name="model"></param>
 65         /// <returns></returns>
 66         public static bool Insert<T>(T model) where T : EntityBase, new()
 67         {
 68             var query = new EntityQuery<T>(DefaultDataBase);
 69             var result = query.Insert(model);
 70
 71             return result == 1;
 72         }
 73
 74         /// <summary>
 75         ///     删除一条记录
 76         /// </summary>
 77         /// <typeparam name="T"></typeparam>
 78         /// <param name="model"></param>
 79         /// <returns></returns>
 80         public static bool Delete<T>(T model) where T : EntityBase, new()
 81         {
 82             var query = new EntityQuery<T>(DefaultDataBase);
 83             var result = query.Delete(model);
 84
 85             return result == 1;
 86         }
 87
 88         /// <summary>
 89         ///     更新一条记录
 90         /// </summary>
 91         /// <typeparam name="T"></typeparam>
 92         /// <param name="model"></param>
 93         /// <returns></returns>
 94         public static bool Update<T>(T model) where T : EntityBase, new()
 95         {
 96             var query = new EntityQuery<T>(DefaultDataBase);
 97             var result = query.Update(model);
 98
 99             return result == 1;
100         }
101
102         /// <summary>
103         ///     查询多条记录
104         /// </summary>
105         /// <typeparam name="T"></typeparam>
106         /// <param name="oql"></param>
107         /// <returns></returns>
108         public static List<T> QueryList<T>(GOQL<T> oql) where T : EntityBase, new()
109         {
110             return oql.ToList(DefaultDataBase);
111         }
112
113         /// <summary>
114         ///     查询一条记录
115         /// </summary>
116         /// <typeparam name="T"></typeparam>
117         /// <param name="oql"></param>
118         /// <returns></returns>
119         public static T QueryObject<T>(GOQL<T> oql) where T : EntityBase, new()
120         {
121             return oql.ToObject(DefaultDataBase);
122         }
123
124         #endregion
125
126         #region SQL TO ORM
127
128         /// <summary>
129         ///     查询多条记录
130         /// </summary>
131         /// <typeparam name="T"></typeparam>
132         /// <param name="sql"></param>
133         /// <returns></returns>
134         public static List<T> QueryList<T>(string sql) where T : EntityBase, new()
135         {
136             return EntityQuery<T>.QueryList(DefaultDataBase.ExecuteDataReader(sql));
137         }
138
139         /// <summary>
140         ///     查询一条记录
141         /// </summary>
142         /// <typeparam name="T"></typeparam>
143         /// <param name="sql"></param>
144         /// <returns></returns>
145         public static T QueryObject<T>(string sql) where T : EntityBase, new()
146         {
147             return EntityQuery<T>.QueryObject(DefaultDataBase.ExecuteDataReader(sql));
148         }
149
150         #endregion
151
152         #region SQL
153
154         /// <summary>
155         ///     获取DataTable
156         /// </summary>
157         /// <param name="sql"></param>
158         /// <returns></returns>
159         public static DataTable GetDataTable(string sql)
160         {
161             DataTable tableResult = null;
162             try
163             {
164                 tableResult = DefaultDataBase.ExecuteDataSet(sql).Tables[0];
165             }
166             catch
167             {
168                 // ignored
169             }
170             return tableResult;
171         }
172
173         /// <summary>
174         ///     获取查询结果数量
175         /// </summary>
176         /// <param name="sql"></param>
177         /// <returns></returns>
178         public static int GetCount(string sql)
179         {
180             var count = 0;
181             try
182             {
183                 var obj = DefaultDataBase.ExecuteScalar("select count(*) from ( " + sql + " )");
184                 count = Convert.ToInt32(obj);
185             }
186             catch
187             {
188                 // ignored
189             }
190             return count;
191         }
192
193         /// <summary>
194         ///     执行SQL语句
195         /// </summary>
196         /// <param name="sql"></param>
197         /// <returns></returns>
198         public static bool Execute(string sql)
199         {
200             try
201             {
202                 DefaultDataBase.ExecuteNonQuery(sql);
203                 return true;
204             }
205             catch
206             {
207                 return false;
208             }
209         }
210
211         /// <summary>
212         ///     判断是否存在查询结果
213         /// </summary>
214         /// <param name="sql"></param>
215         /// <returns></returns>
216         public static bool ExecuteCount(string sql)
217         {
218             var bok = false;
219             try
220             {
221                 var count = GetCount(sql);
222                 if (count > 0)
223                     bok = true;
224             }
225             catch
226             {
227                 // ignored
228             }
229
230             return bok;
231         }
232
233         /// <summary>
234         ///     返回数据表第一行、第一列的字段段值
235         /// </summary>
236         /// <param name="sql"></param>
237         /// <returns></returns>
238         public static string ExecuteString(string sql)
239         {
240             var result = "";
241             try
242             {
243                 result = (string)DefaultDataBase.ExecuteScalar(sql);
244             }
245             catch
246             {
247                 // ignored
248             }
249             return result;
250         }
251
252         /// <summary>
253         ///     保存Blob
254         /// </summary>
255         /// <param name="cmdSql"></param>
256         /// <param name="keyName"></param>
257         /// <param name="myBytes"></param>
258         public static void SetBlob(string cmdSql, string keyName, byte[] myBytes)
259         {
260             var p = new OracleParameter(keyName, OracleDbType.Blob);
261             p.Value = myBytes;
262             DefaultDataBase.ExecuteNonQuery(cmdSql, CommandType.Text, new IDataParameter[] { p });
263         }
264
265         /// <summary>
266         ///     获取Blob
267         /// </summary>
268         /// <param name="cmdSql"></param>
269         /// <returns></returns>
270         public static byte[] GetBlob(string cmdSql)
271         {
272             return (byte[])DefaultDataBase.ExecuteScalar(cmdSql);
273         }
274
275         #endregion
276     }
277 }
时间: 2024-10-21 19:45:44

SOD让你的旧代码焕发青春的相关文章

一种在旧代码上增加新需求的重构模式

应用场景 相信大家遇到过这种场景:旧代码中已经有一堆的if-else或者switch-case了:产品却要求在这段流程里增加一个新的功能. 这种时候大家会怎么做?我的建议是: 重构这段代码.在重构的基础上,加入新的功能. 肯定会有人说: 工期本来紧张,再对原有代码进行重构,岂不会更加捉襟见肘? 这里介绍的(也是我在实践中经常使用的)这种方式,我称之为"接口-分发器模式".它可以在尽量减少重构工作量的同时,完成大部分重构工作. 类图 接口-分发器类图 接口 这个模式首先将旧代码/功能抽取

【旧代码整理】Nodejs的另类用法

Nodejs 的中文维基百科介绍:https://zh.wikipedia.org/wiki/Node.js Nodejs 可以 在linux命令行执行js代码. 比如: var a = 1; var b = 2; var c = a + b; console.log(c+"\r"); 以上代码保存为 test.js 然后执行命令: [email protected]:~/# nodejs test.js 3 再看下面,用nodejs执行新浪微博登录加密密码的js:(这堆代码是别人整理

高效程序员系列(扔掉旧代码)

话不多说,直入正题. 大家都知道,程序员做的最多的事情就是调试代码.在代码编写完成后,为了保证代码的正确运行,必须进行大量的调试.其实写代码的过程就是一个不断调整.不断调试的过程,大多数情况下我们不能够一次写出正确运行的代码,需要反复进行测试.在我看来,在写出正确代码之前的一系列活动都算是调试.在调试的过程中,我们会写出许多代码,在进行下一测试的时候,我们通常会把之前的测试代码注释掉,没错,这是正确的做法,因为你不能保证这些代码在你之后的调试过程中不会被用到.但是,在调试完成后,这些代码应该怎么

修改代码运行的还是旧代码

Eclipse Junit Maven project:项目中对代码进行了修改,运行的结果还是修改代码之前的结果,感觉没有重新编译class文件,工具条中"Project>Build Automatically"是勾选上的, 在控制台使用mvn clean install(或者mvn clean指令) 清除class文件,再使用mvn test重新编译后,运行代码是修改后的结果(例如结果是A),但是再次修改代码运行的还是结果A,但是如果使用mvn clean和mvn test反复

如何快速熟悉公司的旧代码

---恢复内容开始--- 记录控制器对应的类 ppt   找应用程序的根控制器 AppDelegate 文件 int main

【转载】关于烂代码的那些事

http://kb.cnblogs.com/page/526768/ ============上篇============ 1. 摘要 最近写了不少代码,review了不少代码,也做了不少重构,总之是对着烂代码工作了几周.为了抒发一下这几周里好几次到达崩溃边缘的情绪,我决定写一篇文章谈一谈烂代码的那些事.这里是上篇,谈一谈烂代码产生的原因和现象. 2. 写烂代码很容易 刚入程序员这行的时候经常听到一个观点:你要把精力放在ABCD(需求文档/功能设计/架构设计/理解原理)上,写代码只是把想法翻译成

关于烂代码的那些事(上)

1. 摘要 最近写了不少代码,review了不少代码,也做了不少重构,总之是对着烂代码工作了几周.为了抒发一下这几周里好几次到达崩溃边缘的情绪,我决定写一篇文章谈一谈烂代码的那些事.这里是上篇,谈一谈烂代码产生的原因和现象. 2. 写烂代码很容易 刚入程序员这行的时候经常听到一个观点:你要把精力放在ABCD(需求文档/功能设计/架构设计/理解原理)上,写代码只是把想法翻译成编程语言而已,是一个没什么技术含量的事情. 当时的我在听到这种观点时会有一种近似于高冷的不屑:你们就是一群傻X,根本不懂代码

代码重构原则--很重要,供以后参阅

重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 新建一个方法 新建方法 把要抽取的代码,直接复制到新方法中 根据需求调整参数 调整旧代码 注释原代码,给自己一个后悔的机会 调用新方法 测试 优化代码 在原有位置,因为要照顾更多的逻辑,代码有可能是合理的 而抽取之后,因为代码少了,可以检查是否能够优化 分支嵌套多,不仅执行性能会差,而且不易于阅读 测试 修改注释 在开发中,注释

HTTP.SYS远程执行代码漏洞分析

社区:i春秋 时间:2016年8月10日 作者:MAX丶 大家肯定用过bugscan老板裤子里面经常出现这个漏洞提示. [xxx存在http.sys远程漏洞]今天我们来分析分析这漏洞如何存在的, 据称,利用HTTP.sys的安全漏洞,攻击者只需要发送恶意的http请求数据包,就可能远程读取IIS服务器的内存数据,或使服务器系统蓝屏崩溃. 根据公告显示,该漏洞对服务器系统造成了不小的影响,主要影响了包括Windows 7.Windows Server 2008 R2.Windows 8.Windo