我们都知道,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?
在这里,我们在dotnet core下面使用Dapper操作MySQL。
首先,就先创建一个core webapi的项目,基于core3.1版本创建一个项目。
Dapper安装,使用NuGet来安装Dapper程序包
Install-Package Dapper -Version 2.0.30
Install-Package Dapper.Contrib -Version 2.0.30
使用NuGet安装MySQL.Data的程序包
安装这些程序包之后,在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架构搭建(四):仓储的依赖注入