Qt day8 数据库编程

Qt数据库编程


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


#include <QsqlDatabase>数据库连接处理        eg:QSqlDatabase db_student
#include <QSqlQuery>连接完成后操作数据库
#include <QSqlError> 打印数据库相关错误
私有成员:    
    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()<<str<<"faild";qDebug()<<query.lastError().text();
插入数据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<QStringList> list;    
    while(query.next()){    //遍历所有查询到的记录
        QStringList record;
        for(int i=0;i<4;i++){
            record<<query.value(i).toString();
        }
        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()<<str<<"faild";
                qDebug()<<query.lastError().text();
            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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        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 <QWidget>
#include <QSqlDatabase>//数据库连接处理

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 <QDebug>
#include <QSqlError>//打印错误
#include <QSqlQuery>//连接之后的操作数据库
#include <QFile>
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()<<db_student.connectionName();//打印第一个连接的名字
    qDebug()<<db_student.connectionNames();//打印所有连接的名字

//    //指定数据连接的名字
//    QSqlDatabase db_2 = QSqlDatabase::addDatabase("QSQLITE","my_db_connection");
//    qDebug()<<db_student.connectionName();
//    qDebug()<<db_student.connectionNames();

    //设置数据库的文件
    //db_student.setDatabaseName(db_file);//设置名字
    db_student.setDatabaseName("student.db");//设置名字

    //通过连接打开数据库
    if(!db_student.open()){
        qDebug()<<"数据库打开失败";
        qDebug()<<db_student.lastError().text();
    }
    else{
        qDebug()<<"数据库打开成功";
    }


    if (!isFileExists){
        qDebug()<<"数据库文件不存在";
    QSqlQuery query(db_student);//使用数据库连接:db_student -- 建表
    //等效QSqlQuery query;//不使用 数据库连接,它使用连接名字为 "qt_sql_default_connection"
    QString str = "create table Student(num varchar(64) primary key,name varchar(128),sex varchar(16),age varchar(16))";
        if (!query.exec(str)){
             qDebug()<<str<<"faild";
             qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法1
        str = "insert into Student values('20240105001','小明','男','21')";//不能写成xx='xxxx',
        if (!query.exec(str)){
             qDebug()<<str<<"faild";
             qDebug()<<query.lastError().text();
        }
        //插入数据 -- 方法2
        str = "insert into Student values(?,?,?,?)";//插入待定数据
        query.prepare(str);
        query.addBindValue("20240105002");
        query.addBindValue("麦克");
        query.addBindValue("男");
        query.addBindValue("20");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法3
        str = "insert into Student values(:num,:xxx,:sex,:age)";
        query.prepare(str);
        query.bindValue(":num","20240105015");//替换      03
        query.bindValue(":xxx","阿瑟2");
        query.bindValue(":sex","男");
        query.bindValue(":age","23");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法3.1
        str = "insert into Student values(:num,:name,:sex,:age)";
        query.prepare(str);
        query.bindValue(0,"20240105004");//替换
        query.bindValue(1,"梅梅");
        query.bindValue(2,"女");
        query.bindValue(3,"19");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }
    }
    else{
        qDebug()<<"数据库文件已存在";
    }

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

Widget::~Widget()
{
    delete ui;
    //关闭数据库 连接
    db_student.close();
}
void Widget::clearInputs()
{
    ui->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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        return;
    }

    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);
    }
}

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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        return;
    }
    showInfo();
    clearInputs();
}

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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        return;
    }
    showInfo();
    clearInputs();
}

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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        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());
    }
}

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()<<str<<"faild";
        qDebug()<<query.lastError().text();
        return;
    }
    showInfo();
    clearInputs();
}

演示

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

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSqlDatabase>

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 <QFile>    //查看表是否存在
#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
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()<<db_student.lastError().text();
    }
    else{
        qDebug()<<"数据库打开成功";
    }
    if (!isFileExists){
        qDebug()<<"数据库文件不存在";
    QSqlQuery query(db_student);//使用数据库连接:db_student -- 建表
    //等效QSqlQuery query;//不使用 数据库连接,它使用连接名字为 "qt_sql_default_connection"
    QString str = "create table Student(num varchar(64) primary key,name varchar(128),sex varchar(16),age varchar(16))";
        if (!query.exec(str)){
             qDebug()<<str<<"faild";
             qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法1
        str = "insert into Student values('20240105001','小明','男','21')";
        if (!query.exec(str)){
             qDebug()<<str<<"faild";
             qDebug()<<query.lastError().text();
        }
        //插入数据 -- 方法2???
        str = "insert into Student values(?,?,?,?)";//插入待定数据
        query.prepare(str);
        query.addBindValue("20240105002");
        query.addBindValue("麦克");
        query.addBindValue("男");
        query.addBindValue("20");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法3
        str = "insert into Student values(:num,:name,:sex,:age)";
        query.prepare(str);
        query.bindValue(":num","20240105003");//替换
        query.bindValue(":name","阿瑟");
        query.bindValue(":sex","男");
        query.bindValue(":age","23");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }

        //插入数据 -- 方法3.1
        str = "insert into Student values(:num,:name,:sex,:age)";
        query.prepare(str);
        query.bindValue(0,"20240105004");//替换
        query.bindValue(1,"梅梅");
        query.bindValue(2,"女");
        query.bindValue(3,"19");
        if (!query.exec())//无需放入参数str 因为已经prepare了
        {
            qDebug()<<str<<"faild";
            qDebug()<<query.lastError().text();
        }
    }
    else{
        qDebug()<<"数据库文件已存在";
    }

    ui->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()<<str<<"failed";    //失败
        qDebug()<<query.lastError().text();//失败的详细信息
        return;
    }
    QList<QStringList> list;        //QList是表的意思 QStringList是Qt中用于存储字符串列表的类。
                                    //list.append(QStringList)
    //QString主要用于处理单个字符串,而QStringList主要用于处理字符串列表。在需要处理字符串集合时,使用QStringList会更方便和高效。
    while(query.next()){    //遍历所有查询到的记录
        QStringList record;
        for(int i=0;i<4;i++){
            record<<query.value(i).toString();
        }
        list.append(record);
    }

    //设置tablewidget的行数
    ui->tw->setRowCount(list.size());  //row行数 column列数
    for(int i=0;i<list.size();i++){
        for(int j=0;j<list.at(i).size();j++){   //list.at(i).size()i行的列数
            QTableWidgetItem *item = new QTableWidgetItem(list.at(i).at(j));
            ui->tw->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()<<str<<"failed";    //失败
            qDebug()<<query.lastError().text();//失败的详细信息
            return;
        }
        ui->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 = "<<currentRow;

    QString str = "update Student set name=?,sex=?,age=? where num=?";
    QSqlQuery query;
    query.prepare(str);//不是完整语句 要prepare绑定
    query.addBindValue(ui->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()<<str<<"failed";    //失败
        qDebug()<<query.lastError().text();//失败的详细信息
        return;
    }
    showInfo();

}

void Widget::on_pb_delete_clicked() //选中一行 删除
{
    int currentRow = ui->tw->currentRow();
    qDebug()<<"currentRow = "<<currentRow;

    QString str = "delete from Student where num=?";
    QSqlQuery query;
    query.prepare(str);//不是完整语句 要prepare绑定
    query.addBindValue(ui->tw->item(currentRow,0)->data(0).toString());//data一般固定填0

    if(!query.exec()){//prepare后已经绑定 就不需要exec(str)
        qDebug()<<str<<"failed";    //失败
        qDebug()<<query.lastError().text();//失败的详细信息
        return;
    }
    showInfo();
}

演示

Qt数据库显示软件

SQLiteExpertPers

终于写完啦!享受周末了

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

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值