DotNet Core中使用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?
- 轻量。只有一个文件(SqlMapper.cs),编译完成之后只有120k(好象是变胖了)
- 速度快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
- 支持多种数据库。Dapper可以在所有Ado.net Providers下工作,包括sqlite, sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
- 可以映射一对一,一对多,多对多等多种关系。
- 性能高。通过Emit反射IDataReader的序列队列,来快速的得到和产生对象,性能不错。
- 支持FrameWork2.0,3.0,3.5,4.0,4.5
在这里,我们在dotnet core下面使用Dapper操作MySQL。
首先,既然是演示,就先创建一个core MVC的项目,这里选择有模板的。因为公司使用的是dotnet core2.2的版本,我就基于core2.2版本创建一个项目。
Dapper安装,使用NuGet来安装Dapper程序包
使用NuGet安装MySQL.Data的程序包
安装这些程序包之后,在appsettings.json文件中添加链接数据库的字符串:
"ConnectionStrings": {
"DefaultConnection": "server=服务器;port=端口号;database=regatta{0};SslMode=None;uid=userName;pwd=passWord;Allow User Variables=true"
}
然后,封装一个工具类,来获得我们的连接字符串,和管理连接池。
public class BaseRepository : IDisposable
{
public static IConfigurationRoot Configuration { get; set; } public static MySqlConnection conn; public static MySqlConnection GetMySqlConnection(bool open = true,
bool convertZeroDatetime = false, bool allowZeroDatetime = false)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var cs = builder.GetSection("ConnectionStrings:DefaultConnection").Value;
var csb = new MySqlConnectionStringBuilder(cs)
{
AllowZeroDateTime = allowZeroDatetime,
ConvertZeroDateTime = convertZeroDatetime
};
conn = new MySqlConnection(csb.ConnectionString);
return conn;
} public void Dispose()
{
if (conn != null && conn.State != System.Data.ConnectionState.Closed)
{
conn.Close();
}
}
}
或者, 在startup中注册dapper仓储,并现时注册数据库类型和数据库连接串,因为在mysql和sqlserver中,它们的连接串是不同的,模块化设计请看大叔这篇文章,《DotNetCore跨平台~组件化时代来了》
services.UseLog4Logger(o =>
{
o.Log4ConfigFileName = "log4.config";
o.ProjectName = "test";
}).UseDapper(o =>
{
o.ConnString = "server=服务器;port=端口号;database=regatta{0};SslMode=None;uid=userName;pwd=passWord;Allow User Variables=true";
o.DbType = DbType.MySql;
}).UseDefaultMQ();
创建数据库中的一个需要映射的实体类:
public class Area
{
public int ID { get; set; } public string Name { get; set; } public int ParentID { get; set; }
}
当有些时候,数据库中的表名,与我们定义的实体类的类名,可能会不一致。这个时候,就需要加一个特性标签来声明了:
[Display(Name = "tbl_area")]
public class Area
{
public int ID { get; set; } public string Name { get; set; } public int ParentID { get; set; }
}
当然,有些表中的字段与实体类中的自己定义的属性,也不一样,其实有好多解决方法,可以在使用T-SQL的时候,使用别名。比如,SELECT id AS ID FROM TABLE..,或者使用特性标签,具体请参考:https://www.cnblogs.com/efreer/p/8277329.html
查询操作
/// <summary>
/// 查询单个数据
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public static Area QueryFirstOrDefault(int Id)
{
var sql = "SELECT * from Area where id =@ID";
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.QueryFirstOrDefault<Area>(sql, new { ID = Id });
}
}
/// <summary>
/// 查询所有数据
/// </summary>
/// <returns></returns>
public static List<Area> QueryList()
{
var sql = "select * from Area";
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Query<Area>(sql).ToList();
}
}
/// <summary>
/// In操作
/// </summary>
public static List<Area> QueryIn()
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
var sql = "select * from Area where id in @ids";
//参数类型是Array的时候,dappper会自动将其转化
return connection.Query<Area>(sql, new { ids = new int[] { , }, }).ToList();
}
} public static List<Area> QueryIn(int[] ids)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
var sql = "select * from Area where id in @ids";
//参数类型是Array的时候,dappper会自动将其转化
return connection.Query<Area>(sql, new { ids }).ToList();
}
}
插入操作
/// <summary>
/// 插入一条数据
/// </summary>
/// <param name="Area"></param>
/// <returns></returns>
public static int Insert(Area Area)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute($"INSERT INTO Area(Name,ParentID) VALUES(@Name,@ParentID)", Area);
}
} /// <summary>
/// 批量插入Area数据,返回影响行数
/// </summary>
/// <param name="Areas"></param>
/// <returns></returns>
public static int Insert(List<Area> Areas)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute("INSERT INTO Area(ID,Name,ParentID) VALUES(@ID,@Name,@ParentID)", Areas);
}
}
删除操作
/// <summary>
/// 删除一条
/// </summary>
/// <param name="Area"></param>
/// <returns></returns>
public static int Delete(Area Area)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute("DELETE FROM Area WHERE id=@ID", Area);
}
} /// <summary>
/// 批量删除
/// </summary>
/// <param name="Areas"></param>
/// <returns></returns>
public static int Delete(List<Area> Areas)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute("DELETE FROM Area WHERE id=@ID", Areas);
}
}
修改操作
/// <summary>
/// 修改
/// </summary>
/// <param name="Area"></param>
/// <returns></returns>
public static int Update(Area Area)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute("update Area set name=@name where id=@ID", Area);
}
} /// <summary>
/// 批量修改
/// </summary>
/// <param name="Areas"></param>
/// <returns></returns>
public static int Update(List<Area> Areas)
{
using (IDbConnection connection = BaseRepository.GetMySqlConnection())
{
return connection.Execute("update Area set name=@name where id=@ID", Areas);
}
}
Join操作
我们是面向对象编程,所以一个对象里面会有许多其他子对象,这个子对象里面又有其自己的子对象,这种关系在数据库里的表示就是外键。
比如我们有一本书book,它有主人person,book是一个对象,主人又是一个对象。
public class BookWithPerson
{
public int ID { get; set; }
public Person Pers { get; set; }
public string BookName { get; set; }
}
我们自然想要一个方法把数据库里复杂的外键关系转成我们需要的对象BookWithArea,所有我们需要的信息都存在里面,取数据的时候只要找这个对象取数据就行了,比如我们需要一本书的主人的姓名,我们只需要bookWithArea.Pers.Name。如果是一对多的关系我们用数组,如果是多对多我们加一层mapping。
现在我们想根据书的ID查询书的信息,包括主人信息。那么
public static BookWithPerson QueryJoin(Book book)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
var sql = @"select b.id,b.bookName,p.id,p.name,p.remark
from Person as p
join Book as b
on p.id = b.personId
where b.id = @id;";
var result = connection.Query<BookWithPerson, Person, BookWithPerson>(sql,
(bookWithPerson, person) =>
{
bookWithPerson.Pers = person;
return bookWithPerson;
},
book);
//splitOn: "bookName");
return (BookWithPerson)result;
}
}
中,Query的三个泛型参数分别是委托回调类型1
,委托回调类型2
,返回类型
。形参的三个参数分别是sql语句
,map委托
,对象参数
。所以整句的意思是先根据sql语句查询;同时把查询的Area信息赋值给bookWithArea.Pers,并且返回bookWithArea;book是对象参数,提供参数绑定的值。
最终整个方法返回BookWithArea,这样我们所需要的所有信息就有了。
这里只是简单介绍下同步增删改查的API的书写,异步的API,可以自行去了解。
参考地址:https://www.cnblogs.com/flywong/p/9666963.html
DotNet Core中使用dapper的更多相关文章
- .NET Core中使用Dapper操作Oracle存储过程最佳实践
为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...
- NET Core中使用Dapper操作Oracle存储过程
.NET Core中使用Dapper操作Oracle存储过程最佳实践 为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为Or ...
- Dotnet Core中使用AutoMapper
官网:http://automapper.org/ 文档:https://automapper.readthedocs.io/en/latest/index.html GitHub:https://g ...
- 依赖注入在 dotnet core 中实现与使用:1 基本概念
关于 Microsoft Extension: DependencyInjection 的介绍已经很多,但是多数偏重于实现原理和一些特定的实现场景.作为 dotnet core 的核心基石,这里准备全 ...
- DotNet Core中使用RabbitMQ
上一篇随笔记录到RabbitMQ的安装,安装完成,我们就开始使用吧. RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协 ...
- 依赖注入在 dotnet core 中实现与使用:4. 集成 Autofac
本示例使用 .net core 5 rc-1 实现. 1. 添加 Nuget 包引用 使用 Autofac 当然要添加 Autofac 的 Nuget 包,主要涉及到两个: Autofac.Exten ...
- 依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection
既然是依赖注入容器,必然会涉及到服务的注册,获取服务实例,管理作用域,服务注入这四个方面. 服务注册涉及如何将我们的定义的服务注册到容器中.这通常是实际开发中使用容器的第一步,而容器本身通常是由框架来 ...
- 学学dotnet core中的身份验证和授权-1-概念
前言 身份验证: Authentication 授权: Authorization net core 中的身份验证和授权这两个部分,是相辅相成的.当初我在学在部分的时候,是看的 net core 官网 ...
- .Net Core中使用Dapper构建泛型仓储
前言:Dapper是.NET的简单对象映射器,在速度方面拥有ORM之王的称号,与使用原始ADO.NET读取数据一样快.ORM是对象关系映射器,它负责数据库和编程语言之间的映射. 仓储主要是用来解耦业务 ...
随机推荐
- jeecg培训第一课(代码生成与权限分配)
问题描述:进口部要完成一票进口报关单的增删改查,操作员张三登录只能增删改张三的报关单,操作员李四登录只能增删改李四的报关单, 部门主管王五登录能查看张三和李四的报关单,但不能修改删除.操作员能提交报关 ...
- cocoapods 安装使用详解
http://blog.csdn.net/showhilllee/article/details/38398119 http://www.jianshu.com/p/1222dd6c4271 删除 ...
- 数据库Oracle的含义
数据库的含义: 所谓的数据库其实就是数据的集合.用户可以对集合中的数据进行新增.查询.更新. 删除等操作.数据库是以一定方式储存在一起.能与多个用户共享.具有尽可能小的冗余度. 与应用程序彼此独立的数 ...
- Mybatis的模糊查询以及自动映射
Mybatis的模糊查询 1. 参数中直接加入%% ? 1 2 3 4 5 6 7 8 9 param.setUsername("%CD%"); param.setP ...
- Ceph 架构以及原理分析
一.架构 Ceph在一个统一的系统中独特地提供对象,块和文件存储. Ceph高度可靠,易于管理且免费. Ceph的强大功能可以改变您公司的IT基础架构以及管理大量数据的能力. Ceph提供了非凡的可扩 ...
- Python文章相关性分析---金庸武侠小说分析-2018.1.16
最近常听同事提及相关性分析,正巧看到这个google的开源库,并把相关操作与调试结果记录下来. 输出结果: 比较有意思的巧合是黄蓉使出打狗棒,郭靖就用了降龙十八掌,再后测试了名词的解析. 小说集可以百 ...
- 常见的RuntimeException报错原因
对于RuntimeException 做java开发的朋友想必不会陌生,可以用于事物的回滚操作.异常类型也有很多种,写这篇文章主要是为了总结自己开发中遇到的一些异常类型 以便帮助大家遇到相应的报错找不 ...
- Python3 常用模块3
目录 numpy模块 创建numpy数组 numpy数组的属性和用法 matplotlib模块 条形图 直方图 折线图 散点图 + 直线图 pandas模块 numpy模块 numpy模块可以用来做数 ...
- 【Maven】常用命令
[Maven]常用命令 转载:https://www.cnblogs.com/yangchongxing/p/10267028.html Maven Jar 搜索:https://mvnreposit ...
- Java垃圾回收机制你还不明白?一线大厂面试必问的!
什么是自动垃圾回收? 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制. 所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未 ...