前言 混跡.Net圈子已經好幾年了, 從最初出來使用的SqlHelper 到 微軟的企業庫, 再到 EF, 再到第三方ORM框架, 經歷了一個不可描述的過程, SqlHelper和企業庫就不多說了. EF很強大, 但是.....(此處省去一萬字), 尋尋覓覓最後發現了幾個國內的ORM, 都使用過, ...
前言
混跡.Net圈子已經好幾年了, 從最初出來使用的SqlHelper 到 微軟的企業庫, 再到 EF, 再到第三方ORM框架, 經歷了一個不可描述的過程, SqlHelper和企業庫就不多說了. EF很強大, 但是.....(此處省去一萬字), 尋尋覓覓最後發現了幾個國內的ORM, 都使用過, 到最後停留在了SqlSugar. SqlSugar相對其它的ORM, 雖然起步較晚一點點, 但是功能卻是最強大的, 沒有之一, 至少我的使用過程中, 是這樣感覺的. 高性能, 強大的Lambda支持(Lambda的支持比Dos.ORM還要多, 這裡沒有貶低Dos.ORM的意思), 多庫支持(目前支持Sql Server & Oracle
& MySql & Sqlite), 支持.Net Core等等.(目前貌似支持.Net Core的ORM屈指可數, SqlSugar就是其中一個), 其它的, 可以自己去發現咯, 一句兩句說不清. 而且SqlSugar的更新和維護都是非常及時的, 詳細信息點我去官網
更多問題, 可加QQ群交流, QQ群號: 225982985
廢話不多說了, 進入正題
大神務噴, 適合新手看看
DEMO環境介紹
本系列博客才用的環境如下:
IDE: VS2017
JS環境: Vue 2.x
資料庫: SQL Server 2016
.Net環境: .Net Core 2.0
網站托管伺服器: IIS
操作系統: Windows 10 企業版
本系列博客不會對Core做過多的介紹, 只會一帶而過, Core技術需要另尋文檔和學習
我們先新建一個項目, 我已經新建好了, 大概目錄結構如下圖(後面的目錄結構會越來越多, 代碼在文章下方有提供下載, 循序漸近)
比較簡單, Web和邏輯層, 數據層我已經去掉了, 我認為用了ORM數據層存在的意義不是那麼必要了, 具體要不要, 你們自己選擇
項目建好之後, 在SqlSugarDemo.Busines安裝SqlSugar即可, 通過NuGet安裝, 如圖
如果你的項目是.Net的, 不是.Net Core, 安裝第一個即可
1. 我們在邏輯層新建一個SugarBase類, 用來提供ORM的DB訪問對象
代碼如下(此處為個人封裝, 技術有限, 僅供參考):
using System; using System.Data; namespace SqlSugarDemo.Busines.Base { using SqlSugar; /// <summary> /// Sugar ORM父類, 封裝一些基本的操作 /// </summary> public static class SugarBase { /// <summary> /// 資料庫鏈接字元串 /// </summary> public static string DB_ConnectionString { get; set; } /// <summary> /// 獲取ORM資料庫連接對象(只操作資料庫一次的使用, 否則會進行多次資料庫連接和關閉) /// 預設超時時間為30秒 /// 預設為SQL Server資料庫 /// 預設自動關閉資料庫鏈接, 多次操作資料庫請勿使用該屬性, 可能會造成性能問題 /// 要自定義請使用GetIntance()方法或者直接使用Exec方法, 傳委托 /// </summary> public static SqlSugarClient DB { get { return InitDB(30, DbType.SqlServer, true); } } /// <summary> /// 獲得SqlSugarClient(使用該方法, 預設請手動釋放資源, 如using(var db = SugarBase.GetIntance()){你的代碼}, 如果把isAutoCloseConnection參數設置為true, 則無需手動釋放, 會每次操作資料庫釋放一次, 可能會影響性能, 請自行判斷使用) /// </summary> /// <param name="commandTimeOut">等待超時時間, 預設為30秒 (單位: 秒)</param> /// <param name="dbType">資料庫類型, 預設為SQL Server</param> /// <param name="isAutoCloseConnection">是否自動關閉資料庫連接, 預設不是, 如果設置為true, 則會在每次操作完資料庫後, 即時關閉, 如果一個方法裡面多次操作了資料庫, 建議保持為false, 否則可能會引發性能問題</param> /// <returns></returns> public static SqlSugarClient GetIntance(int commandTimeOut = 30, DbType dbType = DbType.SqlServer, bool isAutoCloseConnection = false) { return SugarBase.InitDB(commandTimeOut, dbType, isAutoCloseConnection); } /// <summary> /// 初始化ORM連接對象 /// </summary> /// <param name="commandTimeOut">等待超時時間, 預設為30秒 (單位: 秒)</param> /// <param name="dbType">資料庫類型, 預設為SQL Server</param> /// <param name="isAutoCloseConnection">是否自動關閉資料庫連接, 預設不是, 如果設置為true, 則會在每次操作完資料庫後, 即時關閉, 如果一個方法裡面多次操作了資料庫, 建議保持為false, 否則可能會引發性能問題</param> private static SqlSugarClient InitDB(int commandTimeOut = 30, DbType dbType = DbType.SqlServer, bool isAutoCloseConnection = false) { var db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = SugarBase.DB_ConnectionString, DbType = dbType, InitKeyType = InitKeyType.Attribute, IsAutoCloseConnection = isAutoCloseConnection }); db.Ado.CommandTimeOut = commandTimeOut; return db; } /// <summary> /// 執行資料庫操作 /// </summary> /// <typeparam name="Result">返回值類型 泛型</typeparam> /// <param name="func">方法委托</param> /// <param name="commandTimeOut">超時時間, 單位為秒, 預設為30秒</param> /// <param name="dbType">資料庫類型, 預設為SQL Server</param> /// <returns>泛型返回值</returns> public static Result Exec<Result>(Func<SqlSugarClient, Result> func, int commandTimeOut = 30, DbType dbType = DbType.SqlServer) { if (func == null) throw new Exception("委托為null, 事務處理無意義"); using (var db = InitDB(commandTimeOut, dbType)) { try { return func(db); } catch (Exception ex) { throw ex; } finally { db.Dispose(); } } } /// <summary> /// 帶事務處理的執行資料庫操作 /// </summary> /// <typeparam name="Result">返回值類型 泛型</typeparam> /// <param name="func">方法委托</param> /// <param name="commandTimeOut">超時時間, 單位為秒, 預設為30秒</param> /// <param name="dbType">資料庫類型, 預設為SQL Server</param> /// <returns>泛型返回值</returns> public static Result ExecTran<Result>(Func<SqlSugarClient, Result> func, int commandTimeOut = 30, DbType dbType = DbType.SqlServer) { if (func == null) throw new Exception("委托為null, 事務處理無意義"); using (var db = InitDB(commandTimeOut, dbType)) { try { db.Ado.BeginTran(IsolationLevel.Unspecified); var result = func(db); db.Ado.CommitTran(); return result; } catch (Exception ex) { db.Ado.RollbackTran(); throw ex; } finally { db.Dispose(); } } } } }SugarBase
DB_ConnectionString資料庫連接字元串, 需要在MVC初始化的時候進行賦值, 也有別的方式,我偷懶了, 直接在MVC的Startup類賦值了,Startup代碼如下
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SqlSugarDemo.Busines.Base; namespace SqlSugarDemo.Web { public class Startup { readonly private IConfiguration _Configuration; public Startup(IConfiguration configuration) { this._Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); SugarBase.DB_ConnectionString = this._Configuration.GetConnectionString("Sugar"); //為資料庫連接字元串賦值 } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapRoute( name: "default1", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }Startup
資料庫配置信息寫在web的appsettings.json文件下麵, MVC會預設載入該json配置到記憶體中, 該JSON文件結構如下
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "ConnectionStrings": { "Sugar": "server=127.0.0.1;database=SqlSugarDemo;uid=sa;pwd=123456;" } }View Code
到了這一步ORM的DB對象提供基本上已經完成. 大家已經看到了, 我的DB提供對象有N個方法, 下麵依依通過代碼進行演示使用方法
2. 直接使用DB屬性操作資料庫 (此文章不會使用Lambda語法, 全部使用SQL進行DB對象使用說明, 下一篇詳細說增加的時候, 會使用實體層, 使用Lambda語法)
在邏輯層添加一個HomeManager類, 導入命名空間, 由於我使用的是VS2017, 所以可以直接導入靜態類
using static SqlSugarDemo.Busines.Base.SugarBase;
這樣就可以直接使用DB了, 而不用SugarBase.DB
添加方法, 使用DB屬性進行查詢, 資料庫結構下麵的代碼裡面可以下載
編寫 DBTest方法, 測試DB屬性
public bool DBTest() { return DB.Ado.ExecuteCommand("insert into TB_User values(@Name,@Gender,@Phone,@CreateDate)", new List<SugarParameter> { new SugarParameter("@Name", "Dos.Orm"), new SugarParameter("@Gender", false), new SugarParameter("@Phone", "18888888888"), new SugarParameter("@CreateDate", DateTime.Now) }) > 0; }DBTest
在控制裡面調用, 我使用了Lazy類, 調用代碼如下
/// <summary> /// 主頁 /// </summary> /// <returns></returns> [HttpGet] public IActionResult Index() { var result = this._HomeManager.Value.DBTest(); ViewBag.Result = result; return View(); }Index
我們運行程式, 界面顯示True, 執行成功, 資料庫成功多了一條數據
上面的例子簡單介紹了使用 DB屬性操作資料庫的方法, 使用還是很簡單的, 而且不必考慮是否需要釋放, 因為SqlSugar會自動處理, 如果你不想在使用完之後, 立即釋放, 我們的SugarBase有提供方法, 下麵介紹不自動釋放的方法使用
繼續在邏輯層編寫NotAutoDisposeTest方法, 代碼如下
/// <summary> /// 不自動釋放 /// </summary> /// <returns></returns> public bool NotAutoDisposeTest() { using(var db = GetIntance()) { var id = db.Ado.GetInt("Select ID from TB_User where Name = @Name", new SugarParameter("@Name", "SqlSugar")); var result = db.Ado.ExecuteCommand("update TB_User set Name = @Name where ID = @ID", new SugarParameter("@Name", "SqlSugar_SqlSugar"), new SugarParameter("@ID", id)); return result > 0; } }NotAutoDisposeTest
我們運行程式, 一樣得到True, 執行成功
該方法中, 我們使用SugarBase類裡面的GetIntance方法提供資料庫訪問對象, GetIntance方法有三個參數, 可以設置超時時間, 資料庫類型, 是否自動釋放, 都有預設值, 我所以沒有寫
使用GetIntance方法必須用using, 否則不會在使用完之後進行資料庫鏈接釋放
GetIntance方法使用場景, 在一個方法中, 要多次操作資料庫的時候使用, 而不是使用DB屬性, DB屬性會在每次操作完資料庫後進行釋放, 會造成一定的性能影響, 具體影響多少, 沒測試
GetIntance方法有個確定, 就是每次使用必須寫using, 對此做出了優化, SugarBase裡面提供了Exec<T>方法, 省去每次寫using的煩惱
我們在邏輯層編寫ExecTest方法, 代碼如下
/// <summary> /// Exec方法 /// </summary> /// <returns></returns> public bool ExecTest() { return Exec(db => { var id = db.Ado.GetInt("Select ID from TB_User where Name = @Name", new SugarParameter("@Name", "SqlSugar_SqlSugar")); var result = db.Ado.ExecuteCommand("update TB_User set Name = @Name where ID = @ID", new SugarParameter("@Name", "SqlSugar_Sugar"), new SugarParameter("@ID", id)); return result > 0; }); }ExecTest
可以看出, Exec方法需要傳入一個委托, 委托提供了SqlSugarClient參數, 用來操作資料庫, 運行程式, 返回true, 成功執行.
在多次操作資料庫的時候, 省去了寫using的麻煩, 偷懶試用, 本質和GetIntance沒有太大的區別
SugarBase還對事務操作提供了簡單封裝, 使用方法和Exec一樣, 裡面會自動處理事務, 這裡就不做DEMO編寫了.
事務處理方法為ExecTran, 發生異常會自動回滾事務, 成功會自動提交失誤
需要註意的是, 想手動回滾事務, 需自己編寫回滾代碼
如進行修改, 返回值受影響行數為0, 表示執行失敗了, 這時候我們要回滾事務, 不繼續執行, 則需要這麼編寫
if (result<=0) { db.Ado.RollbackTran(); return false; }
ExecTran方法使用和Exec一樣, 再次說明
到這裡, SqlSugar的入門就基本上介紹完畢, SugarBase類為博主自己簡單封裝, 適合大多數場景使用, 可以使用我提供的SugarBase類型進行資料庫操作對象獲取, 可以快速上手
基本上到這裡, 對ORM對象的創建已經都瞭解了, 下一篇編寫使用SqlSugar進行資料庫添加
提取密碼: 3mk7