Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作
场景
Sqlite数据库
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。
它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。
就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。
SQLite 直接访问其存储文件。
需求是在Winform程序启动时进行本地建库建表,然后进行增删改查的逻辑操作。
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
实现
1、本文直接参考博客
SQLite操作指南之.NET篇
https://www.cnblogs.com/wml-it/p/16574254.html
进行调用和适配。
2、Nuget安装System.Data.SQLite.Core

3、封装操作Sqlite的帮助类SqLiteHelper
class SqLiteHelper{/// <summary>/// 数据库连接定义/// </summary>private SQLiteConnection dbConnection;/// <summary>/// SQL命令定义/// </summary>private SQLiteCommand dbCommand;/// <summary>/// 数据读取定义/// </summary>private SQLiteDataReader dataReader;/// <summary>/// 构造函数/// </summary>/// <param name="connectionString">连接SQLite库字符串</param>public SqLiteHelper(string connectionString){try{dbConnection = new SQLiteConnection(connectionString);dbConnection.Open();}catch (Exception e){Log(e.ToString());}}/// <summary>/// 执行SQL命令/// </summary>/// <returns>The query.</returns>/// <param name="queryString">SQL命令字符串</param>public SQLiteDataReader ExecuteQuery(string queryString){try{dbCommand = dbConnection.CreateCommand();dbCommand.CommandText = queryString;dataReader = dbCommand.ExecuteReader();}catch (Exception e){Log(e.Message);}return dataReader;}/// <summary>/// 关闭数据库连接/// </summary>public void CloseConnection(){//销毁Commendif (dbCommand != null){dbCommand.Cancel();}dbCommand = null;//销毁Readerif (dataReader != null){dataReader.Close();}dataReader = null;//销毁Connectionif (dbConnection != null){dbConnection.Close();}dbConnection = null;}/// <summary>/// 读取整张数据表/// </summary>/// <returns>The full table.</returns>/// <param name="tableName">数据表名称</param>public SQLiteDataReader ReadFullTable(string tableName){string queryString = "SELECT * FROM " + tableName;return ExecuteQuery(queryString);}/// <summary>/// 向指定数据表中插入数据/// </summary>/// <returns>The values.</returns>/// <param name="tableName">数据表名称</param>/// <param name="values">插入的数值</param>public SQLiteDataReader InsertValues(string tableName, string[] values){//获取数据表中字段数目int fieldCount = ReadFullTable(tableName).FieldCount;//当插入的数据长度不等于字段数目时引发异常if (values.Length != fieldCount){throw new SQLiteException("values.Length!=fieldCount");}string queryString = "INSERT INTO " + tableName + " VALUES (" + "'" + values[0] + "'";for (int i = 1; i < values.Length; i++){queryString += ", " + "'" + values[i] + "'";}queryString += " )";return ExecuteQuery(queryString);}/// <summary>/// 更新指定数据表内的数据/// </summary>/// <returns>The values.</returns>/// <param name="tableName">数据表名称</param>/// <param name="colNames">字段名</param>/// <param name="colValues">字段名对应的数据</param>/// <param name="key">关键字</param>///<paramname="value">关键字对应的值</param><BR> ///<paramname="operation">运算符:=,<,>,...,默认“=”</param>public SQLiteDataReader UpdateValues(string tableName, string[] colNames, string[] colValues, string key, string value, string operation = "="){//当字段名称和字段数值不对应时引发异常if (colNames.Length != colValues.Length){throw new SQLiteException("colNames.Length!=colValues.Length");}string queryString = "UPDATE " + tableName + " SET " + colNames[0] + "=" + "'" + colValues[0] + "'";for (int i = 1; i < colValues.Length; i++){queryString += ", " + colNames[i] + "=" + "'" + colValues[i] + "'";}queryString += " WHERE " + key + operation + "'" + value + "'";return ExecuteQuery(queryString);}/// <summary>/// 删除指定数据表内的数据/// </summary>/// <returns>The values.</returns>/// <param name="tableName">数据表名称</param>/// <param name="colNames">字段名</param>/// <param name="colValues">字段名对应的数据</param>public SQLiteDataReader DeleteValuesOR(string tableName, string[] colNames, string[] colValues, string[] operations){//当字段名称和字段数值不对应时引发异常if (colNames.Length != colValues.Length || operations.Length != colNames.Length || operations.Length != colValues.Length){throw new SQLiteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length");}string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + "'" + colValues[0] + "'";for (int i = 1; i < colValues.Length; i++){queryString += "OR " + colNames[i] + operations[0] + "'" + colValues[i] + "'";}return ExecuteQuery(queryString);}/// <summary>/// 删除指定数据表内的数据/// </summary>/// <returns>The values.</returns>/// <param name="tableName">数据表名称</param>/// <param name="colNames">字段名</param>/// <param name="colValues">字段名对应的数据</param>public SQLiteDataReader DeleteValuesAND(string tableName, string[] colNames, string[] colValues, string[] operations){//当字段名称和字段数值不对应时引发异常if (colNames.Length != colValues.Length || operations.Length != colNames.Length || operations.Length != colValues.Length){throw new SQLiteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length");}string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + "'" + colValues[0] + "'";for (int i = 1; i < colValues.Length; i++){queryString += " AND " + colNames[i] + operations[i] + "'" + colValues[i] + "'";}return ExecuteQuery(queryString);}/// <summary>/// 创建数据表/// </summary> +/// <returns>The table.</returns>/// <param name="tableName">数据表名</param>/// <param name="colNames">字段名</param>/// <param name="colTypes">字段名类型</param>public SQLiteDataReader CreateTable(string tableName, string[] colNames, string[] colTypes){string queryString = "CREATE TABLE IF NOT EXISTS " + tableName + "( " + colNames[0] + " " + colTypes[0];for (int i = 1; i < colNames.Length; i++){queryString += ", " + colNames[i] + " " + colTypes[i];}queryString += " ) ";return ExecuteQuery(queryString);}/// <summary>/// Reads the table./// </summary>/// <returns>The table.</returns>/// <param name="tableName">Table name.</param>/// <param name="items">Items.</param>/// <param name="colNames">Col names.</param>/// <param name="operations">Operations.</param>/// <param name="colValues">Col values.</param>public SQLiteDataReader ReadTable(string tableName, string[] items, string[] colNames, string[] operations, string[] colValues){string queryString = "SELECT " + items[0];for (int i = 1; i < items.Length; i++){queryString += ", " + items[i];}queryString += " FROM " + tableName + " WHERE " + colNames[0] + " " + operations[0] + " " + colValues[0];for (int i = 0; i < colNames.Length; i++){queryString += " AND " + colNames[i] + " " + operations[i] + " " + colValues[0] + " ";}return ExecuteQuery(queryString);}/// <summary>/// 本类log/// </summary>/// <param name="s"></param>static void Log(string s){Console.WriteLine("class SqLiteHelper:::" + s);}}
注意这里的引入
using System;
using System.Data.SQLite;
4、如果需要在程序启动时执行建库建表等操作,只需要在Program.cs中添加执行代码
上面参考博客中的使用示例
class Program{private static SqLiteHelper sql;static void Main(string[] args){sql = new SqLiteHelper("data source=StudentSystem.db");//创建名为table1的数据表sql.CreateTable("Students", new string[] { "ID", "Name", "Age", "Email" }, new string[] { "INTEGER", "TEXT", "INTEGER", "TEXT" });//插入两条数据sql.InsertValues("Students", new string[] { "1", "张三", "22", "Zhang@163.com" });sql.InsertValues("Students", new string[] { "2", "李四", "25", "Li4@163.com" });//更新数据,将Name="张三"的记录中的Name改为"Zhang3"sql.UpdateValues("Students", new string[] { "Name" }, new string[] { "ZhangSan" }, "Name", "Zhang3");//删除Name="张三"且Age=26的记录,DeleteValuesOR方法类似sql.DeleteValuesAND("Students", new string[] { "Name", "Age" }, new string[] { "张三", "22" }, new string[] { "=", "=" });//读取整张表SQLiteDataReader reader = sql.ReadFullTable("Students");while (reader.Read()){//读取IDLog("ID:" + reader.GetInt32(reader.GetOrdinal("ID")));//读取NameLog("NAME:" + reader.GetString(reader.GetOrdinal("Name")));//读取AgeLog("Age:" + reader.GetInt32(reader.GetOrdinal("Age")));//读取EmailLog("Email:" + reader.GetString(reader.GetOrdinal("Email")));}Console.ReadLine();}static void Log(string s){Console.WriteLine(s);}}
这里只需要在启动后执行建库建表的操作,所以在Program.cs中执行封装的全局工具类方法
namespace DataConvert
{static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);//顺序勿动//初始化positions数据库Global.Instance.InitPositionSqLite();Application.Run(new Form1());}}
}
如上添加一行
Global.Instance.InitPositionSqLite();
注意这行添加的位置。
然后构建一个单例的全局工具类Global
class Global{private SqLiteHelper _sqlLiteHelper;private static string _lockFlag = "GlobalLock";private static Global _instance;//mqtt是否已经连接public bool isMqttClientConnected = false;private Global(){}public static Global Instance{get{lock (_lockFlag){if (_instance == null){_instance = new Global();}return _instance;}}}public SqLiteHelper sqlLiteHelper{get { return _sqlLiteHelper; }set { _sqlLiteHelper = value; }}public void InitPositionSqLite(){_sqlLiteHelper = new SqLiteHelper("data source=positions.db");//创建名为positions的数据表_sqlLiteHelper.CreateTable("positions", new string[] { "timestamp", "data" }, new string[] { "TEXT", "TEXT" });}}
添加一个方法,用来实例化SqlLiteHelp的实例执行建库建表操作
这里创建名为positions.db的库,并且创建名为positions的表,然后该表有两个字段timestamp和data,全部为字符串文本格式。
5、项目启动后查看exe所在同目录下的db文件已经创建成功

6、Sqlite可视化工具DB Browser for SQLite的下载与使用
DB Browser for SQLite:
mirrors / sqlitebrowser / sqlitebrowser · GitCode
下载地址:
Downloads - DB Browser for SQLite
下载并在Windows上解压打开后,双击
DB Browser for SQLite.exe
启动,然后打开数据库,选择上面的db文件
这里可以看到表以及浏览数据和执行sql等操作

7、这样的话就可以在Form1.cs等页面中执行增删改查的逻辑
插入数据时就可以
Global.Instance.sqlLiteHelper.InsertValues("positions", new string[] { time2, "霸道的程序猿"});
其中time2是获取的当前时间戳字符串。
读取整张表的数据
SQLiteDataReader reader = Global.Instance.sqlLiteHelper.ReadFullTable("positions");while (reader.Read()){//读取Console.WriteLine("timestamp:" + reader.GetString(reader.GetOrdinal("timestamp")));Console.WriteLine("data:" + reader.GetString(reader.GetOrdinal("data")));}
如果要读取Sqlite指定表中的前多少行,可以通过执行Sqlite的自定义语句的方式实现
比如要查询前6行
SQLiteDataReader reader = Global.Instance.sqlLiteHelper.ExecuteQuery("SELECT* FROM positions LIMIT 6;");
其他操作都可以通过执行sql语句的方式执行,比如删除指定条件的数据
Global.Instance.sqlLiteHelper.ExecuteQuery("DELETE FROM positions WHERE timestamp = "+ reader.GetString(reader.GetOrdinal("timestamp"))+";");
这里是查询出前6行并挨个操作后删除。
其他更多Sqlite语句的写法和示例可自行网上搜索
SQLite 教程 | 菜鸟教程
相关文章:
Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作
场景 Sqlite数据库 SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其他数据库,SQLite 引擎不…...
2023最新版本RabbitMQ下载安装教程
一、RabbitMQ简介 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。主要用于在进程、应用程序和服务器之间交换数据,可以通过插件支持进行扩展,支持许多协议,并提供高性能、可靠性、集群和高可用队列。 AMQP :Advanced Me…...
如何使用码匠连接 Elasticsearch
目录 在码匠中集成 Elasticsearch 在码匠中使用 Elasticsearch 关于码匠 Elasticsearch 是一个开源的分布式搜索和分析引擎,常用于处理大规模数据集的搜索、实时数据分析和数据挖掘任务。它支持多种数据源,包括关系型数据库(如 MySQL、Pos…...
jmeter学习笔记二(jmeter函数与后置处理器)
Jmeter重要的函数 ${__counter(,)} 计数器 ${__counter(TRUE,)} 默认加1; TRUE,每个用户有自己的计数器;FALSE,使用全局计数器 计数器元件,可以设置起始值,间隔值,最大值。运行结果超过最大值时&a…...
【独家】华为OD机试提供C语言题解 - 子序列长度
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明子序…...
Java之注解
注解1.1 注解的概念1.2 内置注解1.3 元注解1.4 自定义注解1.1 注解的概念 Annotation 是从JDK5.0 开始引入的新技术 Annotation的作用: 不是程序本身,可以对程序做出解释(这一点和注释comment没什么区别)可以被其他程序ÿ…...
【C++】string
【C修炼秘籍】string 目录 【C修炼秘籍】string 文章目录 前言 一、标准库里的string 二、string常用接口功能简介(具体使用和底层转到模拟实现) 1、string类的常见构造函数 2、string类对象的容量操作 3、string类对象的访问及遍历操作 4、 string类对象…...
JVM详解——执行引擎
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:耶瞳空间 一:执行引擎介绍 “虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和…...
python学习——【第二弹】
前言 上一篇文章 python学习——【第一弹】给大家介绍了python中的基本数据类型等,这篇文章接着学习python中的运算符的相关内容。 运算符 python中的运算符主要有:算术运算符,赋值运算符,比较运算符,布尔运算符以及…...
242. 有效的字母异位词 349. 两个数组的交集
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意: 若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat…...
web网页设计——JavaScript一些语法
1、事件监听 语法: <1> 元素对象.addEventListener(‘事件类型’,要执行的函数) 三要素:(1)、事件源 (2)事件类型 (3)执行的函数 <2>元素对象.on事件类型 …...
php宝塔搭建部署实战CSM会议室预约系统源码
大家好啊,我是测评君,欢迎来到web测评。 本期给大家带来一套基于fastadmin开发的CSM会议室预约系统的源码。感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码࿰…...
嵌入式知识点-SPI通讯
该文原自 : 正点原子 01 SPI概述 SPI (Serial Peripheralinterface),顾名思义就是串行外围设备接口。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同…...
C#教程--01 简介
简介 C# 是一个简单的、现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的。 C#的特性 现代的、通用的编程语言。 面向对象。 面向组件。 容易学习。 结构化语言。 它产生高效率的程序。 它可以在多种计算机平台上编译。 .Net 框架的一部分。 C#强大的编程…...
【java基础】一篇文章彻底搞懂lambda表达式
文章目录lambda表达式是什么lambda表达式的语法函数式接口初次使用深入理解方法引用 :: 用法快速入门不同形式的::情况1 object::instanceMethod情况2 Class::instanceMethod情况3 Class::staticMethod对于 :: 的一些示例及其注意事项构造器引用变量作用域使用外部变量定义内部…...
通用SQL查询分析器
技术:Java、JSP等摘要:本文主要针对当前很多软件都无法实现跨数据库、跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件。此软件是一个通用SQL查询分析器,利用java语言本身的跨…...
机器学习100天(三十八):038 朴素贝斯-处理离散数据
《机器学习100天》完整目录:目录 机器学习100天,今天讲的是:朴素贝斯-处理离散数据! 打开 spyder,新建一个 naive_bayes_category.py 脚本。上一节我们引入了一批西瓜样本。并使用朴素贝叶斯公式计算出一个瓜蒂脱落、圆形、青色的西瓜是熟瓜的概率。下面我们来使用 pytho…...
【3.3】指针、二分、SSM项目
二分查找 class Solution {public int search(int[] nums, int target) {int n nums.length;int left 0;int right n - 1;while(left < right){int mid left (right - left) / 2;if(nums[mid] < target){left mid 1;}else if(nums[mid] > target){right mid …...
buu [INSHack2017]rsa16m 1
题目描述: 打开的 rsa_16m 文件 : (在此我只想说神人才找得到 c 的位置) ,这位置是真的难找啊 题目分析: 首先打开 description.md 文件,得到: 翻译下来: 当您需要真正…...
【数据结构起航】:衡量算法的好坏--时间空间复杂度
时间复杂度和空间复杂度 文章目录时间复杂度和空间复杂度1.算法效率1.1算法复杂度1.2复杂度在OJ里的应用2.时间复杂度2.1时间复杂度的概率2.2大O渐进表示法推导大O阶方法:2.3时间复杂度的举例计算3.空间复杂度3.1空间复杂度的举例计算4.复杂度各量级对比1.算法效率 …...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
