.NET Core学习——Dapper

一、了解Dapper

我们都知道,ORM全称是,Object Relationship Mapper,即,对象关系映射。也就是可以用object来map我们的db,而且市面上的orm框架有很多,其中有一个框架叫做dapper,而且被称为the king of ORM。

  市场上,也有一些其他的ORM,比如EF Core,NHibernate 、FreeSQL等等,来处理大数据访问及关系映射。既然官方推出了EF Core,说明其对框架的支持会很友好,为什么又会有那么多的ORM框架供我们使用呢?其实,每一个框架都有其适用的场景。如果你在小的项目中,使用Entity Framework、Entity Framework Core、NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀。你又觉得ORM省时省力,这时Dapper 将是你不二的选择。其实,Entity Framework Core的性能并不是很高,当对性能有要求的时候,一般公司都会自己封装一套ORM。

为什么选择Dapper?

  1. 轻量。只有一个文件(SqlMapper.cs),编译完成之后只有120k(好象是变胖了)
  2. 速度快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
  3. 支持多种数据库。Dapper可以在所有Ado.net Providers下工作,包括sqlite, sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
  4. 可以映射一对一,一对多,多对多等多种关系。
  5. 性能高。通过Emit反射IDataReader的序列队列,来快速的得到和产生对象,性能不错。
  6. 支持FrameWork2.0,3.0,3.5,4.0,4.5

 二、使用Dapper

在这里,我们在dotnet core下面使用Dapper操作MySQL。

首先,就先创建一个core webapi的项目,基于core3.1版本创建一个项目。

Dapper安装,使用NuGet来安装Dapper程序包

.NET Core学习——Dapper_第1张图片

Install-Package Dapper -Version 2.0.30

Install-Package Dapper.Contrib -Version 2.0.30

使用NuGet安装MySQL.Data的程序包 

.NET Core学习——Dapper_第2张图片

安装这些程序包之后,在appsettings.json文件中添加链接数据库的字符串:

"ConnectionStrings": {
    "DefaultConnection": "server=服务器;port=端口号;database=regatta{0};SslMode=None;uid=userName;pwd=passWord;Allow User Variables=true"
  }

然后,封装一个工具类,来获得我们的连接字符串,和管理连接池。

IDapperContext:

    /// 
    /// Dapper上下文
    /// 
    public interface IDapperContext : IDisposable
    {
        /// 
        /// 数据库连接对象
        /// 
        IDbConnection ReadConnection { get; }

        /// 
        /// 数据库连接对象
        /// 
        IDbConnection WriteConnection { get; }
    }

 DapperContext:

    public class DapperContext : IDapperContext
    {
        /// 
        /// 读连接字符串
        /// 
        private string _readConnectionString;

        /// 
        /// 写连接字符串
        /// 
        private string _writeConnectionString;

        private bool _useMiniProfiling;

        /// 
        /// 读连接
        /// 
        private IDbConnection _readConnection;

        /// 
        /// 写连接
        /// 
        private IDbConnection _wrteConnection;

        /// 
        /// 配置
        /// 
        private readonly AppSetting _appSetting;

        /// 
        /// 构造函数注入IOptions
        /// 
        /// 
        public DapperContext(IOptions appSetting)
        {
            _appSetting = appSetting.Value;
            _readConnectionString = _appSetting.ReadOnlyConnectionString;
            _writeConnectionString = _appSetting.SetConnectionString;
            _useMiniProfiling = _appSetting.UseMiniProfiling;
        }

        /// 
        /// 连接字符串
        /// 
        /// 
        public DapperContext(string connectionString)
        {
            _readConnectionString = connectionString;
        }

        #region 读

        /// 
        /// 获取连接
        /// 
        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;
            }
        }

        /// 
        /// 释放连接
        /// 
        public void Dispose()
        {
            if (_readConnection != null && _readConnection.State == ConnectionState.Open)
                _readConnection.Close();
            if (_wrteConnection != null && _wrteConnection.State == ConnectionState.Open)
                _wrteConnection.Close();
        }

        #endregion 读

        #region 写

        /// 
        /// 获取连接
        /// 
        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 写
    }

 创建一个仓储,用来存放数据库CRUD等操作

IRepository:

    /// 
    /// 数据库CRUD等操作
    /// 
    /// 
    public interface IRepository where T : class
    {
        /// 
        /// 上下文
        /// 
        IDapperContext Context { get; }

        /// 
        /// 只读连接
        /// 
        IDbConnection ReadConnection { get; }

        /// 
        /// 读写连接
        /// 
        IDbConnection WriteConnection { get; }

        /// 
        /// 获取分页数据
        /// 
        /// 
        /// 查询设置
        /// 
        /// 
        PageDataView GetPageData(PageCriteria criteria, object param = null) where TEntity : class;

        /// 
        ///
        /// 
        /// 
        /// 
        /// 
        /// 
        PageDataView GetAllData(PageCriteria criteria, object param = null) where TEntity : class;

        /// 
        /// 添加数据
        /// 
        /// 
        /// 
        /// 
        /// 
        long Add(T entity, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 批量添加数据
        /// 
        /// 
        /// 
        /// 
        /// 
        long BatchAdd(IEnumerable list, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        ///
        /// 
        /// 
        /// 
        /// 
        bool Update(T entity, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 删除单条数据
        /// 
        /// 
        /// 
        /// 
        bool Remove(T entity, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 批量删除
        /// 
        /// 
        /// 
        /// 
        /// 
        bool BatchRemove(IEnumerable list, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 根据主键获取数据
        /// 
        /// 
        /// 
        /// 
        /// 
        T GetByKey(object key, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 获取所有数据
        /// 
        /// 
        /// 
        /// 
        IEnumerable GetAll(IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 根据条件获取数据列表
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        IEnumerable GetBy(object sql = null, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 查询数据列表
        /// 
        /// 
        /// 
        /// 
        /// 
        IEnumerable Query(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 多对象查询
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        GridReader QueryMultiple(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);

        /// 
        /// 执行sql
        /// 
        /// 
        /// 
        /// 
        /// 
        int Excute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);

        /// 
        /// 执行是否存在数据
        /// 
        /// 查询(例:SELECT COUNT(1)  FROM XXX )
        /// 
        bool Exists(string sqlStr, object param = null);
    }

Repository:

    public class Repository : IRepository 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 GetPageData(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();

            pageData.Items = ReadConnection.Query(proName, p, commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList();
            pageData.TotalNum = p.Get("_totalcount");
            pageData.TotalPageCount = p.Get("_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 GetAllData(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();
            pageData.Items = ReadConnection.Query(proName, p, commandType: CommandType.StoredProcedure, commandTimeout: 300).ToList();
            pageData.TotalNum = p.Get("_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 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 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(queryId, transaction: transaction, commandTimeout: commandTimeout);
        }

        public virtual IEnumerable GetAll(IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return ReadConnection.GetAll(transaction: transaction, commandTimeout: commandTimeout);
        }

        public virtual IEnumerable GetBy(object sql = null, object param = null, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return ReadConnection.Query(sql.ToString(), param, commandTimeout: commandTimeout);
        }

        public IEnumerable Query(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return ReadConnection.Query(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(sqlStr, param).Count() > 0 ? true : false;
        }
    }

 利用工厂模式创建仓库

IFactoryRepository:

    /// 
    /// 创建仓库接口
    /// 
    public interface IFactoryRepository
    {
        /// 
        /// 创建仓库
        /// 
        /// 
        /// 
        /// 
        IRepository CreateRepository(IDapperContext context) where T : class;
    }

 FactoryRepository:

    /// 
    /// 工厂
    /// 
    public class FactoryRepository : IFactoryRepository
    {
        /// 
        /// 创建Repository
        /// 
        /// 
        /// 
        /// 
        public IRepository CreateRepository(IDapperContext context) where T : class
        {
            IRepository repository = new Repository(context);
            return repository;
        }
    }

相关文章:

**Dapper的基本使用 

NetCore+Dapper WebApi架构搭建(一):基本框架

NetCore+Dapper WebApi架构搭建(二):底层封装

NetCore+Dapper WebApi架构搭建(三):添加实体和仓储

NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入

 

 

你可能感兴趣的:(.Net,Core)