SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。
/// <summary>
/// SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。
/// </summary>
public class SqlHelper : IDbHelper
{private readonly IDbConnectionFactory _connectionFactory;private readonly ILogger<SqlHelper>? _logger;private readonly AsyncPolicy _retryPolicy;private readonly IRedisCacheHelper? _redisCacheHelper;/// <summary>/// 构造函数,注入数据库连接工厂,日志记录器,自动重试次数与延迟,以及可选 Redis 缓存。/// </summary>/// <param name="connectionFactory">数据库连接工厂</param>/// <param name="logger">日志记录器</param>///<param name="retryCount">自动重试次数</param> /// <param name="retryDelayMs">重试延迟(毫秒)</param> /// <param name="redisCacheHelper">Redis 缓存(可空)</param> public SqlHelper( IDbConnectionFactory connectionFactory, ILogger<SqlHelper>? logger = null, int retryCount = 3, int retryDelayMs = 200, IRedisCacheHelper? redisCacheHelper = null) { _connectionFactory = connectionFactory; _logger = logger;_redisCacheHelper = redisCacheHelper;_retryPolicy = Policy.Handle<Exception>().WaitAndRetryAsync(retryCount, _ => TimeSpan.FromMilliseconds(retryDelayMs),(ex, timespan, retryCount, context) =>{_logger?.LogWarning($"Retry {retryCount} in {timespan.TotalMilliseconds}ms due to: {ex.Message}");});}/// <summary>/// 获取数据库连接实例/// </summary>/// <returns>DbConnection 实例</returns>private DbConnection GetConnection() => _connectionFactory.CreateConnection();public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object? parameters = null){var sw = Stopwatch.StartNew();await using var conn = GetConnection();await conn.OpenAsync();var result = await _retryPolicy.ExecuteAsync(() => conn.QueryAsync<T>(sql, parameters));sw.Stop();_logger?.LogInformation($"[Query] {sw.ElapsedMilliseconds}ms - SQL: {sql}");return result;}public async Task<T> QueryFirstOrDefaultAsync<T>(string sql, object? parameters = null){var sw = Stopwatch.StartNew();await using var conn = GetConnection();await conn.OpenAsync();var result = await _retryPolicy.ExecuteAsync(() => conn.QueryFirstOrDefaultAsync<T>(sql, parameters));sw.Stop();_logger?.LogInformation($"[QueryFirstOrDefault] {sw.ElapsedMilliseconds}ms - SQL: {sql}");return result;}public async Task<int> ExecuteAsync(string sql, object? parameters = null){var sw = Stopwatch.StartNew();await using var conn = GetConnection();await conn.OpenAsync();var result = await _retryPolicy.ExecuteAsync(() => conn.ExecuteAsync(sql, parameters));sw.Stop();_logger?.LogInformation($"[Execute] {sw.ElapsedMilliseconds}ms - SQL: {sql}");return result;}public async Task<IEnumerable<T>> RunProcedureAsync<T>(string procName, object? parameters = null){var sw = Stopwatch.StartNew();await using var conn = GetConnection();await conn.OpenAsync();var result = await _retryPolicy.ExecuteAsync(() => conn.QueryAsync<T>(procName, parameters, commandType: CommandType.StoredProcedure));sw.Stop();_logger?.LogInformation($"[RunProcedure] {sw.ElapsedMilliseconds}ms - Procedure: {procName}");return result;}public async Task ExecuteInTransactionAsync(Func<IDbHelper, Task> transactionalOperations){await using var conn = GetConnection();await conn.OpenAsync();await using var tran = await conn.BeginTransactionAsync();try{var tranHelper = new SqlHelperWithTransaction(conn, tran, _connectionFactory.DbProvider, _logger, _retryPolicy, _redisCacheHelper);await transactionalOperations(tranHelper);await tran.CommitAsync();}catch (Exception ex){await tran.RollbackAsync();_logger?.LogError(ex, "Transaction failed.");throw;}}public Task<string> BuildPagedQuery(string baseSql, string orderBy, int pageIndex, int pageSize){int offset = (pageIndex - 1) * pageSize;string pagedSql = _connectionFactory.DbProvider.ToLower() switch{"mysql" => $"{baseSql} ORDER BY {orderBy} LIMIT {offset}, {pageSize}","postgresql" => $"{baseSql} ORDER BY {orderBy} OFFSET {offset} LIMIT {pageSize}",_ => $"{baseSql} ORDER BY {orderBy} OFFSET {offset} ROWS FETCH NEXT {pageSize} ROWS ONLY"};return Task.FromResult(pagedSql);}public async Task<IEnumerable<T>> QueryCachedAsync<T>(string cacheKey, string sql, object? parameters = null, TimeSpan? expiry = null){if (_redisCacheHelper == null)throw new InvalidOperationException("Redis cache helper not configured.");return await _redisCacheHelper.GetOrSetAsync(cacheKey, async () =>{await using var conn = GetConnection();await conn.OpenAsync();return await conn.QueryAsync<T>(sql, parameters);}, expiry);}}
完整源码:【免费】.Net7封装操作数据库,支持MySql、MSSQL、postgresql多数据库操作资源-CSDN文库
相关文章:
SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。
/// <summary> /// SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。 /// </summary> public class SqlHelper : IDbHelper {private readonly IDbConnectionFactory _connectionFactory;private…...

语音识别——声纹识别
通过将说话人的声音与数据库中的记录声音进行比对,判断说话人是否为数据库白名单中的同一人,从而完成语音验证。目前,3D-Speaker 声纹验证的效果较为出色。 3D-Speaker 是一个开源工具包,可用于单模态和多模态的说话人验证、说话…...

window 显示驱动开发-报告图形内存(三)
图形内存报告示例 示例 1:笔记本电脑上的 128 MB 专用板载图形内存 以下屏幕截图显示了使用 Intel Iris 离散图形适配器运行 Windows 11 的 Surface 笔记本电脑的计算图形内存数。 适配器的可用内存总数为 16424 MB,用于图形用途,细分如下&…...
安全运维 -- linux磁盘挂载到windows
0x00 背景 一个需求需要将linux服务器文件同步到windows。在此过程中遇到了三连报错,特此记录一下。 0x00 error 1 一开始死活挂不上,报错 mount: /mnt/Folder: mount(2) system call failed: No route to host. 一开始以为是dns问题,其实…...
使用 Apache POI 生成 Word 文档
创建一个包含标题、段落和表格的简单文档。 步骤 1:添加依赖 确保你的项目中已经添加了 Apache POI 的依赖。如果你使用的是 Maven,可以在 pom.xml 中添加以下内容: <dependency><groupId>org.apache.poi</groupId>...
高防服务器流量“清洗”什么意思
在当今数字化的时代,网络安全成为了备受关注的焦点。其中,高防服务器流量“清洗”这个概念,对于许多朋友来说可能还比较陌生。今天,就让我们一起来揭开它神秘的面纱。 首先,咱们得明白,高防服务器流量“清…...

UE5 GAS框架解析内部数据处理机制——服务器与客户端
当, gas通过点击鼠标光标触发事件时,内部的处理机制。 当通过点击事件,命中中目标时, 可获取到对应的TargetData 目标数据。处理相应的操作。 仅有本地的客户端的情况下。命中并不会有什么异常。 当存在服务器时, 服…...
Unity实用技能-UI定位总结
实用技能系列 Unity实用技能-UI滑动条技能总结Unity实用技能-UI规范总结Unity实用技能-协作规范总结Unity实用技能-UI与粒子效果总结 文章目录 实用技能系列前言什么是定位UI怎么实现定位UI总结 前言 本周接触了UI和定位相关的工作,记录一下 什么是定位UI 一般就是…...

开源GPU架构RISC-V VCIX的深度学习潜力测试:从RTL仿真到MNIST实战
点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,按量计费,灵活弹性,顶级配置,学生专属优惠。 一、开篇:AI芯片架构演变的三重挑战 (引述TPUv4采用RISC-V的行业案…...
服务间的“握手”:OpenFeign声明式调用与客户端负载均衡
现在,假设我们有一个新的order-service,它在创建订单时需要获取用户信息。 如果order-service直接硬编码user-service的IP和端口进行调用,会面临以下问题: 缺乏弹性: 如果user-service实例的IP或端口发生变化(在云环境…...
26、DAPO论文笔记(解耦剪辑与动态采样策略优化,GRPO的改进)
DAPO论文笔记 1、项目背景与目标2、DAPO算法与关键技术3、过长响应奖励塑形(Overlong Reward Shaping)**一、问题背景:截断惩罚的缺陷****二、解决方案:分层惩罚与软截断策略**1. **过长过滤:屏蔽无效惩罚**2. **软过长…...
JQuery 禁止页面滚动(防止页面抖动)
// 禁止页面滑动 function unScroll() {const width $(body).width();$(body).css(width, width px);$(body).css(overflow-y, hidden); }// 移除禁止页面滑动 function reUnScroll() {$(body).css(overflow-y, auto);$(body).css(width, ); }使用场景:鼠标局部滑…...
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七)
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七) 在 Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(六)-CSDN博客 的基础上改进,主要是…...
Halcon与C#:工业级机器视觉开发
Halcon(由MVTec开发)是一款广泛应用于工业机器视觉的高性能软件库,支持C#、C、Python等多种语言。以下是基于C#的Halcon开发详解,涵盖环境配置、核心流程、关键API及最佳实践。 1. 开发环境配置 1.1 安装Halcon …...
Unity序列化字段、单例模式(Singleton Pattern)
一、序列化字段 在Unity中,序列化字段是一个非常重要的概念,主要用于在Unity编辑器中显示和编辑类的成员变量,或者在运行时将对象的状态保存到文件或网络中。 1.Unity序列化字段的作用 在编辑器中显示和编辑字段:默认情况下&…...

【工具】Windows|外接的显示器怎么用软件调亮度(Brightness Slider)
文章目录 工具安装及使用Twinkle Tray:Brightness Slider补充背景知识1. DDC/CI(Display Data Channel Command Interface)2. WMI(Windows Management Instrumentation)3. Twinkle Tray如何结合两者?对比总…...
在 Java MyBatis 中遇到 “操作数类型冲突: varbinary 与 float 不兼容” 的解决方法
在 MyBatis 中遇到 “操作数类型冲突: varbinary 与 float 不兼容” 错误,通常是因为当字段值为 null 时,MyBatis 无法正确推断其 JDBC 类型,导致向数据库传递 null 值时类型不匹配。以下是原因分析和解决方案: 问题原因 未指定 j…...
系统架构设计(十四):解释器风格
概念 解释器风格是一种将程序的每个语句逐条读取并解释执行的体系结构风格。程序在运行时不会先被编译为机器码,而是动态地由解释器分析并执行其语义。 典型应用:Python 解释器、JavaScript 引擎、Bash Shell、SQL 引擎。 组成结构 解释器风格系统的…...

【Nextcloud】使用 LNMP 架构搭建私有云存储:Nextcloud 实战指南
目录 一、环境准备与基础配置 1. 系统环境要求 2. 初始化系统配置 二、搭建 LNMP 基础架构 1. 一键安装 LNMP 组件 2. 启动数据库服务 三、部署 Nextcloud 存储服务 1. 上传并解压安装包 2. 设置目录权限(测试环境配置) 3. 配置 MariaDB 数据库…...
VDC、SMC、MCU怎么协同工作的?
华为视频会议系统中,VDC(终端控制)、SMC(会话管理)、MCU(媒体处理) 通过分层协作实现端到端会议管理,其协同工作机制可总结为以下清晰架构: 1. 角色分工 组件核心职责类…...

【办公类-100-01】20250515手机导出教学照片,自动上传csdn+最小化Vscode界面
背景说明: 每次把教学照片上传csdn,都需要打开相册,一张张截图,然后ctrlV黏贴到CSDN内,我觉得太烦了。 改进思路: 是否可以先把所有照片都上传到csdn,然后再一张张的截图(去掉幼儿…...
Java-List集合类全面解析
Java-List集合类全面解析 前言一、List接口概述与核心特性1.1 List在集合框架中的位置1.2 List的核心特性1.3 常见实现类对比 二、ArrayList源码剖析与应用场景2.1 内部结构与初始化2.2 动态扩容机制2.3 性能特点与最佳实践 三、LinkedList 源码剖析与应用场景3.1 内部结构与节…...

uniapp-商城-60-后台 新增商品(属性的选中和页面显示,数组join 的使用)
前面添加了属性,添加属性的子级项目。也分析了如何回显,但是在添加新的商品的时,我们也同样需要进行选择,还要能正常的显示在界面上。下面对页面的显示进行分析。 1、界面情况回顾 属性显示其实是个一嵌套的数据显示。 2、选中的…...

[c语言日寄]数据结构:栈
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...

WEB安全--Java安全--LazyMap_CC1利用链
一、前言 该篇是基于WEB安全--Java安全--CC1利用链-CSDN博客的补充,上篇文章利用的是TransformedMap类,而CC链的原作者是利用的LazyMap类作为介质进行的触发。 所以本文将分析国外原作者在ysoserial commonscollections1中给出的CC1利用链。 二、回顾梳…...
【杂谈】-AI 重塑体育营销:从内容管理到创意释放的全面变革
AI 重塑体育营销:从内容管理到创意释放的全面变革 文章目录 AI 重塑体育营销:从内容管理到创意释放的全面变革1、加速从采集到推广的内容生命周期2、个性化粉丝体验3、以比赛速度分发体育内容4、让创作者在人工智能(AI)时代自由创…...

黑马k8s(六)
1.Deployment(Pod控制器) Selector runnginx 标签选择:会找pod打的标签 执行删除之后,pod也会删除,Terminating正在删除 如果想要访问其中的一个pod借助:IP地址端口号访问 假设在某一个瞬间,…...
【数据结构】二分查找(返回插入点)5.14
二分查找基础版 package 二分查找; public class BinarySearch { public static void main(String[] args) { // TODO Auto-generated method stub } public static int binarySearchBasic(int[] a,int target) { int i0,ja.length-1; //设置指针初值 while…...
如何设计一个二级缓存(Redis+Caffeine)架构?Redis 6.0多线程模型如何工作?
一、二级缓存(RedisCaffeine)架构设计 1. 设计目标 通过「本地缓存(Caffeine) 分布式缓存(Redis)」的分层结构,实现: 低延迟:热点数据本地缓存(内存级访问…...
Java:logback-classic与slf4j版本对应关系
1、结论 logback-classic-1.2.x及以下版本,则适配的slf4j 1.0.x - 1.7.x logback-classic-1.3.x及以上版本,则适配的slf4j 1.8.x及以上 2、原因分析 (1)logback-classic-1.2.x及以下版本 通过org.slf4j.impl.StaticLoggerBinder初…...