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是对象关系映射器,它负责数据库和编程语言之间的映射. 仓储主要是用来解耦业务 ...
随机推荐
- 小白的springboot之路(八)、继承Redis以及@Cacheable注解实现Redis缓存
0.前言 在项目中,缓存作为一种高效的提升性能的手段,几乎必不可少,Redis作为其中的佼佼者被广泛应用: 一.spring boot集成Redis 1.添加依赖 <dependency> ...
- 谁说微服务是Spring Cloud的独角戏?Service Mesh了解一下?
Service Mesh 的概念自 2017 年初提出之后,受到了业界的广泛关注,作为微服务的下一代发展架构在社区迅速发酵,并且孵化出了诸如 Istio 等广受业界关注的面向于云原生 (Cloud N ...
- [TimLinux] Python 使用入门
1. 为什么用Python 软件质量:Python注重可读性.一致性和软件质量. 提高开发者的效率:Python代码的大小往只有C++/Java代码的1/5 ~ 1/3. 程序的可移植性:绝大多数Py ...
- MySQL面试总结
MySQL面试总结 # MySQL的存储引擎 `MyISAM`(默认表类型):非事务的存储引擎,基于传统的`ISAM`(有索引的顺序访问方法)类型,是存储记录和文件的标准方法,不是事务安全,不支持外键 ...
- 菜鸟系列docker——docker网络(8)
Docker网络 Docker在容器内部运行应用,这些应用之间的交互依赖于大量不同的网络,这意味着Docker需要强大的网络功能. Docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多 ...
- KafkaManager2.0.0.2安装与使用
KafkaManager 是雅虎开源的一款 针对kafka集群的web管理工具, 具体功能和介绍就不再这细讲 kafka-manager github官网 https://github.com/ya ...
- Vue中无法检测到数组的变动
本周在写项目中遇到修改数组中的值时,视图无变化问题.在查阅Vue官方文档后了解到,由于由JavaScript 的限制,Vue 不能检测以下数组的变动: 当利用索引直接设置一个数组项时,例如:vm.it ...
- pipelinedb 常用sql语句
-- 创建普通表create table simple_user (name varchar(80), age int , phone varchar(30), birthday date ); -- ...
- 【搞定Jvm面试】 面试官:谈谈 JVM 类加载过程是怎样的?
类加载过程 Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢? 系统加载 Class 类型的文件主要三步:加载->连接->初始化.连接过程 ...
- IDC:助力转型、深入变革:中国云专业服务市场持续升温
来源:IDC 北京,2019 年 10 月 24 日——随着云计算在中国市场更深入和广泛的应用,与云相关的专业服务(咨询.迁移.开发与建设服务)需求旺盛.IDC 首次发布的<2019 年上半年云 ...