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

  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@GIThttp://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让你的旧代码焕发青春的更多相关文章

  1. ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换

    /*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...

  2. [实用指南]如何使您的旧代码库(遗留代码)符合MISRA C 2012编码规范?

    重用旧代码是现实,但是在安全关键型软件项目中重用旧代码并实现MISRA C 2012的完全合规性是艰巨的任务. 最初的MISRA原则是为了在开发代码时应用而创建的,即使文档本身也有警告: " ...

  3. 请注意更新TensorFlow 2.0的旧代码

    TensorFlow 2.0 将包含许多 API 变更,例如,对参数进行重新排序.重新命名符号和更改参数的默认值.手动执行所有这些变更不仅枯燥乏味,而且容易出错.为简化变更过程并让您尽可能顺畅地过渡到 ...

  4. VS重新生成后仍然执行旧代码

    主要可能有以下三种情况: 1,生成的代码放错位置了,在iis中浏览打开网站目录,确保路径正确,不要自以为是. 2,页面和动态库不匹配,都要更新. 3,清除浏览器的缓存.

  5. 迁移32位下的旧代码到64位sever遇到过的两个很诡异的问题

    一个是GetHashCode,这个方法是返回一个int值,在32位系统里,都是正值,但在64位系统里会返回负值. 另一个问题是DataTable的Sort属性,在没有显示写明升序或降序的情况下,在32 ...

  6. .NET ORM 的 “SOD蜜”--零基础入门篇

    PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...

  7. iOS 代码规范

    1 目的 统一规范XCode编辑环境下Objective-C.swift的编码风格和标准 2 适用范围 适用于所有用Objective-C,swift语言开发的项目. 3 编码规范 3.1 文件 项目 ...

  8. ReactiveCocoa代码实践之-RAC网络请求重构

    前言 RAC相比以往的开发模式主要有以下优点:提供了统一的消息传递机制:提供了多种奇妙且高效的信号操作方法:配合MVVM设计模式和RAC宏绑定减少多端依赖. RAC的理论知识非常深厚,包含有FRP,高 ...

  9. CSS代码重构与优化之路

    作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...

随机推荐

  1. 创建虚拟目录失败,必须为服务器名称指定“localhost”?看进来!!

    没废话,直接讲! 关于微信开发过程,远程调试后,再次打开vs出现项目加载失败的解决办法! 上图: 这图应该不陌生,你肯定打开iis把绑定的域名给干掉了.这个提示很坑人,简直就是坑爹!!!fck!! 来 ...

  2. xampp与Hbuilder、phpstorm配置

    1.xampp的安装就不用多说了,安装完按之后出现这个界面. 2.点击中间那个按钮,运行三个选项,全部正常之后是这样的,这样xampp就不用管了,但是要记下安装的路径,之后需要用 3.首先说Hbuil ...

  3. Scala 变长参数

    如果Scala定义变长参数 def sum(i Int*), 那么调用sum时,可以直接输入sum(1,2,3,4,5) 但是不可以sum(1 to 5) 必须要将1 to 5 强制为seq sum( ...

  4. Java Web之网上购物系统(注册、登录、浏览商品、添加购物车)

    眼看就要期末了,我的专业课也迎来了第二次的期末作业---------<网上购物系统>.虽然老师的意图是在锻炼我们后台的能力,但是想着还是不利用网上的模板,准备自己写,以来别人写的静态页看不 ...

  5. Android面试题--事件处理

    1.Handler 机制 Android 中主线程也叫 UI 线程,那么从名字上我们也知道主线程主要是用来创建.更新 UI 的,而其他耗时操作,比如网络访问,或者文件处理,多媒体处理等都需要在子线程中 ...

  6. iOS开发常用快捷键

    二. Xcode基本快捷键 新建项目 Shift + CMD + N 项目中新建文件 CMD + N 运行 CMD + R 编译 CMD + B 停止运行 CMD + . 清除缓存 Shift + C ...

  7. Java之递归求和的两张方法

    方法一: package com.smbea.demo; public class Student { private int sum = 0; /** * 递归求和 * @param num */ ...

  8. 机器学习实战笔记(Python实现)-08-线性回归

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  9. php使用microtime(true)查看代码执行时间

    microtime() 函数返回当前 Unix 时间戳和微秒数. 如果带个 true 参数, 返回的将是一个浮点类型 round() 取出小数点后 3 位 $t1 = microtime(true); ...

  10. 初见SpringMVC

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...