Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台 独立”,既包括操作系统平台,也包括各个数据库平台,Qt支持以下几种数据库:
1.QtSql
要使用QtSql 模块的话,需要在.pro文件中添加这么一句:
QT += sql
2.QSqlDatabase
QSqlDatabase类提供了一个接口,用于通过连接访问数据。QSqlDatabase的一个实例表示连接。该连接通过受支持的数据库驱动程序之一提供对数据库的访问,该驱动程序派生自QSqlDriver。
2.1 创建一个数据库示例如下
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("scooters.dat"); //如果本目录下没有该文件,则会在本目录下生成,否则连接该文件
if (!db.open()) {
QMessageBox::warning(0, QObject::tr("Database Error"),
db.lastError().text());
return false;
}
编译运行后,可以看到已经创建了该文件:
创建成功后,该文件默认为空的,然后就可以使用QSqlQuery类来操作该数据库, QSqlQuery类使用的是SQL语句,如果只需要使用高层次的数据 库接口(不关心 SQL 语法),我们可以选择 QSqlTableModel 和 QSqlRelationalTableModel(在后续章节介绍)。本章我们介绍 QSqlQuery 类,来如何使用SQL语法.
3.QSqlQuery类介绍
通过exec()成员函数来执行DML(数据操作语言)语句,如SELECT、INSERT、UPDATE和DELETE,以及DDL(数据定义语言)语句等.
比如:
QSqlQuery query;
query.exec("DROP TABLE students"); //删除名为students的表
4.接下来,我们讲讲如何导入数据
创建表:
query.exec("CREATE TABLE students ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(40) NOT NULL, "
" score INTEGER NOT NULL, "
"class VARCHAR(40) NOT NULL)");
//创建一个students表,标题分别为id、name、score、class
" PRIMARY KEY AUTOINCREMENT,":表示该列为整数递增,如果为空时则自动填入1,然后在下面的每一行都会自动+1, PRIMARY KEY则表示该列作为列表的主键,通过它可以轻易地获取某一行数据
" INTEGER ":表示该列为带符号的整数
" VARCHAR(40) ":表示该列为可变长字符串,默认只能存储英文和数字或者utf-8,最多存储40个字节.
"NOT NULL ":表示该列的内容不为空
导入数据:
query.exec("INSERT INTO students (name, score,class) "
"VALUES ('小张', 85, '初2-1班')");
//向students表里的(name, score,class)标题下插入一项数据'小张', 85, '初2-1班'
添加后如下图所示:
5.批量导入库
如果我们有大串数据需要导入时,也可以使用prepare()来绑值,然后再通过bindValue()向绑值加入数据
示例代码如下所示:
QStringList names;
names<<"小A"<<"小B"<<"小C"<<"小D"<<"小E"<<"小F"<<"小G"
<<"小H"<<"小I"<<"小G"<<"小K"<<"小L"<<"小M"<<"小N";
QStringList clases;
clases<<"初1-1班"<<"初1-2班"<<"初1-3班"<<"初2-1班"
<<"初2-2班"<<"初2-3班"<<"初3-1班"<<"初3-2班"<<"初3-3班";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("students.dat"); //在本目录下生成
QSqlQuery query;
query.exec("DROP TABLE students"); //先清空一下表
query.exec("CREATE TABLE students ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(40) NOT NULL, "
" score INTEGER NOT NULL, "
"class VARCHAR(40) NOT NULL)");
//创建一个students表
query.prepare("INSERT INTO students (name, score,class) "
"VALUES (:name, :score, :class)");
//为每一列标题添加绑定值
foreach (QString name, names) //从names表里获取每个名字
{
query.bindValue(":name", name); //向绑定值里加入名字
query.bindValue(":score", (qrand() % 101)); //成绩
query.bindValue(":class", clases[qrand()%clases.length()] ); //班级
query.exec(); //加入库中
}
运行后,通过SQLite工具打开students.dat,如下图所示:
6.查询表内容
我们对上图生成的students.dat文件进行查询内容时,则需要使用WHERE 关键字实现.
示例-查询成绩值为60~80之间的学生:
query.exec("SELECT * FROM students WHERE score >= 60 AND score <= 80;");
while(query.next())
{
QString id = query.value(0).toString();
QString name = query.value(1).toString();
QString score = query.value(2).toString();
QString classs = query.value(3).toString();
qDebug()<
运行打印:
当然还有其它语句,比如:
"SELECT * FROM students WHERE score >= 80 OR class == '初3-3班';"
//判断成绩大于等于80,或者班级为初3-3班的
打印如下图所示:
"SELECT * FROM students WHERE class GLOB '*3-3*';"
// GLOB表示通配符,匹配班级带有"3-3"的名字
打印如下图所示:
PS:如果想查询所有内容,则改为 query.exec("SELECT * FROM students ");
7.删表内容
删表内容有3个语句:
示例1
query.exec("DELETE FROM students"); //删除students表里所有内容
删除后如下图所示:
示例2-删除id=3的一行
query.exec("DELETE FROM students WHERE id = 3");
删除前:
删除后:
8.改表内容
改表内容一般用下面两个语句:
8.1 ALTER 示例
示例1
query.exec("ALTER TABLE students RENAME TO new_students"); //将students重命名为new_students
运行后如下图所示:
示例2
query.exec("ALTER TABLE new_students ADD COLUMN 结果 VARCHAR(10)");
//向 new_students表里添加新的一列,标题为结果,内容格式为VARCHAR
运行后如下图所示:
8.2 UPDATE 示例
示例1-不使用WHERE,直接修改某列
query.exec("UPDATE new_students SET score = 100 , name = '小A'");
//修改score和name所在的列内容
修改后如下图所示:
示例2-使用WHERE,判断小于60的设为不合格,否则设为合格
query.exec("UPDATE new_students SET 结果='不合格' WHERE score<60 ");
query.exec("UPDATE new_students SET 结果='合格' WHERE score>=60 ");
修改前如下图所示:
修改后:
注意:QT自带SQLITE数据库,不需要再安装
1.创建一个包含创建、查询、修改和删除数据库的数据库类(DataBase)
DataBase.h头文件
#pragma once
#include
#include
#include
#include
#include
#include "client_global.h"
struct StudentData
{
QString name;
int score;
QString grade;
};
class DataBase : public QObject
{
Q_OBJECT
public:
DataBase(QString name,QObject *parent=0);
~DataBase();
public:
bool insertData(StudentData data);
bool deleteData(int name);
bool getDataByName(int name, StudentData & data);
bool getDataList(QList & list);
bool update();
private:
QSqlDatabase m_DataBase;
private:
bool initTable();
bool isExistTable(QString table);
bool createTable(QString table);
};
DataBase.cpp源文件
#include "XDataBase.h"
#include
#include
#include
DataBase::DataBase(QString name, QObject *parent)
: QObject(parent)
{
if (QSqlDatabase::contains(name)) {
m_DataBase = QSqlDatabase::database(name);
}
else {
m_DataBase = QSqlDatabase::addDatabase("QSQLITE");
m_DataBase.setDatabaseName(QCoreApplication::applicationDirPath()+"/"+ name+".db");
}
initTable();
}
DataBase::~DataBase()
{
}
bool DataBase::initTable()
{
if (!m_DataBase.open()) {
return false;
}
if (!isExistTable("students")) {
createTable("students");
}
return false;
}
bool DataBase::isExistTable(QString table)
{
bool bRet = false;
if (!m_DataBase.open()) {
return bRet;
}
QSqlQuery query(m_DataBase);
query.exec(QString("select count(*) from sqlite_master where type='table' and name='%1'").arg(table)); //关键的判断
if (query.next())
{
if (query.value(0).toInt() > 0)
{
bRet = true;
}
}
return false;
}
bool DataBase::createTable(QString table)
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
if (table == QString("students")) {
bool success = query.exec("CREATE TABLE students ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(40) NOT NULL, "
"score INTEGER NOT NULL, "
"grade VARCHAR(40) NOT NULL)");
if (success) {
return true; //新建数据库成功
}
else {
QSqlError lastError = query.lastError();
QString err = lastError.driverText();
return false;
}
}
else {
return false;
}
}
bool DataBase::insertData(StudentData data)
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
bool success = query.exec(QString("INSERT INTO students (name, score,class) "
"VALUES (%1, %2, %3)").arg(data.name)
.arg(data.score)
.arg(data.grade));
if (!success) {
QSqlError lastError = query.lastError();
QString err = lastError.driverText();
return false;
}
return true;
}
bool DataBase::deleteData(QString name)
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
query.prepare(QString("DELETE FROM students WHERE name='%1'").arg(name));
query.exec();
return false;
}
bool DataBase::getDataByName(int name, StudentData & data)
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
query.prepare(QString("SELECT * FROM students WHERE name='%1'").arg(name));
query.exec();
QSqlRecord rec = query.record();
if (query.next())
{
data.name = query.value(0).toString();
data.score = query.value(1).toInt();
data.grade = query.value(2).toString();
return true;
}
return false;
}
bool DataBase::getDataList(QList& list)
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
query.prepare(QString("SELECT * FROM students"));
query.exec();
QSqlRecord rec = query.record();
while (query.next())
{
StudentData data;
device.name = query.value(0).toInt();
device.score = query.value(1).toString();
device.grade = query.value(2).toInt();
list.append(data);
return true;
}
return false;
}
bool DataBase::update()
{
if (!m_DataBase.open()) {
return false;
}
QSqlQuery query(m_DataBase);
query.prepare("UPDATE students SET score = 100 , name = '小A'");
query.exec();
return false;
}
调用:
XClientApp.h头文件
#pragma once
#include
#include
#include "ServerAPI.h"
#define clientApp static_cast(QCoreApplication::instance())
class XClientApp : public QApplication
{
Q_OBJECT
public:
XClientApp(int argc, char *argv[]);
~XClientApp();
DataBase* getDataBase();
ServerAPI* getServerAPI();
QString getAppName();
private:
void setFont(QString font);
void setStyle();
private:
DataBase* m_pDataBase;
ServerAPI* m_pServerAPI;
signals:
void sglSystemMessage(QString type, QString data);
};
XClientApp.cpp源文件
#include "XClientApp.h"
XClientApp::XClientApp(int argc, char *argv[])
: QApplication(argc, argv)
{
m_pDataBase = new DataBase("xclient", this);
setWindowIcon(QIcon(":/Images/Resources/朱砂古镇.ico"));//可执行程序图标
setStyle();
m_pServerAPI = new ServerAPI(this); //注意有重载
}
DataBase * XClientApp::getDataBase() //获取本地数据库并进行操作
{
return m_pDataBase;
}