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代码也会越来越多, ...
随机推荐
- yii框架安装心得
最近在学习yii框架, 现在将遇到的一些问题和解决方法写出来与大家分享. yii框架的安装: 下载yii框架之后, 打开文件运行init.bat文件, 如果闪退就打开php的扩展(php_openss ...
- 【笔记】LAMP 环境无脑安装配置 Centos 6.3
p.p1 { margin: 0.0px 0.0px 5.0px 0.0px; font: 12.0px Times; color: #ff2500 } p.p2 { margin: 0.0px 0. ...
- javascript实现键盘自动打字效果
最近在网上看到一个字符逐个出现的打字效果,觉得挺有趣的,想一想基本实现思路就是设置一个定时器逐然后逐个向容器中添加字符,于是就基于jQuery写了一个简单版的. <!DOCTYPE html&g ...
- delphi连接sql存储过程
针对返回结果为参数的 一. 先建立自己的存储过程 ALTER PROCEDURE [dbo].[REName] ) AS BEGIN select ROW_NUMBER() over(order by ...
- SVG Path高级教程
课程分为四个方面: 1. Path概述 2. 移动和直线命令 3. 弧线命令 4. 贝塞尔曲线命令 Path概述 <path> 标签用来定义路径,Path字符串是由命令及其参数组组成的字符 ...
- 数据可视化案例 | 如何打造数据中心APP产品
意识到数据探索带来的无尽信息,越来越多的企业开始建立自有的数据分析平台,打造数据化产品,实现数据可视化. 在零售商超行业,沃尔玛"啤酒与尿布"的故事已不再是传奇.无论是大数据还是小 ...
- Android Weekly Notes Issue #224
Android Weekly Issue #224 September 25th, 2016 Android Weekly Issue #224 本期内容包括: Google Play的pre-lau ...
- c#进阶之神奇的CSharp
CSharp 简写为c#,是一门非常年轻而又有活力的语言. CSharp的诞生 在2000年6月微软发布了c#这门新的语言.作为微软公司.NET 平台的主角,c#吸收了在他之前诞生的语言(c ...
- Installation error: INSTALL_FAILED_NO_MATCHING_ABIS
使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法 http://www.cnblogs.com/xiaobo-Linux/ 下载地址: ...
- 必杀技———SQL基础整理系列(一)
SQL(Structured Query Language)——结构化查询语言 SQL语言的组成部分 数据定义语言 (DDL:Data Definition Language) 负责数据结构定义与数据 ...