qt 数据库
SQL 模块分层机制
驱动层(底层):用于控制数据库,且连接sql接口层,相当于sql接口层和数据库之间的桥梁
sql接口层:各种的指令与函数访问数据库 sqlDataBase,这些指令是数据库的原生指令
用户接口层:将数据库的内容,链接到窗口部件上,sql_xxx_model 基于该层的类和函数,可以实现在窗体内对数据库的显示修改等内容
如果这时利用c++代码实现对数据库的操作,使用sql接口层就可以
如果想在widget窗体内进行操作,就需要使用用户接口层
sql语句 - sql接口层
/* .pro */
QT += sql
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// sqldatabase 是sql接口层
QStringList drivers=QSqlDatabase::drivers();
foreach (const QString &driver, drivers) {
qDebug()<<driver;
}
// 创建一个数据库对象
// sqlLite=new QSqlDriver(this); // ERROR
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydataset.db");
// 默认路径是.pro文件的包含路径
if (!db.open())
{
qDebug()<<"ERROR: dataset.db can not open...";
qDebug()<<db.lastError();
}
else
{
qDebug()<<"SUCCESS: dataset.db connected...";
}
// 创建查询对象
// QSqlQuery类,类中有很多方法,各种方法可以操作数据库
QSqlQuery sqlQuery(db);
// 查找tables
QStringList tables=db.tables(QSql::Tables);
qDebug()<<"tables info: ";
for(const QString &table:tables)
{
qDebug()<<table;
}
QString command; // sql语句
// 防止重复创建 与清空
if (!tables.contains("student"))
{
// 创建表
command=QString("CREATE TABLE student(%1,%2,%3)")
.arg(QString("id INT"))
.arg(QString("name VARCHAR(20)"))
.arg(QString("age INT"));
sqlQuery.prepare(command); // 准备
if (!sqlQuery.exec()) // 执行语句
{
qDebug()<<"ERROR: failed to create table...";
qDebug()<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: table created...";
}
// sqlQuery.finish();
}
else
{
// 清空表
command=QString("DELETE FROM student ");
sqlQuery.prepare(command);
if (!sqlQuery.exec()) // 执行语句
{
qDebug()<<"ERROR: failed to clear table...";
qDebug()<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: table clear...";
}
}
// 插入数据
// version 1
command=QString("INSERT INTO student (id,name,age)");
command+=QString("values(:id,:name,:age)");
sqlQuery.prepare(command);
sqlQuery.bindValue(":id",1);
sqlQuery.bindValue(":name","li");
sqlQuery.bindValue(":age",20);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: insert a info";
}
// sqlQuery.finish();
// version 2
command=QString("INSERT INTO student (id,name,age)\n");
command+=QString("values(?,?,?)");
sqlQuery.prepare(command);
sqlQuery.addBindValue(2);
sqlQuery.addBindValue("zhang");
sqlQuery.addBindValue(21);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: insert a info";
}
// sqlQuery.finish();
/*
// version 3 ERROR 不能用Qstring这种方式初始化
command=QString("INSERT INTO student (id,name,age) values(%1,%2,%3)").arg(QString::number(3)).arg("wang").arg(QString::number(23));
sqlQuery.prepare(command);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: insert a info";
}
*/
// 显示所有信息
command=QString("SELECT * from student");
sqlQuery.prepare(command);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
const char *data_format="%-10d%-10s%-10d";
qDebug("%-10s%-10s%-10s","id","name","age");
while (sqlQuery.next())
{
int id=sqlQuery.value(0).toInt(); // 将sql语句中的数据类型转换成qt中的数据类型
QString name=sqlQuery.value(1).toString();
QByteArray name_tmp=name.toLatin1();
int age=sqlQuery.value(2).toInt();
qDebug(data_format,id,name_tmp.data(),age);
}
}
// sqlQuery.finish();
// 更新数据
command=QString("UPDATE student SET name= :_name WHERE id=:_id");
sqlQuery.prepare(command);
sqlQuery.bindValue(":_name","wang");
sqlQuery.bindValue(":_id",1);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: update a info";
}
command=QString("SELECT * from student");
sqlQuery.prepare(command);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
const char *data_format="%-10d%-10s%-10d";
qDebug("%-10s%-10s%-10s","id","name","age");
while (sqlQuery.next())
{
int id=sqlQuery.value(0).toInt(); // 将sql语句中的数据类型转换成qt中的数据类型
QString name=sqlQuery.value(1).toString();
QByteArray name_tmp=name.toLatin1();
int age=sqlQuery.value(2).toInt();
qDebug(data_format,id,name_tmp.data(),age);
}
}
}
Widget::~Widget()
{
delete ui;
}
sql - 用户层
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSqlDatabase>
#include <QSqlDriver> // 接口层
#include <QSqlQuery> // 接口层
#include <QSqlError> // 接口层
#include <QSqlQueryModel> // 用户层
#include <QSqlTableModel> // 用户层
#include <QSqlRelationalTableModel> // 用户层
#include <QTableView>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::Widget *ui;
QSqlTableModel *model;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// sqldatabase 是sql接口层
QStringList drivers=QSqlDatabase::drivers();
foreach (const QString &driver, drivers) {
qDebug()<<driver;
}
// 创建一个数据库对象
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydataset.db");
// 默认路径是.pro文件的包含路径
if (!db.open())
{
qDebug()<<"ERROR: dataset.db can not open...";
qDebug()<<db.lastError();
}
else
{
qDebug()<<"SUCCESS: dataset.db connected...";
}
// 创建查询对象
// QSqlQuery类,类中有很多方法,各种方法可以操作数据库
QSqlQuery sqlQuery(db);
// 查找tables
QStringList tables=db.tables(QSql::Tables);
qDebug()<<"tables info: ";
for(const QString &table:tables)
{
qDebug()<<table;
}
QString command; // sql语句
// 防止重复创建 与清空
if (!tables.contains("student"))
{
// 创建表
command=QString("CREATE TABLE student(%1,%2,%3)")
.arg(QString("id INT"))
.arg(QString("name VARCHAR(20)"))
.arg(QString("age INT"));
sqlQuery.prepare(command); // 准备
if (!sqlQuery.exec()) // 执行语句
{
qDebug()<<"ERROR: failed to create table...";
qDebug()<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: table created...";
}
}
else
{
// 清空表
command=QString("DELETE FROM student ");
sqlQuery.prepare(command);
if (!sqlQuery.exec()) // 执行语句
{
qDebug()<<"ERROR: failed to clear table...";
qDebug()<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: table clear...";
}
}
// 插入数据
// version 1
command=QString("INSERT INTO student (id,name,age)");
command+=QString("values(:id,:name,:age)");
sqlQuery.prepare(command);
sqlQuery.bindValue(":id",1);
sqlQuery.bindValue(":name","li");
sqlQuery.bindValue(":age",20);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: insert a info";
}
// version 2
command=QString("INSERT INTO student (id,name,age)\n");
command+=QString("values(?,?,?)");
sqlQuery.prepare(command);
sqlQuery.addBindValue(2);
sqlQuery.addBindValue("zhang");
sqlQuery.addBindValue(21);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
qDebug()<<"SUCCESS: insert a info";
}
// 显示所有信息
command=QString("SELECT * from student");
sqlQuery.prepare(command);
if (!sqlQuery.exec())
{
qDebug()<<"ERROR: "<<sqlQuery.lastError();
}
else
{
const char *data_format="%-10d%-10s%-10d";
qDebug("%-10s%-10s%-10s","id","name","age");
while (sqlQuery.next())
{
int id=sqlQuery.value(0).toInt(); // 将sql语句中的数据类型转换成qt中的数据类型
QString name=sqlQuery.value(1).toString();
QByteArray name_tmp=name.toLatin1();
int age=sqlQuery.value(2).toInt();
qDebug(data_format,id,name_tmp.data(),age);
}
}
// 创建对象
model =new QSqlTableModel(this);
ui->tableView->setModel(model); // 用tableview显示model
model->setTable("student");
model->select(); // 直接显示信息
// model->setHeaderData(0,Qt::Horizontal,"学号");
// model->setHeaderData(1,Qt::Horizontal,"姓名");
// model->setHeaderData(2,Qt::Horizontal,"年龄");
// 修改模型更新策略
model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 手动提交,只有调用特定函数才能更新或者撤销成功
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
model->submitAll(); // 提交
}
void Widget::on_pushButton_2_clicked()
{
model->revertAll(); // 撤销
model->submitAll();
}
void Widget::on_pushButton_3_clicked()
{
// 查找
QString name=ui->lineEdit->text();
if (!name.isEmpty())
{
model->setFilter(QString("name = '%1'").arg(name));
}
else
{
model->setFilter(""); // 取消筛选
}
model->select(); // 用于在tableview显示
}