/*******************************************************************************************/

一、数据库连接

Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台独立”,既包括操作系统平台,

有包括各个数据库平台。另外,我们强调了“基于 SQL”,因为 NoSQL 数据库至今没有一个通用查询方法,

所以不可能提供一种通用的 NoSQL 数据库的操作。Qt 的数据库操作还可以很方便的与 model/view 架构进行整合。

通常来说,我们对数据库的操作更多地在于对数据库表的操作,而这正是 model/view 架构的长项。

Qt 使用QSqlDatabase表示一个数据库连接。更底层上,Qt 使用驱动(drivers)来与不同的数据库 API 进行交互。

Qt 桌面版本提供了如下几种驱动:

驱动         数据库

QDB2       IBM DB2 (7.1 或更新版本)

QIBASE    Borland InterBase

QMYSQL  MySQL

QOCI        Oracle Call Interface Driver

QODBC    Open Database Connectivity (ODBC) – Microsoft SQL Server 及其它兼容 ODBC 的数据库

QPSQL     PostgreSQL (7.3 或更新版本)

QSQLITE2        SQLite 2

QSQLITE  SQLite 3

QSYMSQL        针对 Symbian 平台的SQLite 3

QTDS        Sybase Adaptive Server (自 Qt 4.7 起废除)

不过,由于受到协议的限制,Qt 开源版本并没有提供上面所有驱动的二进制版本,而仅仅以源代码的形式提供。

通常,Qt 只默认搭载 QSqlite 驱动(这个驱动实际还包括 Sqlite 数据库,也就是说,如果需要使用 Sqlite 的话,只需要该驱动即可)。

我们可以选择把这些驱动作为 Qt 的一部分进行编译,也可以当作插件编译。

如果习惯于使用 SQL 语句,我们可以选择QSqlQuery类;如果只需要使用高层次的数据库接口(不关心 SQL 语法),

我们可以选择使用QsqlTableModel类。

在使用时,我们可以通过

QSqlDatabase::drivers();

找到系统中所有可用的数据库驱动的名字列表。我们只能使用出现在列表中的驱动。

1.操作数据库的依赖

使用数据库的时候,需要加入数据库的库文件,比如mysql:

如果没有在项目中加入mysql的库(需要自己去下载然后添加,比如window的libmysql.dll),就会提示驱动没有加载的错误

数据库库文件(libmysql.dll)需要放到qt的安装目录里面的bin目录下

2.项目配置文件的修改

使用数据库时,需要在项目文件中加上:

QT += sql

3.数据库连接代码

#include <QSqlDatabase>

//打印Qt支持的数据库驱动

qDebug() << QSqlDatabase::drivers();

可以得知,qt支持的数据库:

sqllite 静态数据库,不需要服务器,类似文件那样,保存的是.db的文件,但是操作是数据的操作方式

开源,提供.h .c文件,文件型数据库

mysql

obdc windows提供好的一个数据库操作库,封装好,不需要sql语句都可以操作

psql

现在用mysql举例:

//添加MySql数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

//连接数据库

db.setHostName("127.0.0.1"); //数据库服务器IP 端口默认是3236,不需要设置

db.setUserName("root"); //数据库用户名

db.setPassword("123456"); //密码

db.setDatabaseName("info"); //使用哪个数据库,mysql中创建的数据库

//打开数据库

if( !db.open() ) //数据库打开失败

{//如果没有在项目中加入mysql的库(需要自己去下载然后添加,比如window的libmysql.dll),就会提示驱动没有加载的错误

QMessageBox::warning(this, "错误", db.lastError().text());//此时需要,数据库库文件(libmysql.dll)需要放到qt的安装目录里面的bin目录下

return;

}

/*******************************************************************************************/

二、数据库插入

#include <QSqlQuery>//执行sql语句需要的头文件

QSqlQuery query;//只操作一个数据库时不需要传入数据库对象

query.exec("create table student(id int primary key, name varchar(255), age int, score int);");

//这样创建对象后,传入sql语句就可以操作了

1.当需要操作多个数据库(Database)时,有两点需要注意:

1).创建数据库对象时,需要传入标识,用来区分创建出来的数据库和其他的不同

QSqlDatabase db1 = QSqlDatabase::addDatabase("QMYSQL", "a");

2).操作数据时,需要传入数据库对象,来指明是哪个数据库。同时如果前面创建给了标识,则

这里创建查询对象时必须传入数据库对象,否则操作将不成功

QSqlQuery query1(db1);

query1.exec("create table student(id int primary key, name varchar(255), age int, score int);");

2.插入

QSqlQuery query;

query.exec("insert into student(id, name, age, score) values(1, 'mike', 18, 59);");

3.批量插入,有两种方式:

1).odbc(windows)风格

预处理语句

? 相当于 占位符

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

给字段设置内容 通过list,list可以放任何类型

QVariantList nameList;

nameList << "xiaoming" << "xiaolong" << "xiaojiang";

QVariantList ageList;

ageList << 11 << 22 << 33;

QVariantList scoreList;

scoreList << 59 << 69 << 79;

给字段绑定相应的值 按顺序绑定,否则插入不成功

query.addBindValue(nameList);

query.addBindValue(ageList);

query.addBindValue(scoreList);

执行预处理命令

query.execBatch();

2).oracle风格

预处理语句

占位符 : + 自定义名字

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

给字段设置内容 list

QVariantList nameList;

nameList << "xiaoa" << "xiaob" << "xiaoc";

QVariantList ageList;

ageList << 33 << 44 << 55;

QVariantList scoreList;

scoreList << 89 << 90 << 99;

给字段绑定,有标识符指定了,所以不局限于顺序

query.bindValue(":name", nameList);

query.bindValue(":score", scoreList);

query.bindValue(":age", ageList);

执行预处理命令

query.execBatch();

/*******************************************************************************************/

三、数据库删除和遍历

1.删除

//开启一个事务,

QSqlDatabase::database().transaction();//QSqlDatabase::database()获取数据库然后调用开启事务函数

//确定删除

QSqlDatabase::database().commit();

//回滚,撤销

QSqlDatabase::database().rollback();

2.遍历(查找所有):

查询返回结果不包括字段,从第一行记录开始,即第0个为第一条记录

QSqlQuery query;

query.exec("select * from student");//如果只是查一行,sql中加上where条件过滤即可

while(query.next()) //一行一行遍历,执行完自动跳到下一行,从第一行记录开始

{

//取出当前行的内容,取的时候以列为单位,第0列即第一列id,除了用下标来取之外还可以用字段名来取值

qDebug() << query.value(0).toInt()

<< query.value(1).toString()

<< query.value("age").toInt()

<< query.value("score").toInt();

}

上述代码具体见《Database》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); private slots:
void on_buttonDel_clicked(); void on_buttonSure_clicked(); void on_buttonCancel_clicked(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QSqlDatabase>
#include <QDebug>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQuery>
#include <QVariantList> 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"); //数据库服务器IP
db.setUserName("root"); //数据库用户名
db.setPassword(""); //密码
db.setDatabaseName("info"); //使用哪个数据库 //打开数据库
if( !db.open() ) //数据库打开失败
{
QMessageBox::warning(this, "错误", db.lastError().text());
return;
} // QSqlQuery query;
// query.exec("create table student(id int primary key, name varchar(255), age int, score int);"); /*
QSqlDatabase db1 = QSqlDatabase::addDatabase("QMYSQL", "a");
db1.setHostName("127.0.0.1"); //数据库服务器IP
db1.setUserName("root"); //数据库用户名
db1.setPassword("123456"); //密码
db1.setDatabaseName("test"); //使用哪个数据库 //打开数据库
if( !db1.open() ) //数据库打开失败
{
QMessageBox::warning(this, "错误", db.lastError().text());
return;
} QSqlQuery query1;
query1.exec("create table student(id int primary key, name varchar(255), age int, score int);");
*/ //插入
//QSqlQuery query;
// query.exec("insert into student(id, name, age, score) values(1, 'mike', 18, 59);"); //批量插入
//odbc风格
//预处理语句
// ? 相当于 占位符
// query.prepare("insert into student(name, age, score) values(?, ?, ?)");
// //给字段设置内容 list
// QVariantList nameList;
// nameList << "xiaoming" << "xiaolong" << "xiaojiang";
// QVariantList ageList;
// ageList << 11 << 22 << 33;
// QVariantList scoreList;
// scoreList << 59 << 69 << 79;
// //给字段绑定相应的值 按顺序绑定
// query.addBindValue(nameList);
// query.addBindValue(ageList);
// query.addBindValue(scoreList);
// //执行预处理命令
// query.execBatch(); //oracle风格
//占位符 : + 自定义名字
// query.prepare("insert into student(name, age, score) values(:name, :age, :score)");
// //给字段设置内容 list
// QVariantList nameList;
// nameList << "xiaoa" << "xiaob" << "xiaoc";
// QVariantList ageList;
// ageList << 33 << 44 << 55;
// QVariantList scoreList;
// scoreList << 89 << 90 << 99;
// //给字段绑定
// query.bindValue(":name", nameList);
// query.bindValue(":score", scoreList);
// query.bindValue(":age", ageList); // //执行预处理命令
// query.execBatch(); QSqlQuery query;
query.exec("select * from student"); while(query.next()) //一行一行遍历
{
//取出当前行的内容
qDebug() << query.value().toInt()
<< query.value().toString()
<< query.value("age").toInt()
<< query.value("score").toInt();
} } Widget::~Widget()
{
delete ui;
} void Widget::on_buttonDel_clicked()
{
//获取行编辑内容
QString name = ui->lineEdit->text(); QString sql = QString("delete from student where name = '%1'").arg(name); //开启一个事务
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec(sql); } void Widget::on_buttonSure_clicked()
{
//确定删除
QSqlDatabase::database().commit();
} void Widget::on_buttonCancel_clicked()
{
//回滚,撤销
QSqlDatabase::database().rollback();
}

widget.cpp

/*******************************************************************************************/

四、sqlite

sqlite是本地数据库,不需要链接

//添加Sqlite数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

//设置数据库

db.setDatabaseName("../info.db");//注意整个.db文件可以自己新建一个文本文件然后重命名即可

后面都一样,注意,自动累加auto_increment,sqlite不支持。

上述代码具体见《SqlLite》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QSqlDatabase>
#include <QDebug>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQuery>
#include <QVariantList> Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this); //打印Qt支持的数据库驱动
qDebug() << QSqlDatabase::drivers(); //添加Sqlite数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
//设置数据库
db.setDatabaseName("../info.db"); //打开数据库
if( !db.open() ) //数据库打开失败
{
QMessageBox::warning(this, "错误", db.lastError().text());
return;
} QSqlQuery query;
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(?, ?, ?)");
//给字段设置内容 list
QVariantList nameList;
nameList << "xiaoming" << "xiaolong" << "xiaojiang";
QVariantList ageList;
ageList << << << ;
QVariantList scoreList;
scoreList << << << ;
//给字段绑定相应的值 按顺序绑定
query.addBindValue(nameList);
query.addBindValue(ageList);
query.addBindValue(scoreList);
//执行预处理命令
query.execBatch(); query.exec("select * from student"); while(query.next()) //一行一行遍历
{
//取出当前行的内容
qDebug() << query.value().toInt()
<< query.value().toString()
<< query.value("age").toInt()
<< query.value("score").toInt();
} } Widget::~Widget()
{
delete ui;
}

widget.cpp

/*******************************************************************************************/

五、可视化操作数据库

Qt 不仅提供了这种使用 SQL 语句的方式,还提供了一种基于模型的更高级的处理方式。这种基于QSqlTableModel 的模型处理更为高级,

如果对 SQL 语句不熟悉,并且不需要很多复杂的查询,这种QSqlTableModel模型基本可以满足一般的需求。

即使用可以不懂sql语句都可以操作的类,来操作数据库

model/view 架构:

ModelView 模型视图

Model 单独一个类,只做一件事情,存储数据

view  单独一个类,只做一件事情,显示和修改数据

使用ui中的Item Views中的Table View

1.使用模型操作数据库

#include <QSqlTableModel>//表格的模型

//设置模型

model = new QSqlTableModel(this);

model->setTable("student");//自动和数据库关联上了,但是还需要指定使用哪个表

//把model放在view,如果没有放进去,则model只是可以操作数据并不会显示出来

ui->tableView->setModel(model);//但是此时里面还没有数据,需要model来显示数据

//显示model里的数据

model->select();//这样就把表中所有的数据显示成表格的样子在窗口中

//此时修改窗口中表格的数据,数据库里面的内容也会随之改动

另外需要注意,由于QSqlTableModel只是一种高级操作,肯定没有实际 SQL 语句方便。

具体来说,我们使用QSqlTableModel只能进行 SELECT * 的查询,不能只查询其中某些列的数据。

设置model一些属性:

修改字段的显示效果

model->setHeaderData(0, Qt::Horizontal, "学号");//水平方向第0列即id显示为汉字学号

设置model的编辑模式,手动提交修改,修改后需要确定后才会修改到数据库

model->setEditStrategy(QSqlTableModel::OnManualSubmit);

设置view中的数据库不允许修改,只是显示数据里面的内容。//表现为双击不会让用户修改的现象

ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

2.可视化增加一条记录:

//添加空记录

QSqlRecord record = model->record(); //获取空记录,传入标号后就是获取某一行

//获取行号

int row = model->rowCount();

model->insertRecord(row, record);//在指定行插入空记录,这是界面上就会出现一个空行,

//用户就可以在空行里面填入输入,填入好后就实现了增加记录

3.可视化提交:

model->submitAll(); //提交动作

4.可视化回滚:

model->revertAll(); //取消所有动作

model->submitAll(); //提交动作,//取消也是动作,要生效还得提交一次

5.可视化删除,注意可以选中多行删除(需要用到模型的概念:选中的多行就形成一个模型):

//获取选中的模型

QItemSelectionModel *sModel =ui->tableView->selectionModel();

//取出模型中的索引(每条记录的索引集合)

QModelIndexList list = sModel->selectedRows();

//删除所有选中的行

for(int i = 0; i < list.size(); i++)

{

model->removeRow( list.at(i).row() );//传入记录的行号

}

6.可视化查找(以通过名字查找举例):

QString name = ui->lineEdit->text();

QString str = QString("name = '%1'").arg(name);//过滤条件格式,注意字符串不能少了单引号

model->setFilter(str);//设定过滤条件

model->select();//过滤完后显示一下

上述代码具体见《ModelView》

 #ifndef WIDGET_H
#define WIDGET_H #include <QWidget>
#include <QSqlTableModel> namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget(); private slots:
void on_buttonAdd_clicked(); void on_buttonSure_clicked(); void on_buttonCancel_clicked(); void on_buttonDel_clicked(); void on_buttonFind_clicked(); private:
Ui::Widget *ui;
QSqlTableModel *model;
}; #endif // WIDGET_H

widget.h

 #include "widget.h"
#include "ui_widget.h"
#include <QSqlDatabase>
#include <QDebug>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlTableModel>
#include <QSqlRecord> 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"); //数据库服务器IP
db.setUserName("root"); //数据库用户名
db.setPassword(""); //密码
db.setDatabaseName("info"); //使用哪个数据库 //打开数据库
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(); model->setHeaderData(, Qt::Horizontal, "学号"); //设置model的编辑模式,手动提交修改
model->setEditStrategy(QSqlTableModel::OnManualSubmit); //设置view中的数据库不允许修改
//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); } Widget::~Widget()
{
delete ui;
} void Widget::on_buttonAdd_clicked()
{
//添加空记录
QSqlRecord record = model->record(); //获取空记录
//获取行号
int row = model->rowCount();
model->insertRecord(row, record); } void Widget::on_buttonSure_clicked()
{
model->submitAll(); //提交动作
} void Widget::on_buttonCancel_clicked()
{
model->revertAll(); //取消所用动作
model->submitAll(); //提交动作
} void Widget::on_buttonDel_clicked()
{
//获取选中的模型
QItemSelectionModel *sModel =ui->tableView->selectionModel();
//取出模型中的索引
QModelIndexList list = sModel->selectedRows();
//删除所有选中的行
for(int i = ; i < list.size(); i++)
{
model->removeRow( list.at(i).row() );
} } void Widget::on_buttonFind_clicked()
{
QString name = ui->lineEdit->text();
QString str = QString("name = '%1'").arg(name); model->setFilter(str);
model->select(); }

widget.cpp

界面编程之QT的数据库操作20180801的更多相关文章

  1. 界面编程之QT的文件操作20180729

    /*******************************************************************************************/ 一.QT文件 ...

  2. 界面编程之QT窗口系统20180726

    /*******************************************************************************************/ 一.坐标系统 ...

  3. 界面编程之QT的线程20180731

    /*******************************************************************************************/ 一.为什么需 ...

  4. 界面编程之QT的Socket通信20180730

    /*******************************************************************************************/ 一.linu ...

  5. 界面编程之QT的信号与槽20180725

    /*******************************************************************************************/ 一.指定父对 ...

  6. 界面编程之QT的基本介绍与使用20180722

    /*******************************************************************************************/ 一.qt介绍 ...

  7. 界面编程之QT绘图和绘图设备20180728

    /*******************************************************************************************/ 一.绘图 整 ...

  8. 界面编程之QT的事件20180727

    /*******************************************************************************************/ 一.事件 1 ...

  9. QT核心编程之Qt线程 (c)

    QT核心编程之Qt线程是本节要介绍的内容,QT核心编程我们要分几个部分来介绍,想参考更多内容,请看末尾的编辑推荐进行详细阅读,先来看本篇内容. Qt对线程提供了支持,它引入了一些基本与平台无关的线程类 ...

随机推荐

  1. 20155301 Exp7 网络欺诈防范

    20155301 Exp7 网络欺诈防范 1.基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 (2)在日常生活工作中如何防范以上两攻击方法 2.实践过程记录 简单应用SET工具建立 ...

  2. git 创建标签和删除标签

    创建标签 在Git中打标签非常简单,首先,切换到需要打标签的分支上: $ git branch * dev master $ git checkout master Switched to branc ...

  3. (功能篇)回顾Bug管理系统Mantis优化改造经历

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  4. 菜鸟凉经(华为、firehome、大华)

    面试通知都是前一天来的,准备的时间很少,所以表现也不是特别满意,来看面经吧: 华为一面(IT应用工程师): 1.自我介绍:(华为面试都是1对1,面前的是个温柔的小哥,挺放松的) 2.你主要会的it技术 ...

  5. 【MAVEN】Missing artifact jdk.tools:jdk.tools:jar:1.6 eclipse

    搭建开发环境,遇到问题 : IDE 使用 eclipse 公司的项目用Maven管理,从git上拿下来代码后开始build后:    提示    [missing artifact jdk.tools ...

  6. python的闭包函数

    在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用.这样就构成了一个闭包. #闭包函数的实例# outer是外部函数 a和b都是外函数的临时变量def o ...

  7. golang基础--类型与变量

    基础知识--类型与变量 基本类型 布尔型:bool 长度: 1字节 取值范围: false, true 注意事项: 不可以使用数字代表,不像 python中可是使用 1和0表示 整型: int/uin ...

  8. js执行问题

    金三银四搞事季,前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下. 以下是我一个朋友的故事,真的不是我. f ...

  9. 11.5 Daily Scrum

    请把现在当成11月5日······   Today's tasks  Tomorrow's tasks 丁辛 餐厅列表数据结构设计 餐厅列表UI设计             李承晗           ...

  10. 《linux内核分析》作业一:分析汇编代码

    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(王海宁) 姓名:王海宁                             学号:20135103 课程:<Linux内核分析& ...