QT肝8天07--连接数据库

1、sqlite数据库介绍

SQLite是一款轻量级、自包含的关系型数据库管理系统(RDBMS),以其零配置、单文件存储和嵌入式特性著称‌。以下是其核心特点和应用场景:

核心特性

  1. 无服务器架构
    直接嵌入应用程序进程内,无需独立服务进程,通过API调用操作数据库文件‌。
  1. 单文件存储

    整个数据库(表、索引、事务等)存储于单一磁盘文件,便于备份和传输‌23。

  2. ACID事务支持

    完整支持原子性、一致性、隔离性和持久性,确保数据安全‌34。

  3. 跨平台兼容

    支持Windows、Linux、macOS及移动端(如Android/iOS)‌2。

技术优势

  • 轻量化‌:库文件仅几百KB,内存占用低‌3。
  • 标准SQL支持‌:兼容大部分SQL-92语法,支持视图、触发器等功能‌23。
  • 零配置‌:无需安装或管理,开箱即用‌14。

适用场景

  • 嵌入式设备‌:如物联网终端、智能硬件‌3。
  • 移动应用‌:Android/iOS本地数据存储。
  • 桌面程序‌:小型工具软件的配置管理‌2。
  • 开发测试‌:快速搭建轻量级数据库环境‌

与其他数据库对比

2、qt连接sqlite思路

Qt连接SQLite数据库的核心思路可分为以下几个关键步骤

环境配置

首先需在项目配置文件(.pro)中添加SQL模块依赖:QT += sql,并包含必要的头文件如QSqlDatabaseQSqlQuery等14。

数据库连接建立

  1. 创建连接 ‌:通过QSqlDatabase::addDatabase("QSQLITE")指定SQLite驱动,该驱动为Qt内置无需额外安装 。
  2. 设置数据库文件 ‌:使用setDatabaseName()指定数据库文件路径(如"mydatabase.db"),若文件不存在将自动创建 。
  3. 打开连接 ‌:调用open()方法验证连接是否成功,失败时可利用lastError()获取错误信息 。

数据库操作

  1. 执行SQL语句 ‌:通过QSqlQuery执行建表、插入等操作,例如CREATE TABLE IF NOT EXISTS创建表结构 。
  2. 数据绑定 ‌:使用prepare()bindValue()实现参数化查询,提升安全性和性能 。
  3. 事务处理 ‌:通过transaction()commit()确保批量操作的原子性 。

连接管理

操作完成后需显式调用close()关闭连接,但通常程序退出时会自动释放资源46。对于多连接场景,可通过QSqlDatabase::database()管理命名连接 。

示例流程

cpp 复制代码
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("test.db");
if (!db.open()) {
    qDebug() << "Error:" << db.lastError();
    return;
}
QSqlQuery query;
query.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
db.close();

3、躺平舒服,行动更酷

1、创建目录

在项目根目录下创建目录sqlite3的目的是分类管理文件资源,而不是一大堆文件放在根目录下,显得乱七八糟的,连接数据库采用的是sqlite这种类型的数据库,它是内存数据库,效率高,前面第一个文章介绍过,采用的是sqlite3,怎么获取配置可以百度或我。

2、修改配置

3、添加新文件

要注意的这里添加文件类型是C++类,而不是QT选项中的类型

4、添加方法

5、实现方法

实现头文件中某个方法的快捷键是alt+enter,会弹出一个窗体,一看就明白

cpp 复制代码
#ifndef SQLITE3DB_H
#define SQLITE3DB_H
#include <QDateTime>
#include <QObject>


// 定义一个结构--表示用户
typedef struct {
    quint32 id;        // 用户Id
    QByteArray icon;   // 用户图标
    QString username;  // 用户名
    QString password;  // 密码
    QString name;      // 名称
    int gender;        // 性别
    QString addr;      // 地址
    QString phoneNo;   // 手机号
} OperatorInfo;


class Sqlite3Db
{
public:
    Sqlite3Db();
public:
    bool isContain(QString userName, QString passWord, OperatorInfo &infos); //根据用户和密码判断是否存在

};

#endif // SQLITE3DB_H
cpp 复制代码
#include "sqlite3db.h"
#include <QDebug>
#include <QtSql>
#include <QSqlDatabase>
#include <QSqlQuery>

Sqlite3Db::Sqlite3Db() {}

// Qt访问Sqlite的步骤:
// 1. 引入一个模块 QT       += core gui sql
// 2. 引入头文件
// 3. 使用QSqlDatabase 来进行操作

// 根据用户名和密码来判断,当前的用户是否存在Sqlite数据库中
bool Sqlite3Db::isContain(QString userName, QString passWord, OperatorInfo &infos) {
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
    db.setDatabaseName("warehouse.db");  // 设置数据库名称
    bool isOpen = db.open();//打开连接
    //输出错误信息
    qDebug() << isOpen ;
    qDebug() << db.isValid();  // true
    qDebug() << db.isOpen();   // true

    // 1.准备查询QSqlQuery 对象
    QSqlQuery query(db);
    // 2. 准备Sql语句? :占位符---避免sql注入
    QString sqlCmd = QString("SELECT * from operatorInfo where username=? and password=?");

    // 3.准备参数化占位符的数据
    query.prepare(sqlCmd);
    query.bindValue(0, userName);
    query.bindValue(1, passWord);

    //4.开始执行语句
    bool success = query.exec();
    if (success == false) {
        db.close();  // 网络资源,需要回收
        return false;
    }
    if (query.next() == false) {
        db.close();  // 网络资源,需要回收
        return false;
    }
    // 如果继续往后执行,就是已经买查询到对象了,返回这个对象的每个属性值
    OperatorInfo i;
    i.id = query.value(0).toInt();
    i.icon = query.value(1).toByteArray();
    i.username = query.value(2).toString();
    i.password = query.value(3).toString();
    i.addr = query.value(4).toString();
    i.gender = query.value(5).toInt();
    i.name = query.value(6).toString();
    i.phoneNo = query.value(7).toString();
    infos = i;
    db.close();
    return true;
}

6、完善登录

cpp 复制代码
#include "loginwin.h"
#include "ui_loginwin.h"
#include <QPushButton>
#include <QDebug>
#include <QPainter>
#include <QRandomGenerator>
#include <sqlite3/sqlite3db.h>
#include <QMessageBox>

LoginWin::LoginWin(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::LoginWin)
{
    ui->setupUi(this);

    //设置密码框的字符显示
    ui->editpass->setEchoMode(QLineEdit::Password);

    //创建基类窗体对象
    if(m_baseWind==nullptr){
        m_baseWind=new BaseWin(parent);
    }
    //  m_baseWind->resize(600,200);
    m_baseWind->setContentWidget(this);//将当前登录窗体放到基类的内容控件中
    m_baseWind->setTitle("用户登录");
    QPushButton *login=m_baseWind->getButton();
    if(login==nullptr){
        return;
    }else{
        login->setText("登录系统");
        //绑定单击和槽函数
        connect(login,&QPushButton::clicked,this,&LoginWin::onLogin);
    }

    //初始化面板样式
    ui->edituser->setPlaceholderText("请输入您的帐号");
    ui->editpass->setPlaceholderText("请输入您的密码");
    ui->editcode->setPlaceholderText("请输入验证码");

    //默认隐藏错误提示,字体样式为红色
    ui->msguser->setStyleSheet("color:red");
    ui->msguser->hide();
    ui->msgpass->setStyleSheet("color:red");
    ui->msgpass->hide();
    ui->msgcode->setStyleSheet("color:red");
    ui->msgcode->hide();

    // 二维码初始化
    m_captcha = getCaptcha();

}

LoginWin::~LoginWin()
{
    delete ui;
}


//登录
void LoginWin::onLogin()
{
    //获取验证码
    QString verCode=ui->editcode->text();

    //校验证用户名不能为空
    QString username = ui->edituser->text();
    if (username.isNull() || username.isEmpty()) {
        ui->msguser->setText("请输入用户名");
        ui->msguser->show();
        return;
    }
    //校验证密码不能为空
    QString password = ui->editpass->text();
    if (password.isNull() || password.isEmpty()) {
        ui->msgpass->setText("请输入密码");
        ui->msgpass->show();
        //initVerCode();
        return;
    }
    //校验验证码不能为空
    if(verCode.isNull()||verCode.isEmpty()){
        ui->msgcode->setText("验证码不能为空");
        ui->msgcode->show();
        return;
    }
    //校验验证码是否正确
    if (m_captcha.compare(verCode, Qt::CaseInsensitive)) {
        ui->msgcode->setText("验证码错误");
        ui->msgcode->show();
        return;
    }

    //连接数据库
    Sqlite3Db db;
    OperatorInfo user;
    bool success=db.isContain(username,password,user);
    //信息提示
    if(success){
        QMessageBox::information(this,"信息提示","登录成功,欢迎使用本系统.");
    }else{
        QMessageBox::critical(this,"错误提示","帐号或密码错误!");
    }

}



//显示窗体
void LoginWin::showLogin()
{
    m_baseWind->show();//调用基类的显示方法
}

// 绘图--绘制验证码
void LoginWin::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    // 填充背景为白色
    painter.fillRect(ui->Codelab->x() + ui->widgetVer->x(),
                     ui->Codelab->y() + ui->widgetVer->y(),
                     ui->Codelab->width(),
                     ui->Codelab->height(), Qt::white);

    // 设置字体样式
    painter.setFont(QFont("Lucida Console", 20, QFont::Bold));

    // 绘制验证码字符
    for (int i = 0; i < 4; i++) {
        QColor color = generateRandomColor();  // 随机获取颜色
        // 生成随机颜色
        QPen pen(color);
        pen.setWidth(1);
        painter.setPen(pen);
        painter.drawText(ui->Codelab->x() + ui->widgetVer->x() + 20 * i,
                         ui->Codelab->y() + ui->widgetVer->y(), 20,
                         ui->Codelab->height(), Qt::AlignCenter,
                         QString(m_captcha[i]));
    }

    // 绘制噪点
    for (int i = 0; i < 400; i++) {
        QColor color = generateRandomColor();
        // 生成随机颜色
        QPen pen(color);
        pen.setWidth(1);
        painter.setPen(pen);
        painter.drawPoint(ui->Codelab->x() + ui->widgetVer->x() +
                              (rand() % ui->Codelab->width()),
                          ui->Codelab->y() + ui->widgetVer->y() +
                              (rand() % ui->Codelab->height()));
    }

    // 注册事件过滤器
    ui->Codelab->installEventFilter(this);
}


// 在字符串中随机获取四个字符
QString LoginWin::getCaptcha() {
    const QString possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    const int captchaLength = 4;
    QString result = "";
    // 生成验证码字符串
    for (int i = 0; i < captchaLength; ++i) {
        int index = QRandomGenerator::global()->bounded(possibleCharacters.length());
        // 生成一个0到possibleCharacters长度之间的随机整数
        result.append(possibleCharacters.at(index));
        // 将随机位置的字符添加到结果字符串中
    }
    return result;
}

// 刷新验证码
void LoginWin::initVerCode() {
    m_captcha = getCaptcha();         // 获取新的验证码
    m_color = generateRandomColor();  // 生成随机颜色
    repaint();                        // 重新绘制窗口
    update();
    ui->Codelab->setText("");
}


//  随机获取颜色
QColor LoginWin::generateRandomColor() {
    int red = QRandomGenerator::global()->bounded(256);
    // 生成0到255之间的随机整数作为红色通道的值
    int green = QRandomGenerator::global()->bounded(256);
    // 生成0到255之间的随机整数作为绿色通道的值
    int blue = QRandomGenerator::global()->bounded(256);
    // 生成0到255之间的随机整数作为蓝色通道的值
    return QColor(red, green, blue);
    // 使用生成的RGB值创建并返回一个QColor对象
}

// 事件过滤器
bool LoginWin::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::MouseButtonPress) {
        if (obj == ui->Codelab) {
            // 初始化,重新生成验证码
            initVerCode();
            return false;
        }
    }
    return false;
}

7、sqlitestudio介绍

SQLiteStudio 是一款免费开源的跨平台 SQLite 数据库管理工具,提供图形化界面简化数据库操作‌以下是其核心功能与特点:

核心功能

  1. 数据库管理

    • 支持创建、连接、导出/导入数据库文件,并提供备份与还原功能‌。
    • 可通过右键菜单或工具栏快速操作数据库(如新建表、修改表结构)‌。
  2. 数据操作

    • 支持浏览、编辑表数据,并提供导入/导出功能(格式包括 CSV、SQL、XML 等)‌。
    • 支持二进制字段的查看与编辑‌。
  3. SQL 支持

    • 内置高级 SQL 编辑器,提供语法高亮、自动补全、错误检查及历史记录功能‌。
    • 支持跨数据库查询,可同时操作多个数据库文件‌。
  4. 扩展功能

    • 支持加密数据库(如 SQLCipher)和自定义 SQL 函数(通过 JavaScript/Python 实现)‌。
    • 提供事务处理、日志查看及权限管理工具‌。

特点与优势

  • 跨平台‌:兼容 Windows、Linux、macOS,提供免安装便携版本‌。
  • 轻量高效‌:界面简洁,资源占用低,适合嵌入式或移动开发场景‌。
  • 开源免费‌:基于 GPLv3 协议,可商用且代码开放‌。

使用示例

  1. 导出表数据‌:选择表 → 点击"导出数据" → 设置格式(如 CSV)‌。
  2. 创建表‌:右键数据库 → 选择"Create Table" → 定义列名、数据类型及主键

这里介绍一下SQLiteStudio,这是连接sqlite数据库的客户端图形工具,有很多工具可以连接sqlite数据库,这里就不举例了,反正能连接使用操作就行。

4、运行效果

原创不易,打字不易,截图不易,撸码不易,整理不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,灌水,动动你的金手指,祝您早日实现财务自由。

相关推荐
WaWaJie_Ngen3 小时前
LevOJ P2080 炼金铺 II [矩阵解法]
c++·线性代数·算法·矩阵
lagelangri6663 小时前
MySql的存储过程以及JDBC实战
android·数据库·mysql
姝孟3 小时前
笔记(C++篇)—— Day 12(类的默认成员函数)
c++·笔记·学习
ManThink Technology3 小时前
实用的LoRaWAN 应用层协议规范
开发语言·php
敲代码的嘎仔3 小时前
牛客算法基础noob59 简写单词
java·开发语言·数据结构·程序人生·算法·leetcode·学习方法
catchadmin3 小时前
如何在 PHP 升级不踩坑?学会通过阅读 RFC 提前预知版本变化
开发语言·后端·php
tpoog4 小时前
[C++项目组件]Elasticsearch简单介绍
开发语言·c++·elasticsearch
特立独行的猫a6 小时前
C 语言各种指针详解
java·c语言·开发语言
彭于晏Yan7 小时前
MyBatis-Plus使用动态表名分表查询
java·开发语言·mybatis