SQLite¶
1 数据库使用¶
1.1 前言¶
基本上每次用数据库都是临时百度下自己的需求,或者找一个现成的轮子直接改一下用。对数据库这块总是一知半解。准备最近这几天花时间,了解下Qt使用数据库并做个记录,方便以后查阅。
Qt下使用数据库无非就两种MySQL和SQLite,具体使用那个看自己的需求,大致区分的话:
-
MySQL 有用户的概念,支持分布式,功能全面。
如果开发服务器程序、数据量很大(几十万)、访问用户很多,建议MySQL。 -
SQLite 没有用户概念、体积小、完全基于单个文件系统的、使用最简单、Qt内置、速度比MySQL快,没有什么端口这种。
嵌入式、单机的软件、基于文件系统频繁写入写出文件、需要无服务器的、零配置的不用考虑直接用 SQLite。
1.2 Qt 使用数据库¶
Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作(操作系统平台和数据库本身的平台)。Qt 的数据库操作还可以很方便的与 model/view 架构进行整合。通常来说,我们对数据库的操作更多地在于对数据库表的操作,而这正是 model/view 架构的长项。Qt 使用驱动(drivers)来与不同的数据库 API 进行交互。
驱动 | 数据库 |
---|---|
QMYSQL | MySQL |
QSQLITE | SQLite 3 |
Qt 只默认搭载 QSqlite 驱动(包括Sqlite 数据库)也就是说,如果需要使用 Sqlite 的话,什么配置都不需要。其他数据库则不行。
如果熟悉sql语法请使用QSqlQuery类!
如果不熟悉sql语法请使用QSqlTableModel类和QSqlRelationalTableModel类!
1.3 Qt 查询安装好的数据库驱动¶
找到系统中的全部驱动,只能使用出现在列表里的驱动。
1.4 Qt 使用 QtSql 模块¶
如果需要用 QtSql,则应该添加 QtSql 模块,添加方式:
qmake:
cmake:
1.5 sql 常用语句¶
- SELECT - 从数据库中提取数据
SELECT column_name,column_name
FROM table_name; - UPDATE - 更新数据库中的数据
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value; - DELETE - 从数据库中删除数据
SELECT column_name,column_name
FROM table_name; - INSERT INTO - 向数据库中插入新数据
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...); - CREATE TABLE - 创建新表
CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
); - DROP TABLE - 删除表
DROP TABLE table_name
2 QT下使用SQLite¶
2.1 什么是SQLite¶
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库一样,您不需要在系统中配置。
就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
2.2 为什么用SQLite¶
- 不需要一个单独的服务器进程或操作的系统(无服务器的)。
- SQLite 不需要配置,这意味着不需要安装或管理。
- 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
- SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
- SQLite 是自给自足的,这意味着不需要任何外部的依赖。
- SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
- SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
- SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
- SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。
3 SQLite常用函数(Qt)¶
先新建几个全局变量,并初始化。
enum SQLiteType {
dbNull = 0,//空值类型
dbInteger = 1,//有符号整数
dbReal = 2,//有符号浮点数,8字节
dbText = 3,//文本字符串
dbBlob = 4,//根据输入类型
};
static QStringList sqlite_type_string_;
static QSqlDatabase data_base;
static QString db_name_ = "study_sql";
qDebug() << QSqlDatabase::drivers();
if (QSqlDatabase::contains(db_name_)) {
data_base = QSqlDatabase::database(db_name_);
} else {
data_base = QSqlDatabase::addDatabase("QSQLITE", db_name_);
}
sqlite_type_string_.append("NULL");
sqlite_type_string_.append("INTEGER");
sqlite_type_string_.append("REAL");
sqlite_type_string_.append("TEXT");
sqlite_type_string_.append("BLOB");
3.1 打开数据库¶
// 打开数据库
bool OpenDb() {
if (!IsOpenedDb()) {
data_base.setDatabaseName(db_name_);
if (!data_base.open()) {
qWarning() << "database open error:" << data_base.lastError().text();
return false;
}
}
return true;
}
3.2 数据库是否开启状态¶
3.3 创建新表¶
// 创建新表
bool CreateTab(const QString &table_name,
const QStringList &key_list,
const QList<SQLiteType> &type_list) {
if (key_list.size() != type_list.size()) {
qWarning() << "keylist != typelist error";
return false;
}
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString sql_str_1 = QString("CREATE TABLE %1 (").arg(table_name);
QString sql_str_3 = ");";
QString sql_str_2 = "%1 %2 PRIMARY KEY ,";
sql_str_2 = sql_str_2
.arg(key_list.at(0))
.arg(sqlite_type_string_.at(type_list.at(0)));
QString sql_str_temp = "%1 %2 ,";
for(qint32 i = 1; i < type_list.count(); i++) {
sql_str_2 += sql_str_temp
.arg(key_list.at(i))
.arg(sqlite_type_string_.at(type_list.at(i)));
}
sql_str_2 = sql_str_2.left(sql_str_2.size() - 1);// 删除多余的 ,
QString sql_str = sql_str_1 + sql_str_2 + sql_str_3;
QSqlQuery query(data_base);
if (query.exec(sql_str)) {
return true;
} else {
qWarning() << "CreateTab error!" << data_base.lastError().text();
return false;
}
}
3.4 删除表¶
// 删除表
bool DropTab(const QString &table_name) {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString sql_str = QString("DROP TABLE '%1'").arg(table_name);
QSqlQuery query(data_base);
if (query.exec(sql_str)) {
return true;
} else {
qWarning() << "DropTab error!" << data_base.lastError().text();
return false;
}
}
3.5 判断表是否存在¶
// 判断表是否存在
bool ExistTab(const QString &table_name, bool &result) {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString sql_str = QString("SELECT 1 FROM sqlite_master "
"WHERE type = 'table' AND name = '%1'").arg(table_name);
QSqlQuery query(data_base);
if (query.exec(sql_str)) {
if (query.next()) {
//有表时返回1,无表时返回null
qint32 sql_result = query.value(0).toInt();
if (sql_result) {
result = true;
return true;
} else {
result = false;
return true;
}
} else {
result = false;
return true;
}
} else {
qWarning() << "sqlstr exec error:" << data_base.lastError().text();
return false;
}
}
3.6 关闭数据库¶
3.7 执行sql语句¶
// 执行sql语句
bool ExeSqlStr(const QString &sql_str) {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QSqlQuery query(data_base);
if(query.exec(sql_str)) {
qDebug() << query.record();
return true;
} else {
qWarning() << "ExeSqlStr error!" << data_base.lastError().text();
return false;
}
}
3.8 查询sql¶
// 查询结果并打印
bool Select(const QString &table_name,
const QStringList &colunms = {"*"},
const QString &where = "") {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QSqlQuery query(data_base);
QString sql_str_columns;
if(colunms.size()) {
sql_str_columns = colunms.join(",");
} else {
qWarning() << "colunms is null";
return false;
}
QString str_where = "";
if (!where.isEmpty()) {
str_where = "WHERE " + where;
}
QString sql_str = QString("SELECT %1 FROM %2 %3")
.arg(sql_str_columns)
.arg(table_name)
.arg(str_where);
if (query.exec(sql_str)) {
qint32 columns_sum = query.record().count();
while (query.next()) {
qDebug() << "-";
for (qint32 i = 0; i < columns_sum; ++i) {
qDebug() << i << query.value(i);
}
}
} else {
qWarning() << "select error!" << data_base.lastError().text();
}
qDebug() << "**************************************************";
return true;
}
3.9 更新数据¶
// 更新数据
bool Updata(const QString &table_name,
const QMap<QString, QVariant> &values,
const QString &where = "") {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString sql_str_data;
foreach (auto var, values.keys()) {
if(!sql_str_data.isEmpty()) {
sql_str_data = sql_str_data + ",";
}
sql_str_data = sql_str_data +
QString("%1=?").arg(var);
}
QString str_where = "";
if (!where.isEmpty()) {
str_where = "WHERE " + where;
}
QString sql_str = QString("UPDATE %1 SET %2 %3")
.arg(table_name)
.arg(sql_str_data)
.arg(str_where);
QSqlQuery query(data_base);
query.prepare(sql_str);
QList<QString> key_list = values.keys();
for (qint32 i = 0; i < key_list.count(); ++i) {
query.bindValue(i, values.value(key_list.at(i)));
}
if(query.exec()) {
return true;
} else {
qWarning() << "updata error!" << data_base.lastError().text();
return false;
}
}
3.10 删除数据¶
// 删除数据
bool Delete(const QString &table_name,
const QString &where = "") {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString str_where = "";
if (!where.isEmpty()) {
str_where = "WHERE " + where;
} else {
qWarning() << "remove erro!" << "where isEmpty ";
return false;
}
QString sql_str = QString("DELETE FROM %1 %2"
).arg(table_name).arg(str_where);
QSqlQuery query(data_base);
if (query.exec(sql_str)) {
return true;
} else {
qWarning() << "remove erro!" << data_base.lastError().text();
return false;
}
}
3.11 插入数据¶
// 插入数据
bool Insert(const QString &table_name,
const QMap<QString, QVariant> &values) {
if (!IsOpenedDb()) {
qWarning() << "database not open error!";
return false;
}
QString str_column, str_value;
QList<QString>key_list = values.keys();
foreach (auto var, key_list) {
if(!str_column.isEmpty()) {
str_column += ",";
}
str_column += var;
if(!str_value.isEmpty()) {
str_value += ",";
}
str_value += "?";
}
QString sql_str = QString("INSERT INTO %1(%2) VALUES(%3)")
.arg(table_name).arg(str_column).arg(str_value);
QSqlQuery query(data_base);
query.prepare(sql_str);
for (qint32 i = 0; i < key_list.count(); ++i) {
query.bindValue(i, values.value(key_list.at(i)));
}
if (query.exec()) {
return true;
} else {
qWarning() << "insert error!" << data_base.lastError().text();
return false;
}
}
3.12 测试¶
#define study_OPEN_CLOSE 1
#define study_SELECT 1
#define study_UPDATE 1
#define study_DELETE 1
#define study_INSERT_INTO 1
#define study_CREATE_DROP_EXIST 1
int main(int, char *[]) {
#if study_OPEN_CLOSE // study open&&close
qDebug() << QSqlDatabase::drivers();
if (QSqlDatabase::contains(db_name_)) {
data_base = QSqlDatabase::database(db_name_);
} else {
data_base = QSqlDatabase::addDatabase("QSQLITE", db_name_);
}
sqlite_type_string_.append("NULL");
sqlite_type_string_.append("INTEGER");
sqlite_type_string_.append("REAL");
sqlite_type_string_.append("TEXT");
sqlite_type_string_.append("BLOB");
OpenDb();
#if study_SELECT // study sql SELECT
Select("test01");
Select("test01", {"name", "abbreviation"}, "Whether31='1'");
#endif
#if study_UPDATE // study sql UPDATE
Select("test01", {"name", "abbreviation"}, "Whether31='0'");
QMap<QString, QVariant> values;
values.insert("name", "28天的月");
Updata("test01", values, "Whether31='0'");
Select("test01", {"name", "abbreviation"}, "Whether31='0'");
values["name"] = "二月";
Updata("test01", values, "Whether31='0'");
Select("test01", {"name", "abbreviation"}, "Whether31='0'");
#endif
#if study_DELETE // study DELETE
Select("test01");
Delete("test01", "Whether31='0'");
Select("test01");
#endif
#if study_INSERT_INTO // study INSERT INTO
Select("test01");
QMap<QString, QVariant> values1;
values1.insert("id", "2");
values1.insert("name", "二月");
values1.insert("全拼", "February");
values1.insert("缩写", "Feb");
values1.insert("多少天", "28");
values1.insert("Whether31", "0");
Insert("test01", values1);
Select("test01");
#endif
#if study_CREATE_DROP_EXIST // study INSERT INTO
bool resutl;
ExistTab("study_CREATE_DROP_EXIST", resutl);
qDebug() << resutl;
CreateTab("study_CREATE_DROP_EXIST",
{"id", "name"},
{SQLiteType::dbInteger, SQLiteType::dbText});
ExistTab("study_CREATE_DROP_EXIST", resutl);
QMap<QString, QVariant> values2, values3;
values2.insert("id", "0");
values2.insert("name", "张三");
values3.insert("id", "1");
values3.insert("name", "李四");
Insert("study_CREATE_DROP_EXIST", values2);
Insert("study_CREATE_DROP_EXIST", values3);
qDebug() << resutl;
Select("study_CREATE_DROP_EXIST");
DropTab("study_CREATE_DROP_EXIST");
ExistTab("study_CREATE_DROP_EXIST", resutl);
qDebug() << resutl;
#endif
CloseDb();
#endif
return 0;
}