当前位置: 首页 > 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…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...