一、前期環境准備
1、創建一個core webapi的項目,基於core3.1版本創建一個項目。
2、Dapper安裝,使用NuGet來安裝Dapper程序包
Install-Package Dapper -Version 2.0.30
Install-Package Dapper.Contrib -Version 2.0.30
3、MySQL.Data的程序包(可以使用其他數據庫,如:sqlserver,sqllite等)
Install-Package Dapper -Version 8.0.25
4、appsettings.json文件中添加鏈接數據庫的字符串(其他數據庫連接字符串,自行更改):
"ConnectionStrings": {
"DefaultConnection": "server=服務器;port=端口號;database=regatta{0};SslMode=None;uid=userName;pwd=passWord;Allow User Variables=true"
}
二、封裝
1、IDapperContext:
/// <summary> /// Dapper上下文 /// </summary> public interface IDapperContext : IDisposable { /// <summary> /// 數據庫連接對象 /// </summary> IDbConnection ReadConnection { get; } /// <summary> /// 數據庫連接對象 /// </summary> IDbConnection WriteConnection { get; } }
2、DapperContext:
public class DapperContext : IDapperContext { /// <summary> /// 讀連接字符串 /// </summary> private string _readConnectionString; /// <summary> /// 寫連接字符串 /// </summary> private string _writeConnectionString; private bool _useMiniProfiling; /// <summary> /// 讀連接 /// </summary> private IDbConnection _readConnection; /// <summary> /// 寫連接 /// </summary> private IDbConnection _wrteConnection; /// <summary> /// 配置 /// </summary> private readonly AppSetting _appSetting; /// <summary> /// 構造函數注入IOptions /// </summary> /// <param name="appSetting"></param> public DapperContext(IOptions<AppSetting> appSetting) { _appSetting = appSetting.Value; _readConnectionString = _appSetting.ReadOnlyConnectionString; _writeConnectionString = _appSetting.SetConnectionString; _useMiniProfiling = _appSetting.UseMiniProfiling; } /// <summary> /// 連接字符串 /// </summary> /// <param name="connectionString">讀寫連接字符串</param> public DapperContext(string connectionString) { _readConnectionString = connectionString; _writeConnectionString = connectionString; } #region 讀 /// <summary> /// 獲取連接 /// </summary> public IDbConnection ReadConnection { get { if (_readConnection == null || _readConnection.State == ConnectionState.Closed) { if (_useMiniProfiling) { _readConnection = new ProfiledDbConnection(new MySqlConnection(_readConnectionString), MiniProfiler.Current); } else { _readConnection = new MySqlConnection(_readConnectionString); } } if (_readConnection.State != ConnectionState.Open) { _readConnection.Open(); } return _readConnection; } } /// <summary> /// 釋放連接 /// </summary> public void Dispose() { if (_readConnection != null && _readConnection.State == ConnectionState.Open) _readConnection.Close(); if (_wrteConnection != null && _wrteConnection.State == ConnectionState.Open) _wrteConnection.Close(); } #endregion #region 寫 /// <summary> /// 獲取連接 /// </summary> public IDbConnection WriteConnection { get { if (_wrteConnection == null || _wrteConnection.State == ConnectionState.Closed) { if (_useMiniProfiling) { _wrteConnection = new ProfiledDbConnection(new MySqlConnection(_writeConnectionString), MiniProfiler.Current); } else { _wrteConnection = new MySqlConnection(_writeConnectionString); } } if (_wrteConnection.State != ConnectionState.Open) { _wrteConnection.Open(); } return _wrteConnection; } } #endregion }
3、IRepository(倉儲):
/// <summary> /// 數據庫CRUD等操作 /// </summary> /// <typeparam name="T"></typeparam> public interface IRepository<T> where T : class { /// <summary> /// 上下文 /// </summary> IDapperContext Context { get; } /// <summary> /// 只讀連接 /// </summary> IDbConnection ReadConnection { get; } /// <summary> /// 讀寫連接 /// </summary> IDbConnection WriteConnection { get; } /// <summary> /// 獲取分頁數據 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="criteria">查詢設置</param> /// <param name="param"></param> /// <returns></returns> PageDataView<TEntity> GetPageData<TEntity>(PageCriteria criteria, object param = null) where TEntity : class; /// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="criteria"></param> /// <param name="param"></param> /// <returns></returns> PageDataView<TEntity> GetAllData<TEntity>(PageCriteria criteria, object param = null) where TEntity : class; /// <summary> /// 添加數據 /// </summary> /// <param name="entity"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> long Add(T entity, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 批量添加數據 /// </summary> /// <param name="entity"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> long BatchAdd(IEnumerable<T> list, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> bool Update(T entity, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 刪除單條數據 /// </summary> /// <param name="entity"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> bool Remove(T entity, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 批量刪除 /// </summary> /// <param name="list"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> bool BatchRemove(IEnumerable<T> list, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 根據主鍵獲取數據 /// </summary> /// <param name="key"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> T GetByKey(object key, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 獲取所有數據 /// </summary> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> IEnumerable<T> GetAll(IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 根據條件獲取數據列表 /// </summary> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> IEnumerable<T> GetBy(object sql = null, object param = null, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 查詢數據列表 /// </summary> /// <param name="sql"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> IEnumerable<dynamic> Query(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 多對象查詢 /// </summary> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns></returns> GridReader QueryMultiple(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); /// <summary> /// 執行sql /// </summary> /// <param name="sql"></param> /// <param name="transaction"></param> /// <param name="commandTimeout"></param> /// <returns></returns> int Excute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null); /// <summary> /// 執行是否存在數據 /// </summary> /// <param name="sqlStr">查詢(例:SELECT COUNT(1) FROM XXX )</param> /// <returns></returns> bool Exists(string sqlStr, object param = null); }
4、Repository(倉儲實現):
public class Repository<T> : IRepository<T> where T : class { public Repository(IDapperContext context) { Context = context; } public IDapperContext Context { get; private set; } public IDbConnection ReadConnection => Context.ReadConnection; public IDbConnection WriteConnection => Context.WriteConnection; public PageDataView<TEntity> GetPageData<TEntity>(PageCriteria criteria, object param = null) where TEntity : class { var p = new DynamicParameters(); string proName = "ProcGetPageData"; p.Add("_tables", criteria.TableName); p.Add("_fields", criteria.Fields); p.Add("_where", criteria.Condition); p.Add("_pageIndex", criteria.CurrentPage); p.Add("_pageSize", criteria.PageSize); p.Add("_orderby", criteria.Sort); p.Add("_totalcount", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add("_pagecount", dbType: DbType.Int32, direction: ParameterDirection.Output); var pageData = new PageDataView<TEntity>(); pageData.Items = ReadConnection.Query<TEntity>(proName, p, commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList(); pageData.TotalNum = p.Get<int>("_totalcount"); pageData.TotalPageCount = p.Get<int>("_pagecount"); //Convert.ToInt32(Math.Ceiling(pageData.TotalNum * 1.0 / criteria.PageSize)); pageData.CurrentPage = criteria.CurrentPage > pageData.TotalPageCount ? pageData.TotalPageCount : criteria.CurrentPage; return pageData; } public PageDataView<TEntity> GetAllData<TEntity>(PageCriteria criteria, object param = null) where TEntity : class { var p = new DynamicParameters(); string proName = "ProcGetAllData"; p.Add("_tables", criteria.TableName); p.Add("_fields", criteria.Fields); p.Add("_where", criteria.Condition); p.Add("_orderby", criteria.Sort); p.Add("_totalcount", dbType: DbType.Int32, direction: ParameterDirection.Output); var pageData = new PageDataView<TEntity>(); pageData.Items = ReadConnection.Query<TEntity>(proName, p, commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList(); pageData.TotalNum = p.Get<int>("_totalcount"); return pageData; } public long Add(T entity, IDbTransaction transaction = null, int? commandTimeout = null) { if (entity == null) { throw new ArgumentNullException("entity", "Add to DB null entity"); } var res = WriteConnection.Insert(entity, transaction: transaction, commandTimeout: commandTimeout); return res; } public long BatchAdd(IEnumerable<T> list, IDbTransaction transaction = null, int? commandTimeout = null) { if (list == null) { throw new ArgumentNullException("list", "BatchAdd to DB null entity"); } var res = WriteConnection.Insert(list, transaction: transaction, commandTimeout: commandTimeout); return res; } public virtual bool Update(T entity, IDbTransaction transaction = null, int? commandTimeout = null) { if (entity == null) { throw new ArgumentNullException("entity", "Update in DB null entity"); } return WriteConnection.Update(entity, transaction: transaction, commandTimeout: commandTimeout); } public virtual bool Remove(T entity, IDbTransaction transaction = null, int? commandTimeout = null) { if (entity == null) { throw new ArgumentNullException("entity", "Remove in DB null entity"); } return WriteConnection.Delete(entity, transaction: transaction, commandTimeout: commandTimeout); } public bool BatchRemove(IEnumerable<T> list, IDbTransaction transaction = null, int? commandTimeout = null) { if (list == null) { throw new ArgumentNullException("list", "BatchAdd to DB null entity"); } return WriteConnection.Delete(list, transaction: transaction, commandTimeout: commandTimeout); } public virtual T GetByKey(object queryId, IDbTransaction transaction = null, int? commandTimeout = null) { if (queryId == null) { throw new ArgumentNullException("queryId"); } return ReadConnection.Get<T>(queryId, transaction: transaction, commandTimeout: commandTimeout); } public virtual IEnumerable<T> GetAll(IDbTransaction transaction = null, int? commandTimeout = null) { return ReadConnection.GetAll<T>(transaction: transaction, commandTimeout: commandTimeout); } public virtual IEnumerable<T> GetBy(object sql = null, object param = null, IDbTransaction transaction = null, int? commandTimeout = null) { return ReadConnection.Query<T>(sql.ToString(), param, commandTimeout: commandTimeout); } public IEnumerable<dynamic> Query(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null) { return ReadConnection.Query<dynamic>(sql, param); } public GridReader QueryMultiple(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { return ReadConnection.QueryMultiple(sql, param, transaction, commandTimeout, commandType); } public int Excute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null) { return WriteConnection.Execute(sql, param, transaction: transaction); } public bool Exists(string sqlStr, object param = null) { return ReadConnection.Query<dynamic>(sqlStr, param).Count() > 0 ? true : false; } }
利用工廠模式創建倉庫
5、IFactoryRepository:
/// <summary> /// 創建倉庫接口 /// </summary> public interface IFactoryRepository { /// <summary> /// 創建倉庫 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="context"></param> /// <returns></returns> IRepository<T> CreateRepository<T>(IDapperContext context) where T : class; } /// <summary> /// 工廠 /// </summary> public class FactoryRepository : IFactoryRepository { /// <summary> /// 創建Repository /// </summary> /// <typeparam name="T"></typeparam> /// <param name="context"></param> /// <returns></returns> public IRepository<T> CreateRepository<T>(IDapperContext context) where T : class { IRepository<T> repository = new Repository<T>(context); return repository; } }