当前位置: 首页 > news >正文

关于C#操作SQLite数据库的一些函数封装

主要功能:增删改查、自定义SQL执行、批量执行(事务)、防SQL注入、异常处理


1.NuGet中安装System.Data.SQLite


2.SQLiteHelper的封装:
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;namespace inventory_management_system.jdbc
{public class SQLiteHelper{private SQLiteConnection _connection;public SQLiteHelper(string databasePath){_connection = new SQLiteConnection($"Data Source={databasePath};Version=3;BinaryGUID=False;");}public void OpenConnection(){if (_connection.State != ConnectionState.Open){_connection.Open();}}public void CloseConnection(){if (_connection.State != ConnectionState.Closed){_connection.Close();}}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="key_values">键值对字典</param>/// <returns>int</returns>public int Insert(string tableName, List<SQLiteParameter> parameters){using (var cmd = _connection.CreateCommand()){// 添加参数到命令对象  cmd.Parameters.AddRange(parameters.ToArray());// 构建INSERT语句的列名部分和值部分  string columnNames = string.Join(",", parameters.Select(p => p.ParameterName));string placeholders = string.Join(",", parameters.Select(p => "@"+p.ParameterName));// 构建完整的INSERT语句  string query = $"INSERT INTO {tableName} ({columnNames}) VALUES ({placeholders});";cmd.CommandText = query;// 执行命令并返回受影响的行数  return cmd.ExecuteNonQuery();}}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="key_values">键值对字典</param>/// <returns>int</returns>public int Insert(string tableName, Dictionary<string, object> key_values){using (var cmd = _connection.CreateCommand()){List<string> columns = new List<string>();List<SQLiteParameter> parameters = new List<SQLiteParameter>();int index = 0;foreach (var kvp in key_values){columns.Add(kvp.Key);parameters.Add(new SQLiteParameter($"@{kvp.Key}", kvp.Value));cmd.Parameters.Add(parameters[index]);index++;}string query = $"INSERT INTO {tableName} ({string.Join(",", columns)}) VALUES ({string.Join(",", parameters.Select(p => "@" + p.ParameterName))});";cmd.CommandText = query;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行更新操作/// </summary>/// <param name="tableName">表名</param>/// <param name="setValues">新数据</param>/// <param name="whereClause">条件</param>/// <param name="parameters">条件数据</param>/// <returns>int</returns>public int Update(string tableName, Dictionary<string, object> setValues, string whereClause, List<SQLiteParameter> parameters){using (var cmd = _connection.CreateCommand()){List<string> setColumns = new List<string>();int index = 0;foreach (var kvp in setValues){setColumns.Add($"{kvp.Key} = @{kvp.Key}");cmd.Parameters.Add(new SQLiteParameter($"@{kvp.Key}", kvp.Value));index++;}string query = $"UPDATE {tableName} SET {string.Join(",", setColumns)} WHERE {whereClause}";cmd.CommandText = query;cmd.Parameters.AddRange(parameters.ToArray());return cmd.ExecuteNonQuery();}}/// <summary>/// 执行删除操作/// </summary>/// <param name="tableName">表名</param>/// <param name="whereClause">条件</param>/// <param name="parameters">参数数据</param>/// <returns>int</returns>public int Delete(string tableName, string whereClause, List<SQLiteParameter> parameters){using (var cmd = _connection.CreateCommand()){cmd.CommandText = $"DELETE FROM {tableName} WHERE {whereClause};";cmd.Parameters.AddRange(parameters.ToArray());return cmd.ExecuteNonQuery();}}/// <summary>/// 执行查询操作/// </summary>/// <param name="sql">sql语句</param>/// <param name="parameters">参数数据</param>/// <returns>DataTable</returns>public DataTable Select(string sql, List<SQLiteParameter> parameters){DataTable dt = new DataTable();using (var cmd = _connection.CreateCommand()){cmd.CommandText = sql;cmd.Parameters.AddRange(parameters.ToArray());using (var reader = cmd.ExecuteReader()){dt.Load(reader);}}return dt;}/// <summary>/// 执行自定义SQL语句,返回影响行数/// </summary>/// <param name="sql"></param>/// <returns>int类型</returns>public int ExecuteSQL(string sql){using (var cmd = _connection.CreateCommand()){cmd.CommandText = sql;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行自定义SQL语句,返回影响行数/// </summary>/// <param name="sql"></param>/// <param name="parameters"></param>/// <returns>int类型</returns>public int ExecuteSQL(string sql, List<SQLiteParameter> parameters){using (var cmd = _connection.CreateCommand()){cmd.CommandText = sql;cmd.Parameters.AddRange(parameters.ToArray());return cmd.ExecuteNonQuery();}}/// <summary>/// 执行自定义sql查询语句,如果你计划对返回的 DataTable 进行大量的后续操作(例如,添加或删除行,修改列值等),那么使用 SQLiteDataAdapter 可能会更有优势,因为它提供了更高级的数据绑定和更新功能/// </summary>/// <param name="sql"></param>/// <param name="parameters"></param>/// <returns>DataTable</returns>public DataTable ExecuteSelect(string sql, List<SQLiteParameter> parameters){using (SQLiteCommand command = _connection.CreateCommand()){command.CommandText = sql;command.Parameters.AddRange(parameters.ToArray());using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(command)){DataTable dataTable = new DataTable();adapter.Fill(dataTable); // 填充数据表  return dataTable; // 返回查询结果的数据表  }}}/// <summary>/// 批量操作/// </summary>/// <param name="sql"></param>/// <param name="parameters"></param>/// <returns></returns>public int BatchExecuteSQL(string sql, List<List<SQLiteParameter>> parameters){int affectedRows = 0;using (var transaction = _connection.BeginTransaction()){try{using (var cmd = _connection.CreateCommand()){cmd.Transaction = transaction;foreach (var paramList in parameters){cmd.CommandText = sql;cmd.Parameters.Clear();cmd.Parameters.AddRange(paramList.ToArray());affectedRows += cmd.ExecuteNonQuery();}transaction.Commit(); // 提交事务  }}catch (Exception ex){transaction.Rollback(); // 发生异常时回滚事务  throw; // 重新抛出异常,以便上层调用者处理  }}return affectedRows;}}
}

3.SQLiteHelper使用示例:
public void test(){string databasePath = "path_to_your_database.db"; // 替换为你的数据库文件路径  SQLiteHelper helper = new SQLiteHelper(databasePath);try{// 打开数据库连接  helper.OpenConnection();// 插入数据示例  Dictionary<string, object> valuesToInsert = new Dictionary<string, object>{{ "Name", "John Doe" },{ "Age", 30 },{ "Email", "johndoe@example.com" }};int insert_count = helper.Insert("Users", valuesToInsert);// 插入数据示例  List<SQLiteParameter> insert_parameters = new List<SQLiteParameter>(){new SQLiteParameter( "Name", "John Doe" ),new SQLiteParameter("Age", 30 ),new SQLiteParameter("Email", "johndoe@example.com")};int insert_count2 = helper.Insert("Users", insert_parameters);// 更新数据示例  Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>{{ "Age", 31 }};int update_count = helper.Update("Users", valuesToUpdate, "Name = @Name", new List<SQLiteParameter>(){ new SQLiteParameter("@Name", "John Doe") });// 删除数据示例  int delete_count = helper.Delete("Users", "Name = @Name", new List<SQLiteParameter>() { new SQLiteParameter("@Name", "John Doe") });// 查询数据示例  DataTable dataTable = helper.Select("SELECT * FROM Users WHERE Name = @Name", new List<SQLiteParameter>() { new SQLiteParameter("@Name", "John Doe") });foreach (DataRow row in dataTable.Rows){Console.WriteLine($"Name: {row["Name"]}, Age: {row["Age"]}, Email: {row["Email"]}");}//批量操作示例string sql = "INSERT INTO Users (Name,Age,Email) VALUES (@Name,@Age,@Email);";List<List<SQLiteParameter>> parameterList = new List<List<SQLiteParameter>>();for (int i = 0; i < 10; i++){List<SQLiteParameter> parameters = new List<SQLiteParameter>();parameters.Add(new SQLiteParameter("@Name", $"名字{i}"));parameters.Add(new SQLiteParameter("@Age", i));parameters.Add(new SQLiteParameter("@Email", $"邮箱{i}"));parameterList.Add(parameters);}int batch_count = helper.BatchExecuteSQL(sql, parameterList);}catch (Exception ex){Console.WriteLine("An error occurred: " + ex.Message);}finally{// 关闭数据库连接  helper.CloseConnection();}}

注意:在构建sql语句时,占位符尽量不要用"?",虽然大多数据库用"?"是标准做法,但是本人用System.Data.SQLite实际操作过程中,很多情况会报数据类型不匹配异常,最好还是用"@前缀"好一点

相关文章:

关于C#操作SQLite数据库的一些函数封装

主要功能&#xff1a;增删改查、自定义SQL执行、批量执行&#xff08;事务&#xff09;、防SQL注入、异常处理 1.NuGet中安装System.Data.SQLite 2.SQLiteHelper的封装&#xff1a; using System; using System.Collections.Generic; using System.Data.SQLite; using System.…...

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;回溯 回溯三部曲。这里比较关键的是给board做标记&#xff0c;防止之后搜索时重复访问。解题思路二&#xff1a;回溯算法 dfs,直接看代码,很容易理解。visited哈希&#xff0c;防止…...

游戏引擎之高级动画技术

一、动画混合 当我们拥有各类动画素材&#xff08;clips&#xff09;时&#xff0c;要将它们融合起来成为一套完整的动画。 最经典的例子就是从走的动画自然的过渡到跑的动画。 1.1 线性插值 不同于上节课的LERP&#xff08;同一个clip内不同pose之间&#xff09;&#xff…...

Oracle 数据库中的全文搜索

Oracle 数据库中的全文搜索 0. 引言1. 整体流程2. 创建索引2-1. 创建一个简单的表2-2. 创建文本索引2-3. 查看创建的基础表 3. 运行查询3-1. 运行文本查询3-2. CONTAINS 运算符3-3. 混合查询3-4. OR 查询3-5. 通配符3-6. 短语搜索3-7. 模糊搜索&#xff08;Fuzzy searches&…...

代码随想录阅读笔记-二叉树【二叉搜索树中的众数】

题目 给定一个有相同值的二叉搜索树&#xff08;BST&#xff09;&#xff0c;找出 BST 中的所有众数&#xff08;出现频率最高的元素&#xff09;。 假定 BST 有如下定义&#xff1a; 结点左子树中所含结点的值小于等于当前结点的值结点右子树中所含结点的值大于等于当前结点的…...

AcWing-游戏

1388. 游戏 - AcWing题库 所需知识&#xff1a;博弈论&#xff0c;区间dp 由于双方都采取最优的策略来取数字&#xff0c;所以结果为确定的&#xff0c;有可能会有多个不同的过程&#xff0c;但是我们只需要关注最终结果就行了。 方法一&#xff1a; 定义dp[i][j] 表示区间…...

Mybatis——一对一映射

一对一映射 预置条件 在某网络购物系统中&#xff0c;一个用户只能拥有一个购物车&#xff0c;用户与购物车的关系可以设计为一对一关系 数据库表结构&#xff08;唯一外键关联&#xff09; 创建两个实体类和映射接口 package org.example.demo;import lombok.Data;import …...

Web 安全之 SSL 剥离攻击详解

目录 SSL/TLS简介 SSL 剥离攻击原理 SSL 剥离攻击的影响 SSL 剥离攻击的防范措施 小结 SSL 剥离攻击&#xff08;SSL Stripping Attack&#xff09;是一种针对安全套接层&#xff08;SSL&#xff09;或传输层安全性&#xff08;TLS&#xff09;协议的攻击手段&#xff0c;…...

数据结构——顺序表(C语言)

目录 一、顺序表概念 二、顺序表分类 1.静态顺序表 2.动态顺序表 三、顺序表的实现 1.顺序表的结构体定义 2. 顺序表初始化 3.顺序表销毁 4.顺序表的检验 5.顺序表打印 6.顺序表扩容 7.顺序表尾插与头插 8.尾删与头删 9.在pos处插入数据 10.在pos处删除数据 11.查找数据 …...

利用Idea实现Ajax登录(maven工程)

一、新建一个maven工程&#xff08;不会建的小伙伴可以参考Idea引入maven工程依赖(保姆级)-CSDN博客&#xff09;&#xff0c;工程目录如图 ​​​​​​​ js文件可以上up网盘提取 链接&#xff1a;https://pan.baidu.com/s/1yOFtiZBWGJY64fa2tM9CYg?pwd5555 提取码&…...

环信IM集成教程——Web端UIKit快速集成与消息发送

写在前面&#xff1a; 千呼万唤始出来&#xff0c;环信Web端终于出UIKit了&#xff01;&#x1f389;&#x1f389;&#x1f389; 文档地址&#xff1a;https://doc.easemob.com/uikit/chatuikit/web/chatuikit_overview.html 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开…...

Anaconda如何切换国内镜像源

一、anaconda如何切换阿里镜像源 在Anaconda中切换到阿里云镜像源可以通过以下步骤进行&#xff1a; 1、打开终端&#xff08;Windows&#xff09;或者命令行界面&#xff08;macOS/Linux&#xff09;。 2、执行以下命令来配置阿里云镜像源&#xff1a; conda config --add…...

Android 14.0 添加自定义服务,并生成jar给第三方app调用

1.概述 在14.0系统ROM产品定制化开发中,由于需要新增加自定义的功能,所以要增加自定义服务,而app上层通过调用自定义服务,来调用相应的功能,所以系统需要先生成jar,然后生成jar 给上层app调用,接下来就来分析实现的步骤,然后来实现相关的功能 从而来实现所需要的功能 …...

解决沁恒ch592单片机在tmos中使用USB总线时,接入USB Hub无法枚举频繁Reset的问题

开发产品时采用了沁恒ch592&#xff0c;做USB开发时遇到了一个奇葩的无法枚举问题。 典型症状 使用USB线直连电脑时没有问题&#xff0c;可以正常使用。 如果接入某些特定方案的USB Hub&#xff08;例如GL3510、GL3520&#xff09;&#xff0c;可能会出现以下2种情况&#xf…...

nvm保姆级安装使用教程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…...

大语言模型LLM《提示词工程指南》学习笔记02

文章目录 大语言模型LLM《提示词工程指南》学习笔记02设计提示时需要记住的一些技巧零样本提示少样本提示链式思考&#xff08;CoT&#xff09;提示自我一致性生成知识提示 大语言模型LLM《提示词工程指南》学习笔记02 设计提示时需要记住的一些技巧 指令 您可以使用命令来指…...

【realme x2手机解锁BootLoader(简称BL)】

realme手机解锁常识 https://www.realme.com/cn/support/kw/doc/2031665 realme手机解锁支持型号 https://www.realmebbs.com/post-details/1275426081138028544 realme x2手机解锁实践 参考&#xff1a;https://www.realmebbs.com/post-details/1255473809142591488 1 下载apk…...

攻防世界 wife_wife

在这个 JavaScript 示例中&#xff0c;有两个对象&#xff1a;baseUser 和 user。 baseUser 对象定义如下&#xff1a; baseUser { a: 1 } 这个对象有一个属性 a&#xff0c;其值为 1&#xff0c;没有显式指定原型对象&#xff0c;因此它将默认继承 Object.prototype。 …...

Visual Studio安装下载进度为零已解决

因为在安装pytorch3d0.3.0时遇到问题&#xff0c;提示没有cl.exe&#xff0c;VS的C编译组件&#xff0c;可以添加组件也可以重装VS。查了下2019版比2022问题少&#xff0c;选择了安装2019版&#xff0c;下面是下载安装时遇到的问题记录&#xff0c;关于下载进度为零网上有三类解…...

矩阵空间秩1矩阵小世界图

文章目录 1. 矩阵空间2. 微分方程3. 秩为1的矩阵4. 图 1. 矩阵空间 我们以3X3的矩阵空间 M 为例来说明相关情况。目前矩阵空间M中只关心两类计算&#xff0c;矩阵加法和矩阵数乘。 对称矩阵-子空间-有6个3X3的对称矩阵&#xff0c;所以为6维矩阵空间上三角矩阵-子空间-有6个3…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...