Qt实战(3)

Qt 操作MySql数据库

配置

问题:Qt连接MySQL的时候提示“QSqlDatabase: QMYSQL driver not loaded”,

解决办法:

  • 你的Qt Creator与MySQL位数统一的情况下,从 你的MySQL\lib目录下中将 libmysql.dll 文件复制到C:\Qt\Qt5.6.1\5.6\mingw49_32\bin中。运行程序。
  • 如果你的Qt Creator与MySQL位数不统一,下载一个位数与你的Qt相同的Mysql,找到里面的 libmysql.dll文件复制到目录下。
  • 总之,必须保证你拿到libmysql.dll这个文件对应的mysql的位数必须与QT的位数相同。

数据库基本操作

对数据库基本操作就是增、删、改、查。

  1. 新建 Qt Widgets 应用, 项目名称为 database, 类名为Mywidget, 基类选择QWidget。
  2. 完成后在 database.pro文件中添加如下代码:
1
QT += sql
  1. 连接数据库,在构造函数中添加以下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<QSqlDatabase>
#include<QDebug>
#include<QMessageBox>
#include<QSqlError>


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

打印QT支持的数据库驱动
qDebug()<<QSqlDatabase::drivers();

//添加mysql数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

//连接数据库
db.setHostName("127.0.0.1");
db.setUserName("root");
db.setPassword("an1234");
db.setDatabaseName("test_db");

//打开数据库是否成功
if(!db.open())
{
QMessageBox::warning(this,"错误",db.lastError().text());
return;
}
}

QT支持的数据库驱动有:

1
("QSQLITE", "QMYSQL", "QMYSQL3", "QPSQL", "QPSQL7")

  1. 创建数据表格,继续向后添加代码
1
2
3
4
5
6
#include<QSqlQuery>//一组数据


//创建数据表格
QSqlQuery query;
query.exec("create table student(id int primary key auto_increment ,name varchar(255),age int,score int);");

此条语句运行一次后要注释,不能多次创建同名的数据表格

  1. 数据库的另一种操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  
//添加mysql数据库 a是连接名,用于区分
QSqlDatabase db1 = QSqlDatabase::addDatabase("QMYSQL","a");

//连接数据库
db1.setHostName("127.0.0.1");
db1.setUserName("root");
db1.setPassword("an1234");
db1.setDatabaseName("testdb");

//打开数据库是否成功
if(!db1.open())
{
QMessageBox::warning(this,"错误",db.lastError().text());
return;
}

QSqlQuery query1(db1);//有区分时,一定要加上数据库名
query1.exec("create table student(id int primary key auto_increment ,name varchar(255),age int,score int);");
  1. 插入(增)

① 插入一条数据

1
2
3
4

//插入数据
QSqlQuery query;
query.exec("insert into student (id, name, age, score)values(2,'lucy',22,59);");

② 批量插入
两种方法:
obdc风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<QVariantList>//放任何类型,列表 


//obdc风格插入
//预处理语句
//?相当于占位符
query.prepare("insert into student (name, age, score)values(?,?,?);");
//给字段设置内容
QVariantList namelist;
namelist << "xiaoming" << "xiaohua" << "xiaoliao";
QVariantList agelist;
agelist << 19 << 20 << 21;
QVariantList scorelist;
scorelist << 98 << 88 << 99;
//给字段绑定相应的值,按顺序绑定
query.addBindValue(namelist);
query.addBindValue(agelist);
query.addBindValue(scorelist);

//执行预处理命令
query.execBatch();

oracle风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//oracle风格
//占位符 : + 自定义名字

query.prepare("insert into student (name, age, score)values(:name, :age, :score);");
//给字段设置内容
QVariantList namelist;
namelist << "xiaoa" << "xiaob" << "xiaoc";
QVariantList agelist;
agelist << 19 << 20 << 21;
QVariantList scorelist;
scorelist << 98 << 88 << 99;
//给字段绑定 可以不按照顺序
query.bindValue(":name",namelist);
query.bindValue(":score",scorelist);
query.bindValue(":age",agelist);

//执行预处理命令
query.execBatch();

  1. 更新数据(改)
1
2
QSqlQuery query;
query.exec("update student set score = 72 where id = 3");
  1. 查找并打印(查)
1
2
3
4
5
6
7
8
9
10

QSqlQuery query;
query.exec("select * from student where name = 'xiaob' ");//过滤
while(query.next())//一行一行的查找,一直到没有返回false
{
qDebug()<<query.value(0).toInt()
<<query.value(1).toString()
<<query.value("age").toInt()
<<query.value(3).toInt();
}
  1. 在界面上执行删除操作(删)

①设计页面如图所示

②右击按钮转到槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

void Widget::on_buttondelete_clicked()
{
//获取行编辑器内容
QString name = ui->lineEdit->text();
QString sql = QString("delete from student where name ='%1'").arg(name);
//开启一个事务 QSqlDatabase::database()获取你操作的数据库
//事务是数据库的一个重要功能,所谓事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。
//qDebug()<< QSqlDatabase::database().transaction();//有的版本不支持这种用法
QSqlQuery query;
query.exec("START TRANSACTION");
query.exec(sql);
}

void Widget::on_buttonsure_clicked()
{
//确认删除
QSqlDatabase::database().commit();
}

void Widget::on_buttoncancel_clicked()
{
//回滚,撤销
qDebug()<<"hahahhahh";
QSqlDatabase::database().rollback();

}

本地数据库Sqlite

  1. 新建 Qt Widgets 应用, 项目名称为 Sqlite, 类名为Mywidget, 基类选择QWidget。
  2. 在你的Sqlite相同目录下创建文件info.db
  3. 在.pro文件中添加
1
QT+= sql
  1. 操作,同mysql的操作基本一样,因为是本地数据库,所以没有连接数据库的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<QSqlDatabase>
#include<QDebug>
#include<QMessageBox>
#include<QSqlError>//
#include<QSqlQuery>//一组数据
#include<QVariantList>//放任何类型,列表

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

//打印QT支持的数据库驱动
qDebug()<<QSqlDatabase::drivers();

//添加qsqlite数据库 本地数据库
//不是很大型的数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

db.setDatabaseName("../info.db");

//打开数据库是否成功
if(!db.open())
{
QMessageBox::warning(this,"错误",db.lastError().text());
return;
}

//创建数据表格
QSqlQuery query;//不支持自动添加id功能
query.exec("create table student(id int primary key,name varchar(255),age int,score int);");


query.prepare("insert into student (name, age, score)values(?,?,?);");

//给字段设置内容
QVariantList namelist;
namelist << "xiaoming" << "xiaohua" << "xiaoliao";
QVariantList agelist;
agelist << 19 << 20 << 21;
QVariantList scorelist;
scorelist << 98 << 88 << 99;
//给字段绑定相应的值,按顺序绑定
query.addBindValue(namelist);
query.addBindValue(agelist);
query.addBindValue(scorelist);
query.execBatch();

//查找并打印
query.exec("select * from student");
while(query.next())//一行一行的查找,一直到没有返回false
{
qDebug()<<query.value(0).toInt()
<<query.value(1).toString()
<<query.value("age").toInt()
<<query.value(3).toInt();
}

}

QTableModel类实现对数据库的可视化操作

QSqlTableModel,该类提供了一个可读写单张SQL表的可编辑数据模型。下面实际操作一下

  1. 新建 Qt Widgets 应用, 项目名称为sqlModel, 类名为Mywidget, 基类选择QWidget。
  2. 在.pro文件中添加
1
QT+= sql
  1. 设计界面如图所示

注意:和里面的显示数据库的框用的是Item Views(Model-Based)里的TableView。

  1. 在头文件中添加库和对象
1
2
3
4
5
6
#include<QSqlTableModel>

private:
Ui::MyWidget *ui;

QSqlTableModel *model;
  1. 实现可视化操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<QSqlDatabase>
#include<QDebug>
#include<QMessageBox>
#include<QSqlError>
#include<QSqlTableModel>
#include<QSqlRecord>//数据库操作记录

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

//添加mysql数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

//连接数据库
db.setHostName("127.0.0.1");
db.setUserName("root");
db.setPassword("an1234");
db.setDatabaseName("test_db");

//打开数据库是否成功
if(!db.open())
{
QMessageBox::warning(this,"错误",db.lastError().text());
return;
}

//设置模型
model = new QSqlTableModel(this);
model->setTable("student");//指定使用那个表

//把model放在view
ui->tableView->setModel(model);

//显示model里的数据
model->select();

//字段设置为指定中文名 第0个字段即id
model->setHeaderData(0,Qt::Horizontal,"学号");
model->setHeaderData(1,Qt::Horizontal,"姓名");
model->setHeaderData(2,Qt::Horizontal,"年龄");
model->setHeaderData(3,Qt::Horizontal,"分数");

//设置model的编辑模式 为手动提交
model->setEditStrategy(QSqlTableModel::OnManualSubmit);

//设置view中的数据库为不能修改
//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

}
  1. 按钮槽函数添加代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//改
//修改操作可以直接在视图框中操作


//增
void MyWidget::on_buttonadd_clicked()
{
//添加空记录
QSqlRecord record = model->record();
//获取行号
int row = model->rowCount();
model->insertRecord(row,record);

}

//删
void MyWidget::on_buttondelete_clicked()
{
//获取选中的模型
QItemSelectionModel *sModel=ui->tableView->selectionModel();
//取出选中模型中的索引(哪几行)
QModelIndexList list = sModel->selectedRows();
//删除所有选中的行
for(int i=0 ;i<list.size();i++)
{
model->removeRow(list.at(i).row());
//取出所有索引中的i行的索引,再根据这个索引选中并删除这一行
}
}

void MyWidget::on_buttonsure_clicked()
{
model->submitAll();//提交动作
}

void MyWidget::on_buttoncancel_clicked()
{
model->revertAll();//取消动作
model->submitAll();//提交动作(取消也是一个动作)
}

//查
void MyWidget::on_buttonsure_2_clicked()
{
//获取行编辑器内容
QString name = ui->lineEdit->text();
//过滤条件
QString str = QString("name='%1'").arg(name);
model->setFilter(str);
model->select();//重新显示model里的数据
}
你可以对我进行打赏哦