前言
混迹.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;" } }
到了这一步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