持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
概述:
实际软件使用中,很多场景需要使用数据库。常用的数据库种类很多。针对我们这个小软件,我们选取微型数据库sqllite。
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。\
安装sqlite扩展
选择项目nuget包管理,搜索 System.Data.SQLite,并安装扩展包
新建文件夹,DataBase
在dataBase中新建sqlite操作接口
在database文件夹下,新增加一个类:MySqliteAPI,用来对sqlite的增删改查进行封装。
c#操作sqlite的文章很多,我们这里直接上代码
其中:Data_DB_Name表示我们的数据库存放路径。
using System;
using System.Data;
using System.Data.SQLite;
namespace THSensor
{
/// <summary>
/// 后台服务不修改配置数据库 conf.db
/// 仅仅修改数据存储库 data.db
/// </summary>
internal class MySqliteAPI
{
/// <summary>
/// 数据库名称
/// </summary>
private static string Data_DB_Name = $"{AppDomain.CurrentDomain.BaseDirectory}Conf\\Data.db";
#region 删除
/// <summary>
/// 删除数据
/// </summary>
/// <param name="sqlcmd"></param>
/// <returns></returns>
public static bool DelInfoFromDB(string sqlcmd)
{
try
{
string connectionString = "data source = " + Data_DB_Name;
SQLiteConnection dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
using (SQLiteCommand cmd = new SQLiteCommand())
{
//数据
cmd.Connection = dbConnection;
cmd.CommandText = sqlcmd;
cmd.ExecuteNonQuery();
}
dbConnection.Close();
}
catch (Exception e)
{
MyLogger._.Error(e.Message + e.StackTrace);
return false;
}
return true;
}
#endregion
#region 查询
/// <summary>
/// 查询数据
/// </summary>
/// <param name="sqlcmd"></param>
/// <returns></returns>
public static DataTable GetDataFromDB(string sqlcmd)
{
DataTable res = new DataTable();
SQLiteConnection dbConnection = null;
try
{
//打开连接
string connectionString = "data source = " + Data_DB_Name;
dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
//查询
SQLiteDataAdapter mAdapter = new SQLiteDataAdapter(sqlcmd, dbConnection); ;
mAdapter.Fill(res);
}
catch (Exception ex)
{
MyLogger._.Error(ex.StackTrace + ex.Message);
return null;
}
finally
{
if (dbConnection != null)
dbConnection.Close();
}
return res;
}
#endregion
#region 修改
/// <summary>
/// 修改数据
/// </summary>
/// <param name="sqlcmd"></param>
/// <returns></returns>
public static int UPdateDataToDB(string sqlcmd)
{
int num = 0;
try
{
string connectionString = "data source = " + Data_DB_Name;
SQLiteConnection dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
using (SQLiteCommand cmd = new SQLiteCommand())
{
//数据
cmd.Connection = dbConnection;
cmd.CommandText = sqlcmd;
num = cmd.ExecuteNonQuery();
}
dbConnection.Close();
}
catch (Exception e)
{
MyLogger._.Error(e.StackTrace + e.Message);
return -1;
}
return num;
}
#endregion
#region 插入
/// <summary>
/// 增加信息到数据库
/// </summary>
/// <param name="sqlcmd"></param>
/// <returns></returns>
public static bool InsertDataToDB(string sqlcmd)
{
try
{
string connectionString = "data source = " + Data_DB_Name;
SQLiteConnection dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
using (SQLiteCommand cmd = new SQLiteCommand())
{
//数据
cmd.Connection = dbConnection;
cmd.CommandText = sqlcmd;
cmd.ExecuteNonQuery();
}
dbConnection.Close();
}
catch (Exception e)
{
MyLogger._.Error(e.StackTrace + e.Message);
return false;
}
return true;
}
#endregion
}
}
创建一个数据库文件Data.db
我们在项目的bin目录下,新建一个文件夹conf,下面新建一个数据库文件data.db(数据库可以通过软件,实现创建。也可以通过数据库工具创建。
在这里,我选取的是使用数据库工具nvcat创建的数据库文件。
创建表THData
创建字段
id为主键,自增,类型为整形数据
temp 存储温度,文本
humi存储湿度,文本
intime表示入库时间,文本
完成后如下:
新建一个专注业务逻辑的数据库操作类
在database下新增加一个类,db_serAPI.cs,用来进行业务逻辑的处理 针对我们这个小软件,在此实现一个简单的功能: 点击按钮获取完毕温湿度以后,存储数据库中。
代码:
using System;
using System.Data;
namespace THSensor
{
internal static class DB_SerAPI
{
#region 存储温湿度信息
/// <summary>
/// 存储温湿度信息
/// </summary>
/// <param name="temp"></param>
/// <param name="humi"></param>
/// <returns></returns>
public static bool SaveTHData(string temp, string humi)
{
string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string sqlcmd = $"insert into THData (temp,humi,intime) values('{temp}','{humi}','{time}')";
return MySqliteAPI.InsertDataToDB(sqlcmd);
}
#endregion
}
}
修改页面点击按钮回调,增加入库操作
我们实现的数据库逻辑类为静态类,直接使用类名+方法调用,调用方法如下:
//增加入库操作
if (DB_SerAPI.SaveTHData(temp, humi))
{
MessageBox.Show("入库成功");
}
完整方法如下:
form1.cs
/// <summary>
/// 获取温湿度数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonget_Click(object sender, EventArgs e)
{
if (Runport.IsOpen)
{
//获取地址
byte addr = byte.Parse(this.textBox1.Text);
//string ret = THSensor.ReadTHDataFromSensor(Runport, 0x03);
string ret = THSensor.ReadTHDataFromSensor(Runport, addr);
if (!string.IsNullOrEmpty(ret))
{
string temp = ret.Split('&')[0];
string humi = ret.Split('&')[1];
//赋值
textboxhumi.Text = humi;
textboxtemp.Text = temp;
//增加入库操作
if (DB_SerAPI.SaveTHData(temp, humi))
{
MessageBox.Show("入库成功");
}
}
else
{
MessageBox.Show("无数据,请检查配置参数");
}
}
else
{
MessageBox.Show("串口没有打开");
}
}
测试
获取到的温度:36.4 湿度 30.9 时间 8:55
使用数据库工具查看
解决一些小问题
串口打开后,更新打开按钮状态
在之前我们的代码中,点击确定打开串口后,没有任何的提示。不够人性化。 我们增加一个messagebox告知用户打开成功,同时按钮状态变为关闭
form1.cs
- 新增一个串口打开状态
/// <summary>
/// 串口状态
/// </summary>
private bool portopened = false;
- 修改button1的回调函数
/// <summary>
/// 配置确定按钮回调
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
if (portopened)
{
if (Runport.IsOpen)
{
Runport.Close();
MessageBox.Show("串口已关闭");
this.button1.Text = "打 开 串 口";
this.button1.BackColor = Color.LightGreen;
portopened = false;
}
}
else
{
//串口
string comname = this.comboBox1.Text;
//波特率
int baudrate = int.Parse(this.comboBox2.Text);
//打开串口
Runport = ComPort.V_OpenPort8N1(comname, baudrate);
if (Runport != null)
{
MessageBox.Show("打开串口成功");
this.button1.Text = "关 闭 串 口";
this.button1.BackColor = Color.DarkGray;
portopened = true;
}
else
MessageBox.Show("打开串口失败");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace +"\r\n"+ ex.Message);
}
}
效果如下:
- 打开
- 关闭
下一节将实现利用 dataGridView &定时器 技术实现温湿度的表格显示和定时采集