DBHelper (支持事務與資料庫變更)

来源:http://www.cnblogs.com/androidshouce/archive/2016/07/14/5669025.html
-Advertisement-
Play Games

1 概述 更新內容:添加 "支持數據分頁" 這個資料庫操作類的主要特色有 1> 事務操作更加的方便 2> 變更資料庫更加的容易 3> 支持數據分頁 <!--[if gte mso 9]><xml> <o:OfficeDocumentSettings> <o:AllowPNG/> </o:Office ...


1   概述

更新內容:添加 "支持數據分頁"

這個資料庫操作類的主要特色有

1>     事務操作更加的方便

2>     變更資料庫更加的容易

3>   支持數據分頁

最新的所有代碼:

using System;
using System.Data;
using System.Data.Common;
using Project.BaseFramework;
using System.Collections.Generic;
using System.Configuration;

namespace Project.BaseFramework.DataProvider
{
    public class DBHelper
    {

        #region Constuctor
        public DBHelper() { }

        private static string ConnectionString = ConfigurationManager.AppSettings["DBConnectionString"];

        private static IDBClient DBClient = DBClientFactory.GetDBClient(ConfigurationManager.AppSettings["DBClient"]);

        [ThreadStatic]
        private static TransConnection TransConnectionObj = null;

        #endregion

        #region ExecuteNonQuery
        public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
        {
            int result = 0;
            bool mustCloseConn = true;

            DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
            OpenConn(cmd.Connection);
            result = cmd.ExecuteNonQuery();

            if (mustCloseConn) CloseConn(cmd.Connection);
            ClearCmdParameters(cmd);
            cmd.Dispose();

            return result;
        }

        #endregion ExecuteNonQuery

        #region ExecuteScalar
        public static object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
        {
            object result = 0;
            bool mustCloseConn = true;

            DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
            OpenConn(cmd.Connection);
            result = cmd.ExecuteScalar();

            if (mustCloseConn) CloseConn(cmd.Connection);
            ClearCmdParameters(cmd);
            cmd.Dispose();

            return result;
        }
        #endregion ExecuteScalar

        #region ExecuteReader
        public static DbDataReader ExecuteReader(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
        {
            DbDataReader result = null;
            bool mustCloseConn = true;
            DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
            try
            {
                OpenConn(cmd.Connection);
                if (mustCloseConn)
                {
                    result = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
                else
                {
                    result = cmd.ExecuteReader();
                }
                ClearCmdParameters(cmd);
                return result;
            }
            catch (Exception ex)
            {
                if (mustCloseConn) CloseConn(cmd.Connection);
                ClearCmdParameters(cmd);
                cmd.Dispose();
                throw ;
            }
        }
        #endregion ExecuteReader

        #region ExecuteDataset
        public static DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
        {
            DataSet result = null;
            bool mustCloseConn = true;

            DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
            using (DbDataAdapter da = DBClient.GetDbDataAdappter())
            {
                da.SelectCommand = cmd;
                result = new DataSet();

                da.Fill(result);
            }

            if (mustCloseConn) CloseConn(cmd.Connection);
            ClearCmdParameters(cmd);
            cmd.Dispose();

            return result;
        }
        #endregion ExecuteDataset

        #region ExecuteDataTable
        public static DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] parameterValues) 
        {
            DataSet ds = ExecuteDataSet(cmdType,cmdText, parameterValues);
            if (ds != null && ds.Tables.Count > 0)
                return ds.Tables[0];
            else
                return null;
        }
        #endregion

        #region ExecutePaging
        public static DataTable ExecutePagingDataTable(CommandType cmdType, string cmdText,int pageIndex,int pageSize,string orderInfo, params DbParameter[] parameterValues)
        {
            cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
            return ExecuteDataTable(CommandType.Text, cmdText, parameterValues);
        }

        public static DbDataReader ExecutePagingReader(CommandType cmdType, string cmdText, int pageIndex, int pageSize, string orderInfo, params DbParameter[] parameterValues)
        {
            cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
            return ExecuteReader(CommandType.Text, cmdText, parameterValues);
        }
        #endregion

        #region Transaction
        public static void BeginTransaction()
        {
            if (TransConnectionObj == null) 
            {
                DbConnection conn = DBClient.GetDbConnection(ConnectionString);
                OpenConn(conn);
                DbTransaction trans = conn.BeginTransaction();
                TransConnectionObj = new TransConnection();
                TransConnectionObj.DBTransaction = trans;
            }
            else 
            {
                TransConnectionObj.Deeps += 1;
            }
        }

        public static void CommitTransaction()
        {
            if (TransConnectionObj == null) return;
            if (TransConnectionObj.Deeps > 0)
            {
                TransConnectionObj.Deeps -= 1;
            }
            else
            {
                TransConnectionObj.DBTransaction.Commit();
                ReleaseTransaction();
            }
        }

        public static void RollbackTransaction()
        {
            if (TransConnectionObj == null) return;
            if (TransConnectionObj.Deeps > 0)
            {
                TransConnectionObj.Deeps -= 1;
            }
            else
            {
                TransConnectionObj.DBTransaction.Rollback();
                ReleaseTransaction();
            }
        }

        private static void ReleaseTransaction()
        {
            if (TransConnectionObj == null) return;
            DbConnection conn = TransConnectionObj.DBTransaction.Connection;
            TransConnectionObj.DBTransaction.Dispose();
            TransConnectionObj = null;
            CloseConn(conn);
        }

        #endregion

        #region Connection
        private static void OpenConn(DbConnection conn)
        {
            if (conn == null) conn = DBClient.GetDbConnection(ConnectionString);
            if (conn.State == ConnectionState.Closed) conn.Open();
        }

        private static void CloseConn(DbConnection conn)
        {
            if (conn == null) return;
            if (conn.State == ConnectionState.Open) conn.Close();
            conn.Dispose();
            conn = null;
        }
        #endregion

        #region Create DbParameter

        public static DbParameter CreateInDbParameter(string paraName, DbType type, int size, object value)
        {
            return CreateDbParameter(paraName, type, size, value, ParameterDirection.Input);
        }

        public static DbParameter CreateInDbParameter(string paraName, DbType type, object value)
        {
            return CreateDbParameter(paraName, type, 0, value, ParameterDirection.Input);
        }

        public static DbParameter CreateOutDbParameter(string paraName, DbType type, int size)
        {
            return CreateDbParameter(paraName, type, size, null, ParameterDirection.Output);
        }

        public static DbParameter CreateOutDbParameter(string paraName, DbType type)
        {
            return CreateDbParameter(paraName, type, 0, null, ParameterDirection.Output);
        }

        public static DbParameter CreateReturnDbParameter(string paraName, DbType type, int size)
        {
            return CreateDbParameter(paraName, type, size, null, ParameterDirection.ReturnValue);
        }

        public static DbParameter CreateReturnDbParameter(string paraName, DbType type)
        {
            return CreateDbParameter(paraName, type, 0, null, ParameterDirection.ReturnValue);
        }

        public static DbParameter CreateDbParameter(string paraName, DbType type, int size, object value, ParameterDirection direction)
        {
            DbParameter para = DBClient.GetDbParameter();
            
            para.ParameterName = paraName;

            if (size != 0)
            {
                para.Size = size;
            }

            para.DbType = type;

            if (value != null)
            {
                para.Value = value;
            }
            else
            {
                para.Value = DBNull.Value;
            }

            para.Direction = direction;

            return para;
        }

        #endregion

        #region Command and Parameter
        /// <summary>
        /// 預處理用戶提供的命令,資料庫連接/事務/命令類型/參數
        /// </summary>
        /// <param>要處理的DbCommand</param>
        /// <param>資料庫連接</param>
        /// <param>一個有效的事務或者是null值</param>
        /// <param>命令類型 (存儲過程,命令文本, 其它.)</param>
        /// <param>存儲過程名或都T-SQL命令文本</param>
        /// <param>和命令相關聯的DbParameter參數數組,如果沒有參數為'null'</param>
        /// <param><c>true</c> 如果連接是打開的,則為true,其它情況下為false.</param>
        private static DbCommand PrepareCmd(CommandType cmdType,string cmdText, DbParameter[] cmdParams, out bool mustCloseConn)
        {
            DbCommand cmd = DBClient.GetDbCommand(cmdText);

            DbConnection conn = null;
            if (TransConnectionObj != null)
            {
                conn = TransConnectionObj.DBTransaction.Connection;
                cmd.Transaction = TransConnectionObj.DBTransaction;
                mustCloseConn = false;
            }
            else
            {
                conn = DBClient.GetDbConnection(ConnectionString);
                mustCloseConn = true;
            }
            cmd.Connection = conn;

            cmd.CommandType = cmdType;

            AttachParameters(cmd, cmdParams);

            return cmd;
        }

        /// <summary>
        /// 將DbParameter參數數組(參數值)分配給DbCommand命令.
        /// 這個方法將給任何一個參數分配DBNull.Value;
        /// 該操作將阻止預設值的使用.
        /// </summary>
        /// <param>命令名</param>
        /// <param>SqlParameters數組</param>
        private static void AttachParameters(DbCommand command, DbParameter[] commandParameters)
        {
            if (command == null) throw new ArgumentNullException("command");
            if (commandParameters != null)
            {
                foreach (DbParameter p in commandParameters)
                {
                    if (p != null)
                    {
                        // 檢查未分配值的輸出參數,將其分配以DBNull.Value.
                        if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) &&
                        (p.Value == null))
                        {
                            p.Value = DBNull.Value;
                        }
                        command.Parameters.Add(p);
                    }
                }
            }
        }

        private static void ClearCmdParameters(DbCommand cmd)
        {
            bool canClear = true;
            if (cmd.Connection != null && cmd.Connection.State != ConnectionState.Open)
            {
                foreach (DbParameter commandParameter in cmd.Parameters)
                {
                    if (commandParameter.Direction != ParameterDirection.Input)
                    {
                        canClear = false;
                        break;
                    }
                }
            }
            if (canClear)
            {
                cmd.Parameters.Clear();
            }
        }
        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;

namespace Project.BaseFramework.DataProvider
{
    internal class TransConnection
    {
        public TransConnection()
        {
            this.Deeps = 0;
        }

        public DbTransaction DBTransaction { get; set; }

        public int Deeps { get; set; }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient;

namespace Project.BaseFramework.DataProvider
{
    public interface IDBClient
    {
        DbConnection GetDbConnection(string connectionString);

        DbCommand GetDbCommand(string cmdText);

        DbDataAdapter GetDbDataAdappter();

        DbParameter GetDbParameter();

        string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo);
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient;

namespace Project.BaseFramework.DataProvider
{
    public class SqlServerClient:IDBClient
    {
        public DbConnection GetDbConnection(string connectionString)
        {
            return new SqlConnection(connectionString);
        }

        public DbCommand GetDbCommand(string cmdText)
        {
            return new SqlCommand(cmdText);
        }

        public DbDataAdapter GetDbDataAdappter()
        {
            return new SqlDataAdapter();
        }

        public DbParameter GetDbParameter()
        {
            return new SqlParameter();
        }

        public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo) 
        {
            int startIndex = (pageIndex - 1) * pageSize;
            int endIndex = startIndex + pageSize + 1;
            cmdText = string.Format(@";WITH T1 AS({0}),T2 AS(SELECT *,ROW_NUMBER()OVER ({1}) AS _RowNum FROM T1)
                                       SELECT *FROM T2
                                       WHERE _RowNum>{2} AND _RowNum<{3}",cmdText,orderInfo,startIndex,endIndex);
            return cmdText;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using MySql.Data.MySqlClient;

namespace Project.BaseFramework.DataProvider
{
    public class MySqlClient:IDBClient
    {
        public DbConnection GetDbConnection(string connectionString)
        {
            return new MySqlConnection(connectionString);
        }

        public DbCommand GetDbCommand(string cmdText)
        {
            return new MySqlCommand(cmdText);
        }

        public DbDataAdapter GetDbDataAdappter()
        {
            return new MySqlDataAdapter();
        }

        public DbParameter GetDbParameter()
        {
            return new MySqlParameter();
        }

        public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo)
        {
            int startIndex = (pageIndex - 1) * pageSize;
            cmdText = string.Format(@"{0} {1} Limit {2}, {3}", cmdText, orderInfo, startIndex,pageSize);
            return cmdText;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Reflection;

namespace Project.BaseFramework.DataProvider
{
    public class DBClientFactory
    {
        private static readonly string path = "Project.BaseFramework";

        public static IDBClient GetDBClient(string dbClientClassName) 
        {
            if(string.IsNullOrEmpty(dbClientClassName))
                dbClientClassName="SqlServerClient";
            string className = string.Format("{0}.DataProvider.{1}", path, dbClientClassName);
            return (IDBClient)Assembly.Load(path).CreateInstance(className);
        }
    }
}
View Code

配置文件

<appSettings>
    <add key="DBConnectionString" value="Data Source=.;Initial Catalog=ProjectData;Persist Security Info=True;User ID=sa;Password=kjkj,911;"/>
    <add key="DBClient" value="SqlServerClient"/>
</appSettings>

 

 

2  事務操作

2.1 單個事務操作示例

複製代碼
try
{
    DBHelper.BeginTransaction();
    // add 
    DBHelper.ExecuteNonQuery(CommandType.Text, "INSERT INTO TRole(ID,RoleName) VALUES('R1','MKT')");

    //detele by pk
    DBHelper.ExecuteNonQuery(CommandType.Text, "DELETE FROM TRole WHERE ID='R1'");

    Console.WriteLine(string.Format("Success and Commited"));
    DBHelper.CommitTransaction();
}
catch (Exception ex)
{
    Console.WriteLine(string.Format("Exception and rollback"));
    DBHelper.RollbackTransaction();
}
複製代碼

 

用法是:只需要把相關聯的代碼放在BeginTransaction和CommitTransaction中間,如果發生異常調用RollbackTransaction即可。

實現事務的方法是:

首先,DBHelper維護一個TransConnection類型的欄位,並添加ThreadStatic. ThreadStatic可以維護線上程級別上的唯一性。

[ThreadStatic]
private static TransConnection TransConnectionObj = null;

 

其次,TransConnection的作用是保存事務,並記錄嵌套事務的嵌套級別。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近看書比較多,正好對過去幾年的軟體開發做個總結。寫這個的初衷只是為了簡單的做一些記錄。 前言 複雜的應用程式總是面臨很多的頁面之間的數據交互,怎樣創建松耦合的程式一直是多數工程師所思考的問題。諸如依賴註入,PubSub模式,MVVM等概念,都致力於幫助我們創建更加松耦合易於維護的程式,也有不少框架 ...
  • 模擬Visual Studio中的完全匹配查找 轉載請註明出處:http://www.cnblogs.com/jzblogs/p/5670397.html ...
  • 1,document.getElementById getElementById是通過Id來設置/返回HTML標簽的屬性及調用其事件與方法。用這個方法基本上可以控制頁面所有標簽,條件很簡單,就是給每個標簽分配一個ID號。返回具有指定ID屬性值的第一個對象的一個引用。 語法: var inTag = ...
  • 第一步:購買功能變數名稱、伺服器、DNS解析這裡我們是在準備做一個網站的原材料,這三樣缺一不可。目前來說,可以租用的虛擬伺服器的商家很多,像亞馬遜、騰訊、阿裡等,當然,你也可以去找國外的一些免費的伺服器來用。實際一點來說,亞馬遜的伺服器你在成功註冊後有一年的試用期,這個倒是挺不錯的,不過他需要國外的一個信用... ...
  • 原文地址:http://docode.top/Article/Detail/10003 目錄: 1、.Net(C#)平臺下Des加密解密源代碼 2、.Net(C#)平臺下Aes加密解密源代碼 3、.Net(C#)平臺下Sha1加密解密源代碼 4、.Net(C#)平臺下MD5加密解密源代碼 5、總結 ...
  • webapi問世已久,稀里糊塗的人哪它都當mvc來使,畢竟已mvc使用級別的經驗就可以應對webapi。 webapi和mvc在asp.net5時代合體了,這告訴我們,其實 它倆還是有區別的,要不現在也不會取兩個名字,但是由於本人歸納總結能力較差,各種不同也無法一一列出了。 在webapi中 Hel ...
  • FileResult是一個基於文件的ActionResult,利用FileResult我們可以很容易地將從某個物理文件的內容響應給客戶端。ASP.NET MVC定義了三個具體的FileResult,分別是FileContentResult、FilePathResult和FileStreamResul ...
  • 背水一戰 Windows 10 之 MVVM(Model-View-ViewModel): 通過 Binding 或 x:Bind 結合 Command 實現,通過 ButtonBase 觸發命令 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...