Qt day8 数据库编程

Qt数据库编程


1.项目文件添加sql  、添加头文件


#include 数据库连接处理        eg:QSqlDatabase db_student
#include 连接完成后操作数据库
#include 打印数据库相关错误
私有成员:    
    QSqlDatabase db_student;    //创建的数据库连接
        QString db_file;            //数据库的文件名

数据库文件命名 可以通过给定默认参数(db后缀 声明写了默认值,则定义只需要写类型)
比如          explicit Widget(QWidget *parent = 0,QString file_name = "student.db");  
        Widget::Widget(QWidget *parent,QString file_name) :
            QWidget(parent),db_file(file_name),
               ui(new Ui::Widget)                //数据库文件名为student.db
括号内是给定默认值(这里是把QString xxx给了定义的file_name),冒号后是初始化列表(常给成员变量赋值,这里是把括号内初始化的file_name给了QString类型的数据库文件名db_file -- 后面需要给数据库连接设置这个QString类型的名字)

构造函数:


2.数据库连接db_student = QSqlDatabase::addDatabase("QSQLITE","连接名 ");


2.1声明定义一个QSqlDatabase类的对象,db_student,用来创建连接
2.2连接名qt_sql_default_connection通过使用不同的连接名称,你可以在同一应用程序中管理多个数据库连接。
2.3数据库本地文件名student.db,用来检查数据库文件是否存在,以及本地使用

3.绑定数据库连接对象和数据库名字     打开数据库    检查数据库文件是否存在


3.1db_student.setDatabaseName(db_file);//通过连接绑定数据库本地名
3.2    if(!db_student.open())//通过连接打开数据库 返回布尔值 失败通过db_student.lastError().text()打印
3.3    QFile file(db_file);bool isFileExists = file.exists();//文件操作 判断student.db是否存在于本地

4.操作数据库(如果数据库文件不存在 if (!isFileExists))


QSqlQuery query(db_student);    //使用数据库连接对象建表(此处使用连接名query()括号里不写东西则使用上面addDatabase缺省的连接名 我觉得要不写都不写 要写都写 建议都写-add连接时要写连接名,query操作数据库时要写数据库连接对象名)
4.1 写出str并执行query.exec(str)    (注意判错)    ----如果数据库不存在则执行下列初始值插入操作
创建表: QString str = "create table Student(num varchar(64) primary key, name varchar(128), sex varchar(16), age varchar(16) )";    --表名为Student,完整的指令    ----直接执行完整语句
if(!query.exec(str)){}qDebug()< 插入数据1:str = "insert into Student values('2024','zhangsan','boy','18')";    ----直接执行完整语句 常用!
if(!query.exec(str)){} query.lasterror().text();
插入数据2:    str = "insert into Student values(?,?,?,?)";        ----待定问号数据依次插入addbindvalue(??--add)
query.prepare(str);//query准备执行str
query.addBindValue("2025");    //双引号                ?和:xx都是占位符
query.addBindValue("mike");
插入数据3:    str = "insert into Student values(:xx,:xxx,:sex,:age)";    ----冒号替换式插入bindvalue    
query.prepare(str);
query.BindValue(":xx","2026");
query.BindValue(":xxx","xiaoming");
......
if (!query.exec())        //prepare则exec(无参数)
插入数据4:str = "insert into Student values(:num,:name,:sex,:age)";    ----冒号数字替换式插入bindvalue    常用!
query.prepare(str);
query.bindValue(0,"20240105004");
if (!query.exec())

如果数据库文件(.db)不存在,则创建表并插入初始值


5.展示表的函数


调用showInfo();

析构函数:
delete ui;
db_student.close();

6.清除行编辑器、下拉列表框置为-1//0表示第一个选项 1表示第二个选项
写clearInputs函数


void Widget::clearInputs()
{
    ui->cb_sex->setCurrentIndex(-1);        //下拉列表框函数还需熟悉
    ui->le_age->clear();
    ui->le_name->clear();
    ui->le_num->setText("2024010500");
}

7.写showInfo函数


7.1查找


执行QString str  =  "select *from Student";
QSqlQuery query(db_student)对象操作数据库 执行query.exec()程序并判错


7.2清空文本编辑框


7.3循环检索    


//QList是表格的意思,要加<存储的列表类> QStringList是Qt中用于存储字符串列表的类  Qstring用来处理单个字符串。
    QList list;    
    while(query.next()){    //遍历所有查询到的记录
        QStringList record;
        for(int i=0;i<4;i++){
            record<         }
        list.append(record);    //record里面有多个散的QStringList    每个QStringList又包含多个QString
    }
//理解:提取每一行的各个字段值,并将这些值存储在一个字符串列表中。然后,这些字符串列表被添加到一个主列表中。小明 男 25 2021 小红 女 21 2020...每一次完整for循环(4次)表示一条数据收集完成


7.3“    循环检索


    ui->te->clear();//显示前清空文本编辑框
    while(query.next())//下一条不为空
    {
        QString tmp;
        tmp += query.value(0).toString() + " ";//学号
        tmp += query.value(1).toString() + " ";//姓名
        tmp += query.value(2).toString() + " ";//性别
        tmp += query.value(3).toString();      //年龄
        ui->te->append(tmp);
    }


8 转到槽函数


8.1新增


void Widget::on_pb_new_clicked()
{
    QString str = "insert into Student values(:1,:1,:1,:1)";
    QSqlQuery query(db_student);
    query.prepared(str);
    query.BindValues(0,ui->le_num->text());
        query.bindValue(1,ui->le_name->text());
        query.bindValue(2,ui->cb_sex->currentText());
        query.bindValue(3,ui->le_age->text());
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<                 qDebug()<             return;
        }
        showInfo();
        clearInputs();    
}


8.2删除


void Widget::on_pb_delete_clicked()//???
{
    QString str = "delete from Student where num=?";//把所有学号为这个的记录都删掉
    QSqlQuery query;
    query.prepare(str);
    query.addBindValue(ui->le_num->text());

    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<         qDebug()<         return;
    }
    showInfo();
    clearInputs();
}

8.3查找


void Widget::on_pb_search_clicked()
{
    QString str = "select * from Student where num=?";//把所有学号为这个的记录都删掉
    QSqlQuery query;
    query.prepare(str);//非完整语句传str参数后,随后调用query.exec(),取!判错
    query.addBindValue(ui->le_num->text());

    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<         qDebug()<         return;
    }

    if(query.first()){
        ui->le_name->setText(query.value(1).toString());
        ui->cb_sex->setCurrentText(query.value(2).toString());
        ui->le_age->setText(query.value(3).toString());
    }
}

8.4修改


void Widget::on_pb_search_clicked()
{
    QString str = "select * from Student where num=?";//把所有学号为这个的记录都删掉
    QSqlQuery query;
    query.prepare(str);//非完整语句传str参数后,随后调用query.exec(),取!判错
    query.addBindValue(ui->le_num->text());

    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<         qDebug()<         return;
    }

    if(query.first()){
        ui->le_name->setText(query.value(1).toString());
        ui->cb_sex->setCurrentText(query.value(2).toString());
        ui->le_age->setText(query.value(3).toString());
    }
}

例题1       文本编辑框+数据库的增删改查

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include //数据库连接处理

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0,QString file_name = "student.db");//初始化列表
    ~Widget();
    void showInfo();
    void clearInputs();

private slots:
    void on_pb_new_clicked();

    void on_pb_delete_clicked();

    void on_pb_search_clicked();

    void on_pb_change_clicked();

private:
    Ui::Widget *ui;
    QSqlDatabase db_student;    //创建的数据库连接
    QString db_file;            //数据库的文件名
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include 
#include //打印错误
#include //连接之后的操作数据库
#include 
Widget::Widget(QWidget *parent,QString file_name) :
    QWidget(parent),db_file(file_name),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->cb_sex->setFixedWidth(187);
    setWindowTitle("数据库-学生信息登记");

    QFile file(db_file);
    bool isFileExists = file.exists();//判断数据是否存在来决定是否需要建立数据库表

    //"QSQLITE"表示使用的数据库类型为sqlite
    //不指定数据连接的名字,会使用缺省名:"qt_sql_default_connection"
    db_student = QSqlDatabase::addDatabase("QSQLITE");//构造函数可以直接访问私有成员变量吗
    qDebug()<cb_sex->setCurrentIndex(-1);
    ui->le_age->clear();
    ui->le_name->clear();
    ui->le_num->setText("2024010500");
}
void Widget::showInfo()
{
    QString str = "select * from Student";
    QSqlQuery query(db_student);//指定 数据库 连接

    if (!query.exec(str))//完整的 要加字串
    {
        qDebug()<te->clear();//显示前清空文本编辑框
    while(query.next())//下一条不为空
    {
        QString tmp;
        tmp += query.value(0).toString() + " ";//学号
        tmp += query.value(1).toString() + " ";//姓名
        tmp += query.value(2).toString() + " ";//性别
        tmp += query.value(3).toString();      //年龄
        ui->te->append(tmp);
    }
}

void Widget::on_pb_new_clicked()
{
    QString str = "insert into Student values(:1,:1,:1,:1)";
    QSqlQuery query(db_student);
    query.prepare(str);
    query.bindValue(0,ui->le_num->text());//替换
    query.bindValue(1,ui->le_name->text());
    query.bindValue(2,ui->cb_sex->currentText());
    query.bindValue(3,ui->le_age->text());
    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<le_num->text());

    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<le_num->text());

    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<le_name->setText(query.value(1).toString());
        ui->cb_sex->setCurrentText(query.value(2).toString());
        ui->le_age->setText(query.value(3).toString());
    }
}

void Widget::on_pb_change_clicked()
{
    QString str = "update Student set name=?,sex=?,age=? where num=?";
    QSqlQuery query;
    query.prepare(str);
    query.addBindValue(ui->le_name->text());
    query.addBindValue(ui->cb_sex->currentText());
    query.addBindValue(ui->le_age->text());
    query.addBindValue(ui->le_num->text());
    if (!query.exec())//无需放入参数str 因为已经prepare了
    {
        qDebug()<

演示

Qt day8 数据库编程_第1张图片

例题2 表格(tablewidget)的增删改查

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QString name = "Student.db",QWidget *parent = 0);//默认参数
    ~Widget();

    void showInfo();

private slots:
    void on_pb_add_clicked();

    void on_pb_update_clicked();

    void on_pb_delete_clicked();

private:
    Ui::Widget *ui;
    QSqlDatabase db_student;
    QString db_file;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include     //查看表是否存在
#include 
#include 
#include 
Widget::Widget(QString name,QWidget *parent) ://1.默认参数 和 初始化列表区分开 且默认具体参数只需要写在头文件
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("学生信息");

    QFile file(db_file);
    bool isFileExists = file.exists();//5.判断数据库是否已存在

    db_student = QSqlDatabase::addDatabase("QSQLITE");//2.指定数据库类型为"QSQLITE"
    db_student.setDatabaseName(db_file);//4.设置数据库文件



    //通过连接打开数据库
    if(!db_student.open()){
        qDebug()<<"数据库打开失败";
        qDebug()<tw->setColumnCount(4);//设置列数
    QStringList list = {"学号","姓名","性别","年龄"};
    ui->tw->setHorizontalHeaderLabels(list);//设置label


    //显示数据库里所有记录
    showInfo();


}
void Widget::showInfo()
{
    QString str = "select * from Student";
    QSqlQuery query;

    if(!query.exec(str)){
        qDebug()< list;        //QList是表的意思 QStringList是Qt中用于存储字符串列表的类。
                                    //list.append(QStringList)
    //QString主要用于处理单个字符串,而QStringList主要用于处理字符串列表。在需要处理字符串集合时,使用QStringList会更方便和高效。
    while(query.next()){    //遍历所有查询到的记录
        QStringList record;
        for(int i=0;i<4;i++){
            record<tw->setRowCount(list.size());  //row行数 column列数
    for(int i=0;itw->setItem(i,j,item);
        }
        QTableWidgetItem *item = ui->tw->item(i,0);
        item->setFlags(item->flags() &~Qt::ItemIsEditable);//设置第一列学号不能修改

    }
}
Widget::~Widget()
{
    delete ui;
    db_student.close();//3.析构函数关闭数据库
}

void Widget::on_pb_add_clicked()
{
    if (ui->pb_add->text() == "新增"){
        //直接获得当前总行数
        int rowNum = ui->tw->rowCount();
        ui->tw->insertRow(rowNum);//在最后一行的后面增加空白行
        ui->pb_add->setText("提交");
        ui->pb_delete->setEnabled(false);//提交时,另外两个按钮灰掉
        ui->pb_update->setEnabled(false);
    }
    else{
        int rowNum = ui->tw->rowCount();
        rowNum--;//因为是0 base(0行开始算),所以要--
        QString str = "insert into Student values(?,?,?,?)";
        QSqlQuery query;
        query.prepare(str);
        query.addBindValue(ui->tw->item(rowNum,0)->data(0).toString());//学号num
        query.addBindValue(ui->tw->item(rowNum,1)->data(0).toString());//姓名
        query.addBindValue(ui->tw->item(rowNum,2)->data(0).toString());//性别
        query.addBindValue(ui->tw->item(rowNum,3)->data(0).toString());//年龄

        if(!query.exec()){//prepare后已经绑定 就不需要exec(str)
            qDebug()<pb_add->setText("新增");
        ui->pb_delete->setEnabled(true);
        ui->pb_update->setEnabled(true);
        showInfo();
    }
}

void Widget::on_pb_update_clicked()
{
    int currentRow = ui->tw->currentRow();
    qDebug()<<"currentRow = "<tw->item(currentRow,1)->data(0).toString());//name   //获取单元格数据
    query.addBindValue(ui->tw->item(currentRow,2)->data(0).toString());//sex
    query.addBindValue(ui->tw->item(currentRow,3)->data(0).toString());//age
    query.addBindValue(ui->tw->item(currentRow,0)->data(0).toString());//num


    if(!query.exec()){//prepare后已经绑定 就不需要exec(str)
        qDebug()<tw->currentRow();
    qDebug()<<"currentRow = "<tw->item(currentRow,0)->data(0).toString());//data一般固定填0

    if(!query.exec()){//prepare后已经绑定 就不需要exec(str)
        qDebug()<

演示

Qt day8 数据库编程_第2张图片

Qt数据库显示软件

SQLiteExpertPers

Qt day8 数据库编程_第3张图片

终于写完啦!享受周末了

想做个C++Qt贪吃蛇项目   最近也有个Qt项目 有的忙了嘿嘿

你可能感兴趣的:(qt,开发语言)