用轻量级ORM--Dapper实现泛型仓储

阅读本文你的收获

  1. 了解Dapper的适用场景
  2. 了解Dapper的本质其实是一些扩展方法
  3. 学会使用Dapper的扩展Domel来实现泛型仓储

一、什么是Dapper?

Dapper是一个轻量级的ORM(对象关系映射)工具,用于简化数据库操作。它和Entity Framework 不同,它属于轻量级的,并且是半自动的。

Dapper的优势:

  • Dapper非常小巧,只有一个帮助类,完全开源。
  • Dapper以性能优异著称。一般的ORM框架,性能和直接写原生的SQL语句比都差不少,但是Dapper执行SQL语句的性能非常好。

Dapper的使用场景:

  1. 快速的数据访问:Dapper提供了简单、快速的方法来执行数据库查询操作,可以有效地减少代码量和开发时间。

  2. 大数据量的操作:Dapper在处理大数据量的操作时表现出色,相比其他ORM工具,它具有更低的内存占用和更高的性能。

  3. 原始SQL查询:Dapper允许开发人员编写和执行原生SQL查询,可以灵活地处理复杂的查询需求。

  4. 存储过程的调用:Dapper支持存储过程的调用,并提供了简便的方式来执行存储过程并获取返回结果。

总之,Dapper适用于需要快速、高性能的数据访问的场景,尤其适用于对数据库操作要求较高的应用程序。

二、Dapper的本质

Dapper库对IDbConnection接口扩展了许多方法,使得与数据库交互变得更加方便和高效。下面是Dapper中定义的Query方法,它是一个扩展方法,扩展的目标类型是IDbConnection。

public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)

以下是Dapper扩展的一些常用方法(包括但不限于):

  1. Query方法:用于执行SQL查询并返回结果集。
  2. QueryFirstOrDefault方法:用于执行SQL查询并返回结果集中的第一行记录,如果结果集为空则返回默认值。
  3. QuerySingleOrDefault方法:用于执行SQL查询并返回唯一一条记录,如果结果集为空则返回默认值。
  4. Execute方法:用于执行SQL语句并返回受影响的行数。
  5. ExecuteScalar方法:用于执行SQL语句并返回受影响的行数。

这些方法还有与之对应的异步方法(Async结尾的方法)。

此外,Dapper还提供了一些类型用于处理与参数有关的操作,例如:DynamicParameters类:用于动态创建参数。该类的Add方法:用于向参数集合中添加参数,而Get方法:用于获取参数的值。

三、Dapper的入门案例

开发环境:

平台版本是:.NET6
开发框架:ASP.NET Core WebApi
开发工具:Visual Studio 2022
数据库版本:MS SQL Server 2014

3.1 安装Dapper

通过NuGet包管理器安装Dapper
安装Dapper

3.2 用Dapper执行SQL语句

以下案例用Dapper实现查询用户是否存在。

//头上引用命名空间
using Dapper;//获取连接字符串(本例中是硬编码的,最好写在appsettings.json中)
private const string CONNECT_STRING = "Data Source=.;Initial Catalog=shoppingdb1;User ID=sa;Password=123abc!";/// <summary>
/// 检查登录的账号和密码
/// </summary>
/// <param name="UserName"></param>
/// <param name="Password"></param>
/// <returns></returns>
public bool Login(string userName, string password)
{using(var conn = new SqlConnection(CONNECT_STRING)){string sql = "select * from [dbo].[User] where UserName=@UserName and Password=@Password";//Query<>方法用户执行select语句,获取结果集List<User> users = conn.Query<User>(sql, new { UserName=userName, Password=password}).ToList();return users.Count > 0;}
}//或者也可以使用ExecuteScalar扩展方法
public bool Login(string userName, string password)
{using (var conn = new SqlConnection(CONNECT_STRING)){string sql = "select count(*) from [dbo].[User] where UserName=@UserName and Password=@Password";//ExecuteScalar<>方法用于执行返回标量类型的sql语句如count(*)返回的就是标量值int count  = conn.ExecuteScalar<int>(sql, new { UserName = userName, Password = password});return count > 0;}
}

四、Dapper的常用扩展库

看了以上案例,是不是觉得Dapper不就是一个执行SQL语句的帮助类,哪里是一个ORM?ORM不是应该可以减少开发人员手动编写SQL语句的工作量,提高开发效率吗?

对的,作为ORM的Dapper本身并没有带太多的功能,但是Dapper有很多扩展库(官方的和第三方的),使用这些扩展库可以自动映射对象到数据库表、自动生成CRUD操作语句、批量操作等。

Dapper的扩展库有:

  • Dapper.SimpleCRUD : 提供了一套CRUD方法,可以直接传对象,不用自己写SQL
  • Dapper.FluentMap : 提供了一套方法,可以实现实体类与数据库类型之间的映射
  • Dapper.FluentMap.Dommel : 使用Dapper进行CRUD操作变得更为简单
  • Dapper.Contrib : 是Dapper官方提供的扩展库,提供了一些实用的功能和扩展方法,使得在使用Dapper和数据库进行操作时更加方便和高效

五、用Dapper实现仓储模式

ASP.NET Core WebApi的项目中,我们可以用EF/EF Core来实现仓储模式,当然作为轻量级的ORM之王,Dapper也可以实现仓储模式;

下面我们将用Dapper和他的扩展组件Domel来封装仓储模式;

  1. 在基础设施层,NuGet包里面添加Dapper和Dapper.FluentMap.Dommel
    安装Dommel

  2. 用工厂模式和单例模式,来创建一个DapperFactory工厂类,实现灵活切换MySql和SqlServer,后续还可以支持更多数据库

    //需要引用一下命名空间
    using System.Data;
    using MySql.Data.MySqlClient;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Configuration.Json;
    using System.Data.SqlClient;/// <summary>
    /// Dapper实例(采用单例模式)
    /// </summary>
    public class DapperFactory
    {/// <summary>/// 读取配置文件用/// </summary>private IConfiguration Configuration { get; set; }// 静态变量保存类的实例    private static DapperFactory uniqueInstance;// 定义一个标识确保线程同步     private static readonly object locker = new object();/// <summary>/// 私有构造方法,使外界不能创建该类的实例,以便实现单例模式/// </summary>private DapperFactory(){Configuration = new ConfigurationBuilder().Add(new JsonConfigurationSource{Path = "appsettings.json",ReloadOnChange = true}).Build();}/// <summary>/// 获取实例,这里为单例模式,保证只存在一个实例/// </summary>/// <returns></returns>public static DapperFactory GetInstance(){// 双重锁定实现单例模式,在外层加个判空条件主要是为了减少加锁、释放锁的不必要的损耗if (uniqueInstance == null){lock (locker){if (uniqueInstance == null){uniqueInstance = new DapperFactory(); //懒汉模式}}}return uniqueInstance;}/// <summary>/// 创建数据库连接对象(采用了设计模式 之 简单工厂模式)/// </summary>/// <returns></returns>public IDbConnection CreateDbConnection(){IDbConnection dbConnection = null;//读取配置文件中的数据库服务器类型 mysql或sqlserverstring dbType = Configuration["DbServerType"];//读取配置文件中的连接字符串string _connectionString = Configuration.GetConnectionString("Default");switch (dbType){case "MySql":dbConnection = new MySqlConnection(_connectionString);break;case "SqlServer":dbConnection = new SqlConnection(_connectionString);break;}//判断连接状态(Dapper内部会自动打开数据库连接,所以无需以下下代码)//if (dbConnection.State == ConnectionState.Closed)//{//    dbConnection.Open();//}return dbConnection;}
    }
    
  3. 编写泛型仓储接口

    using Dommel; //该库为Dapper扩展了CRUD方法/// <summary>
    /// 仓储抽象基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class BaseRepository<T>: IBaseRepository<T> where T:class, new()
    {//获取数据库连接对象  DapperSingleton这个类是第2步写的protected IDbConnection _db = DapperFactory.GetInstance().CreateDbConnection();/// <summary>/// 添加一条实体数据/// </summary>/// <param name="entity"></param>/// <returns></returns>public int Insert(T entity) {return (int)_db.Insert(entity); }/// <summary>///  更新实体数据/// </summary>/// <param name="entity"></param>/// <returns></returns>public bool Update(T entity){return _db.Update(entity);}/// <summary>/// 删除数据/// </summary>/// <param name="entity">实体类</param>/// <returns></returns>public bool Delete(T entity){return _db.Delete(entity);}/// <summary>///  删除指定ID的数据/// </summary>/// <param name="objId"></param>/// <returns></returns>public bool DeleteById(object objId){return Delete(_db.Get<T>(objId));}/// <summary>/// 根据主值查询单条数据/// </summary>/// <param name="objId">主键值</param>/// <returns>泛型实体</returns>public T GetById(object objId){return _db.Get<T>(objId);}/// <summary>/// 获取全部数据/// </summary>/// <returns></returns>public List<T> GetList(){return _db.GetAll<T>().ToList();}}
    
  4. 在appsettings.json中配置你要用的数据库和连接字符串

      "ConnectionStrings": {"Default": "server=127.0.0.1;database=superhousedb;user=root;password=root"},"DbServerType": "MySql" //MySql数据库 或  SqlServer
    

以上,借助Dapper扩展Domel是不是就能实现不用写SQL语句就能实现增删改查了??
好,今天就分享到这里,更多高级用法以后有机会再分享。如果本文对你有帮助的话,请点赞+评论+关注,或者转发给需要的朋友。


参考链接:

Dapper官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2659881.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

第五章 与HTTP协作的Web服务器

5.1 用单台虚拟主机实现多个域名 在传统的基于IP地址的服务器配置中&#xff0c;一台服务器通常只能提供一个域名的服务。然而&#xff0c;通过虚拟主机的技术&#xff0c;同一台服务器可以根据请求中的域名&#xff0c;区分并提供不同的网站内容。这使得在一台物理或虚拟服务…

如何在Mac中设置三指拖移,这里有详细步骤

三指拖移手势允许你选择文本&#xff0c;或通过在触控板上用三指拖动窗口或任何其他元素来移动它。它可以用于快速移动或调整窗口、文件或图像在屏幕上的位置。 然而&#xff0c;这个手势在默认情况下是禁用的&#xff0c;因此在本教程中&#xff0c;我们将向你展示如何在你的…

Java—Throwing Exceptions

一、指定方法引发的异常 上一节展示了如何为ListOfNumbers类中的writeList&#xff08;&#xff09;方法编写异常处理程序。有时&#xff0c;代码捕获可能在其中发生的异常是适当的。然而&#xff0c;在其他情况下&#xff0c;最好让调用堆栈更上层的方法处理该异常。例如&…

DRF从入门到精通六(排序组件、过滤组件、分页组件、异常处理)

文章目录 一、排序组件继承GenericAPIView使用DRF内置排序组件继承APIView编写排序 二、过滤组件继承GenericAPIView使用DRF内置过滤器实现过滤使用第三方模块django-filter实现and关系的过滤自定制过滤类排序搭配过滤使用 三、分页组件分页器一&#xff1a;Pagination&#xf…

web3方向产品调研

每次互联网形态的改变&#xff0c;都会对世界产生很大的影响&#xff0c;上一次对社会产生重大影响的互联网形态&#xff08;Web2.0&#xff09;催生了一批改变人类生活和信息交互方式的企业。 目录 概述DAO是什么&#xff1f;为什么我们需要DAO? 金融服务金融桥接及周边服务D…

Go 中有效并发的模式

设计高效可靠的并发系统 在现代软件开发领域中&#xff0c;利用并发的能力已经变得至关重要。随着应用程序的复杂性增加和数据处理需求的增长&#xff0c;编写既高效又可靠的并发代码成为了一个重要的关注点。为了解决这个挑战&#xff0c;开发者们已经制定了一些模式和最佳实…

Kubeadmin实现k8s集群:

Kubeadmin来快速搭建一个k8s集群&#xff1a; 二进制搭建适合大集群&#xff0c;50台以上的主机&#xff0c; 但是kubeadm更适合中小企业的业务集群 环境&#xff1a; Master&#xff1a;20.0.0.71 2核4G 或者4核8G docker kubelet kubectl flannel Node1&#xff1a;20.…

【C语言】程序练习(二)

大家好&#xff0c;这里是争做图书馆扫地僧的小白。 个人主页&#xff1a;争做图书馆扫地僧的小白_-CSDN博客 目标&#xff1a;希望通过学习技术&#xff0c;期待着改变世界。 目录 前言 一、运算符练习 1 算术运算符 1.1 练习题&#xff1a; 2 自加自减运算符 3 关系运…

centos下docker安装Rocketmq总结,以及如何更换mq端口

默认你已经装好了docker哈 安装docker-compose sudo curl -L https://github.com/docker/compose/releases/download/1.25.1-rc1/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-composechmod x /usr/local/bin/docker-composedocker-compose --version成功打印…

一招搞定找不到vcruntime140_1.dll无法继续执行此代码

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“找不到指定的模块”或“无法加载某某.dll文件”。而其中一个常见的问题就是vcruntime140_1.dll丢失。那么&#xff0c;vcruntime140_1.dll到底是什么&#xff1f;为什么会出现丢失的情…

MEMS热式气体流量传感器及其应用选型

热式气体流量传感器简介 热式气体流量传感器是基于流体传热学原理的一类传感器&#xff0c;利用 MEMS 热式原理对管路气体介质进行流量监测。 流量芯片由两个热偶堆和一个加热电阻组成&#xff0c;热偶堆对称分布在加热电阻的上、下游&#xff0c;加热电阻和热偶堆的热结处于一…

如何使用凹凸贴图和位移贴图制作逼真的模型

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 本教程将解释如何应用这些效应背后的理论。在以后的教程中&#xff0…

腾讯云服务器怎么选?腾讯云服务器最新优惠价格表来了!

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

Java中实现百度浏览器搜索功能(windows/linux)

要在Java中实现百度浏览器搜索功能&#xff0c;你可以使用Selenium WebDriver。Selenium是一个用于自动化浏览器的工具&#xff0c;WebDriver是Selenium的一个子项目&#xff0c;它提供了一套API&#xff0c;可以直接与浏览器交互。 依赖: <dependencies><dependency…

前端图片适配不同屏幕方案

预备知识&#xff1a; 设备独立像素,以下图的iphone12 Pro为例&#xff0c;390*844表示的就是设备独立像素&#xff08;DIP&#xff09;,也可以理解为CSS像素 物理像素&#xff08;设备像素&#xff09;&#xff0c;就是屏幕的分辨率&#xff0c;显示屏就是由一个个物理像素…

django之drf框架(排序、过滤、分页、异常处理)

排序 排序的快速使用 1.必须是继承GenericAPIView及其子类才能是用排序 导入OrderingFilter类&#xff0c;from rest_framework.filters import OrderingFilter 2.在类中配置类属性 filter_backends[OrderingFilter] 3.类中写属性 ordering_fields [price,id] # 必须是表的…

springboot整合minio做文件存储

一,minio介绍 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&…

Android ImageView如何使用.svg格式图片

我们知道imageview常用的图片格式是.jpg/.png或者drawable里的部分.xml文件。但有时UI会给过来.svg格式的文件&#xff0c;下面讲解如何使用.svg格式图片文件 step1:AS点击File -> New -> Vector Asset step2:选中要使用的.svg文件&#xff0c;按需要命名和调整&#x…

java itext5 生成PDF并填充数据导出

java itext5 生成PDF并填充数据导出 依赖**文本勾选框****页眉**&#xff0c;**页脚****图片**实际图 主要功能有文本勾选框&#xff0c;页眉&#xff0c;页脚&#xff0c;图片等功能。肯定没有专业软件画的好看&#xff0c;只是一点儿方法。仅供参考。 依赖 <!--pdf-->&…

axios配置请求头content-type 和 get/post请求方式

axios配置请求头content-type https://blog.csdn.net/wojiushiwo945you/article/details/107653962 axios 是Ajax的一个插件&#xff0c;axios虽然是一个插件&#xff0c;但是我们不需要通过Vue.use(axios)来使用&#xff0c;下载完成后&#xff0c;只需在项目中引入即可。(一…