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,蜜!
SOD源码地址:
OSC@GIT:http://git.oschina.net/dxzyx/SOD
Codeplex:http://pwmis.codeplex.com/SourceControl/latest
GITHUB:https://github.com/znlgis/PDF.NET-SOD
NUGET地址:https://www.nuget.org/profiles/znlgis
using System.Collections.Generic;
using PWMIS.DataMap.Entity;
using PWMIS.DataProvider.Adapter;
using PWMIS.DataProvider.Data; namespace ComnLib
{
/// <summary>
/// 数据库访问类
/// </summary>
public class DbHelper
{
#region 静态部分 private static AdoHelper _instance;
/// <summary>
/// 获取或者设置默认的数据库操作对象,如果未设置将采用默认的配置进行实例化数据库操作对象。
/// 支持读写分离模式
/// </summary>
public static AdoHelper Instance
{
get
{
if (_instance == null)
{
var dataConInfomation = new DcicDbConnInfo();
DcicComnLib.Sys_GetOracleSetting(ref dataConInfomation); _instance =
MyDB.GetDBHelperByProviderString(
"PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient",
$"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={dataConInfomation.Ip})(PORT={dataConInfomation.Port}))(CONNECT_DATA=(SID={dataConInfomation.Sid})));User Id={dataConInfomation.UserId};Password={dataConInfomation.Pwd};");
} return _instance;
}
} /// <summary>
/// 增加一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static bool Insert<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Insert(model); return result == ;
} /// <summary>
/// 执行一个无返回值的OQL语句
/// </summary>
/// <param name="oql"></param>
/// <returns></returns>
public static bool ExecuteOql(OQL oql)
{
var result = EntityQuery.ExecuteOql(oql, Instance);
return result == ;
} /// <summary>
/// 删除一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static bool Delete<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Delete(model); return result == ;
} /// <summary>
/// 更新一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static bool Update<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Update(model); return result == ;
} /// <summary>
/// 使用OQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(OQL oql) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
return query.GetList(oql);
} /// <summary>
/// 使用GOQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(GOQL<T> oql) where T : EntityBase, new()
{
return oql.ToList(Instance);
} /// <summary>
/// 使用OQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static T QueryObject<T>(OQL oql) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance); return query.GetObject(oql);
} /// <summary>
/// 使用GOQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static T QueryObject<T>(GOQL<T> oql) where T : EntityBase, new()
{
return oql.ToObject(Instance);
} /// <summary>
/// 使用SQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(string sql) where T : EntityBase, new()
{
return EntityQuery<T>.QueryList(Instance.ExecuteDataReader(sql));
} /// <summary>
/// 使用SQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <returns></returns>
public static T QueryObject<T>(string sql) where T : EntityBase, new()
{
return EntityQuery<T>.QueryObject(Instance.ExecuteDataReader(sql));
} /// <summary>
/// 用于复杂查询的映射
/// </summary>
/// <param name="sql"></param>
/// <returns>实体数据容器</returns>
public static DataReaderMapper QueryMapper(string sql)
{
return Instance.ExecuteMapper(sql);
} #endregion #region 动态部分 /// <summary>
/// 获取各种数据库的DbHelper
/// </summary>
/// <param name="providerName"></param>
/// <param name="connectionString"></param>
/// <returns></returns>
public AdoHelper GetHelper(string providerName, string connectionString)
{
return MyDB.GetDBHelperByProviderString(providerName,
connectionString);
} /// <summary>
/// 获取Oracle数据库的DbHelper
/// </summary>
/// <param name="dataConInfomation"></param>
/// <returns></returns>
public AdoHelper GetHelper(DcicDbConnInfo dataConInfomation)
{
return MyDB.GetDBHelperByProviderString(
"PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient",
$"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={dataConInfomation.Ip})(PORT={dataConInfomation.Port}))(CONNECT_DATA=(SID={dataConInfomation.Sid})));User Id={dataConInfomation.UserId};Password={dataConInfomation.Pwd};");
} /// <summary>
/// 增加一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Insert<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Insert(model); return result == ;
} /// <summary>
/// 执行一个无返回值的OQL语句
/// </summary>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool ExecuteOql(OQL oql, AdoHelper db)
{
var result = EntityQuery.ExecuteOql(oql, db); return result == ;
} /// <summary>
/// 删除一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Delete<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Delete(model); return result == ;
} /// <summary>
/// 更新一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Update<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Update(model); return result == ;
} /// <summary>
/// 用GOQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(GOQL<T> oql, AdoHelper db) where T : EntityBase, new()
{
return oql.ToList(db);
} /// <summary>
/// 用GOQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(GOQL<T> oql, AdoHelper db) where T : EntityBase, new()
{
return oql.ToObject(db);
} /// <summary>
/// 用OQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(OQL oql, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
return query.GetList(oql);
} /// <summary>
/// 用OQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(OQL oql, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
return query.GetObject(oql);
} /// <summary>
/// 用SQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(string sql, AdoHelper db) where T : EntityBase, new()
{
return EntityQuery<T>.QueryList(db.ExecuteDataReader(sql));
} /// <summary>
/// 用SQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(string sql, AdoHelper db) where T : EntityBase, new()
{
return EntityQuery<T>.QueryObject(db.ExecuteDataReader(sql));
} /// <summary>
/// 用于复杂查询的映射
/// </summary>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns>实体数据容器</returns>
public DataReaderMapper QueryMapper(string sql, AdoHelper db)
{
return db.ExecuteMapper(sql);
} #endregion
}
}
SOD让你的旧代码焕发青春的更多相关文章
- ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换
/*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...
- [实用指南]如何使您的旧代码库(遗留代码)符合MISRA C 2012编码规范?
重用旧代码是现实,但是在安全关键型软件项目中重用旧代码并实现MISRA C 2012的完全合规性是艰巨的任务. 最初的MISRA原则是为了在开发代码时应用而创建的,即使文档本身也有警告: " ...
- 请注意更新TensorFlow 2.0的旧代码
TensorFlow 2.0 将包含许多 API 变更,例如,对参数进行重新排序.重新命名符号和更改参数的默认值.手动执行所有这些变更不仅枯燥乏味,而且容易出错.为简化变更过程并让您尽可能顺畅地过渡到 ...
- VS重新生成后仍然执行旧代码
主要可能有以下三种情况: 1,生成的代码放错位置了,在iis中浏览打开网站目录,确保路径正确,不要自以为是. 2,页面和动态库不匹配,都要更新. 3,清除浏览器的缓存.
- 迁移32位下的旧代码到64位sever遇到过的两个很诡异的问题
一个是GetHashCode,这个方法是返回一个int值,在32位系统里,都是正值,但在64位系统里会返回负值. 另一个问题是DataTable的Sort属性,在没有显示写明升序或降序的情况下,在32 ...
- .NET ORM 的 “SOD蜜”--零基础入门篇
PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...
- iOS 代码规范
1 目的 统一规范XCode编辑环境下Objective-C.swift的编码风格和标准 2 适用范围 适用于所有用Objective-C,swift语言开发的项目. 3 编码规范 3.1 文件 项目 ...
- ReactiveCocoa代码实践之-RAC网络请求重构
前言 RAC相比以往的开发模式主要有以下优点:提供了统一的消息传递机制:提供了多种奇妙且高效的信号操作方法:配合MVVM设计模式和RAC宏绑定减少多端依赖. RAC的理论知识非常深厚,包含有FRP,高 ...
- CSS代码重构与优化之路
作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...
随机推荐
- c++ builder TIdHttp 获取不到cookie
用c++ builder 的TIdHttp组件Get一个ASP.Net MVC服务器的一个页面,获取页面中Cookie信息,修改后Post到服务器上去. 在本地调试的时候可以获取到,部署到服务器上就获 ...
- C++01.类的引入
1.假设我们要输出张三,李四两个人的基本信息,包括姓名,年龄,可以用以下的C程序实现: eg: #include <stdio.h> int main(int argc,char **ar ...
- Oracle数据库的链接数目超标
测试场景:Oracle数据库的链接数目超标,iServer是否自动连接. 测试步骤:(1)设置了最大连接数为85,oracle后台进程有83:(2)开启3台iserver(A,B,C)A,B发布tes ...
- 写给自己:修改配置文件一定要cp一个.bak
写给自己:修改配置文件一定要cp一个.bak 毕竟不是每次的修改都一定对,而且很多时候是在服务器上直接修改原文件,修改后重启服务才知道是否修改正确,如果不加备份修改,造成服务器动荡,将会造成不可挽回的 ...
- JAVA Shallow heap & Retained heap
最近在研究内存泄漏的问题,在使用MAT工具中发现了Shallow heap & Retained heap,不懂. 然后在网上找了一些资料. Shallow Size 对象自身占用的内存大小, ...
- ios UIWebView自定义Alert风格的弹框
之前开发过一个App,因为公司之前写好了网页版的内容和安卓版本的App,我进去后老板要求我ios直接用网页的内容,而不需要自己再搭建框架.我一听,偷笑了,这不就是一个UIWebView吗?简单! 但是 ...
- 慎用 supportedRuntime
运行环境:win7, net4.5 现象: 无法连接SQL2012数据库,提示连接超时 原因: 真正的原因: 找微软去 解决的办法: 去除多余的supportedRuntime,或者修 ...
- GitLab CI持续集成配置方案
目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 GitLab持续集成所需环境 2.4 需要了解 ...
- GreenPlum高效去除表重复数据
1.针对PostgreSQL数据库表的去重复方法基本有三种,这是在网上查找的方法,在附录1给出.但是这些方法对GreenPlum来说都不管用. 2.数据表分布在不同的节点上,每个节点的ctid是唯一的 ...
- SQL*Plus环境下创建PLUSTRACE角色
普通用户在SQL*Plus中开启AUTOTRACE报告时,遇到SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is ...