在Qt中使用SQLite数据库
前言
SQLite(sql)是一款开源轻量级的数据库软件,不需要server,可以集成在其他软件中,非常适合嵌入式系统。
Qt5以上版本可以直接使用SQLite(Qt自带驱动)。
用法
1 准备
- 引入SQL模块
在Qt项目文件(.pro文件)中,加入SQL模块:
QT += sql
- 引用头文件
在需要使用SQL的类定义中,引用相关头文件。例如:
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
2 使用
1. 建立数据库
检查连接、添加数据库驱动、设置数据库名称、数据库登录用户名、密码。
QSqlDatabase database;
if (QSqlDatabase::contains("qt_sql_default_connection"))
{
database = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName("MyDataBase.db");
database.setUserName("XingYeZhiXia");
database.setPassword("123456");
}
上述代码解释:
(1)第一行中,建立了一个QSqlDatabase
对象,后续的操作要使用这个对象。
(2)if
语句用来检查指定的连接(connection)是否存在。这里指定的连接名称(connection name)是qt_sql_default_connection
,这是Qt默认连接名称。实际使用时,这个名称可以任意取。如果判断此连接已经存在,那么QSqlDatabase::contains()
函数返回true。此时,进入第一个分支,QSqlDatabase::database()
返回这个连接。
(3)如果这个连接不存在,则进入else
分支,需要创建连接,并添加数据库。在else
分支第一行,addDatabase()
的参数QSQLITE
是SQLite对应的驱动名,不能改。而且需要注意的是,addDatabase()
的第二个参数被省略了,第二个参数的默认参数就是上面提到的Qt默认连接名称qt_sql_default_connection
。如果需要使用自定义的连接名称(如果程序需要处理多个数据库文件的话就会这样),则应该加入第二个参数,例如
database = QSqlDatabase::addDatabase("QSQLITE", "my_sql_connection);
这个时候,如果在另一个地方需要判断my_sql_connection
连接是否存在,就应该使用if (QSqlDatabase::contains("my_sql_connection"))
。
(4)else
分支第二行中,setDatabaseName()
的参数是数据库文件名。如果这个数据库不存在,则会在后续操作时自动创建;如果已经存在,则后续的操作会在已有的数据库上进行。
(5)else
分支后面两行,设置用户名和密码。用户名,密码都可以随便取,也可以省略。
2. 打开数据库
使用open()
打开数据库,并判断是否成功。注意,在第一步检查连接是否存在时,如果连接存在,则在返回这个连接的时候,会默认将数据库打开。
if (!database.open())
{
qDebug() << "Error: Failed to connect database." << database.lastError();
}
else
{
// do something
}
如果打开成功,则进入else分支。对数据库的操作都需要在else分支中进行。
3. 关闭数据库
数据库操作完成后,最好关闭。
database.close();
4. 操作数据库
对数据库进行操作需要用到QSqlQuery类,操作前必须定义一个对象。下面举例说明操作方法。操作需要使用SQLite语句,本文中的几个例子会使用几个常用的语句,关于SQLite语句的具体信息请参考SQLite相关资料。
例1:创建表格
创建一个名为student的表格,表格包含三列,第一列是id,第二列是名字,第三列是年龄。
QSqlQuery sql_query;
QString create_sql = "create table student (id int primary key, name varchar(30), age int)";
sql_query.prepare(create_sql);
if(!sql_query.exec())
{
qDebug() << "Error: Fail to create table." << sql_query.lastError();
}
else
{
qDebug() << "Table created!";
}
代码解释:
(1)第一行定义一个QSqlQuery
对象。
(2)第二行是一个QString
,其中的内容是SQLite语句。对数据库的操作,都是用SQLite的语句完成的,把这些指令以QString类型,通过prepare
函数,保存在QSqlQuery对象中。也可将指令,以QString形式直接写在exec()
函数的参数中,例如:
sql_query.exec("create table student (id int primary key, name varchar(30), age int)");
创建表格语句:create table <table_name> (f1 type1, f2 type2,…);
create table
是创建表格的语句,也可用大写CREATE TABLE
;student是表格的名称,可以任意取;括号中是表格的格式,上述指令表明,表格中有三列,第一列的名称(表头)是id,这一列储存的数据类型是int,第二列名称是name,数据类型是字符数组,最多有30个字符(和char(30)的区别在于,varchar的实际长度是变化的,而char的长度始终是给定的值),第三列的名称是age,数据类型是int。
如果sql_query.exec()
执行成功,则创建表格成功。
例2:插入数据
在刚才创建的表格中,插入一行数据。
QString insert_sql = "insert into student values (?, ?, ?)";
sql_query.prepare(insert_sql);
sql_query.addBindValue(max_id+1);
sql_query.addBindValue("Wang");
sql_query.addBindValue(25);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "inserted Wang!";
}
if(!sql_query.exec("INSERT INTO student VALUES(3, \"Li\", 23)"))
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "inserted Li!";
}
插入语句:insert into <table_name> values (value1, value2,…);
insert into
是插入语句,student是表格名称,values()是要插入的数据。这里,我们插入了2组数据。插入第一组数据的时候,用addBindValue
来替代语句中的?
,替代的顺序与addBindValue
调用的顺序相同。插入第二组数据的时候,则是直接写出完整语句。
例3:更新数据(修改数据)
QString update_sql = "update student set name = :name where id = :id";
sql_query.prepare(update_sql);
sql_query.bindValue(":name", "Qt");
sql_query.bindValue(":id", 1);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "updated!";
}
语句:update <table_name> set <f1=value1>, <f2=value2>… where <expression>;
更新(修改)的语句是update...set...
,其中student是表格名称,name是表头名称(即第二列),:name是待定的变量,where用于确定是哪一组数据,:id也是待定变量。
bindValue(" ", " ")
函数用来把语句中的待定变量换成确定值。
例4:查询数据
(1)查询部分数据
QString select_sql = "select id, name from student";
if(!sql_query.exec(select_sql))
{
qDebug()<<sql_query.lastError();
}
else
{
while(sql_query.next())
{
int id = sql_query.value(0).toInt();
QString name = sql_query.value(1).toString();
qDebug()<<QString("id:%1 name:%2").arg(id).arg(name);
}
}
语句select <f1>, <f2>, ... from <table_name>;
select是查询指令;<f1>
等等是要查询的变量(即表头),中间用逗号隔开;from ...指定表格。
上述语句是说查询student表中的 id 和 name 。执行查询之后,用sql_query.value(int)
来获得数据。同样地,value(0)
表示第一个数据,即 id,value(1)
表示name。注意:value()
函数的返回值类型是QVariant
,因此要用toInt()
等函数转换成特定的类型。
(2)查询全部数据
QString select_all_sql = "select * from student";
sql_query.prepare(select_all_sql);
if(!sql_query.exec())
{
qDebug()<<sql_query.lastError();
}
else
{
while(sql_query.next())
{
int id = sql_query.value(0).toInt();
QString name = sql_query.value(1).toString();
int age = sql_query.value(2).toInt();
qDebug()<<QString("id:%1 name:%2 age:%3").arg(id).arg(name).arg(age);
}
}
语句select * from <table_name>;
查询所有数据用 * 表示。用while(sql_query.next())
用来遍历所有行。同样用value()
获得数据。
(3)查询最大id
QString select_max_sql = "select max(id) from student";
int max_id = 0;
sql_query.prepare(select_max_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
while(sql_query.next())
{
max_id = sql_query.value(0).toInt();
qDebug() << QString("max id:%1").arg(max_id);
}
}
这个就是在语句中用max
来获取最大值。
例5:删除与清空
(1)删除一条数据
QString delete_sql = "delete from student where id = ?";
sql_query.prepare(delete_sql);
sql_query.addBindValue(0);
if(!sql_query.exec())
{
qDebug()<<sql_query.lastError();
}
else
{
qDebug()<<"deleted!";
}
语句delete from <table_name> where <f1> = <value>
delete用于删除条目,用where给出限定条件。例如此处是删除 id = 0的条目。
(2)清空表格(删除所有)
QString clear_sql = "delete from student";
sql_query.prepare(clear_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "table cleared";
}
这里没有用where给出限制,就会删除所有内容。
在Qt中使用SQLite数据库的更多相关文章
- Android虚拟机中的sqlite数据库文件
Android虚拟机中的sqlite数据库文件 ①
- 在项目中使用SQLite数据库小结
------------------------------------------------------------------------推荐: - VS2012 使用 1.0.84 版的库 - ...
- 2014-08-01 ASP.NET中对SQLite数据库的操作——ADO.NET
今天是在吾索实习的第18天.我主要学习了如何在ASP.NET中对SQLite数据库的操作,其基本操作如下: 添加引用System.Data.SQLite.dll(PS:在网页里面任意找到适合的.NET ...
- android中与SQLite数据库相关的类
为什么要在应用程序中使用数据库?数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆 ...
- Go语言中使用SQLite数据库
Go语言中使用SQLite数据库 1.驱动 Go支持sqlite的驱动也比较多,但是好多都是不支持database/sql接口的 https://github.com/mattn/go-sqlite3 ...
- 在Android 开发中使用 SQLite 数据库笔记
SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PH ...
- 在 Android 应用程序中使用 SQLite 数据库以及怎么用
part one : android SQLite 简单介绍 SQLite 介绍 SQLite 一个非常流行的嵌入式数据库.它支持 SQL 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...
- Qt中提高sqlite的读写速度(使用事务一次性写入100万条数据)
SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度.例如:向数据库中插入100万条数 ...
- qt中使用sqlite存储数据
一.sqilte的安装 在Windows上安装SQLite: 请访问 SQLite 下载页面,从 Windows 区下载预编译的二进制文件. 您需要下载 sqlite-tools-win32-*.zi ...
随机推荐
- javascript系列学习----对象相关概念理解
1.构造函数(相对于面向对象编程语言里面的类) 2.对象实例(它是由构造函数构造出来的对象,使用到关键字 new) 3.this关键字(往往是指我们的对象本身) 下面我们来看一个实例: var Per ...
- HDOJ5437(优先队列)
Alisha’s Party Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- linux tcp server demo
#include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <ne ...
- java代码---------计算器实现
总结:虽然,没有人会帮你到底,凭什么要对你怜香惜玉 注意实现哪一个运算就把相关代码放在else if这个判断语句里面 package com.rue; import java.awt.BorderLa ...
- css3 box-shadow阴影(外阴影与外发光)讲解
基础说明: 外阴影:box-shadow: X轴 Y轴 Rpx color; 属性说明(顺序依次对应): 阴影的X轴(可以使用负值) 阴影的Y轴(可以使用负值) 阴影 ...
- ThinkPHP 目录结构
2.0 ThinkPHP 目录结构 在前面的博客中,通过一个简单的案例向大家演示了在ThinkPHP 框架下开发的大致法程,本篇博客将对ThinkPHP框架目录结构进行详细讲解. 要想在项目中熟练地使 ...
- 【转】C#父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
原文地址:http://www.xuebuyuan.com/1092603.html Win7+VS2010测试的结果如下: ①子类静态成员变量②子类静态构造函数③子类实例成员变量④父类静态成员变量⑤ ...
- FastDFS:搭建文件管理系统
文章转自:https://www.cnblogs.com/chiangchou/p/fastdfs.html#_label1 一.FastDFS介绍 FastDFS开源地址:https://githu ...
- php效率优化
php效率优化 最近在公司一边自学一边写PHP程序,由于公司对程序的运行效率要求很高,而自己又是个新手,一开始就注意程序的效率很重要,这里就结合网上的一些资料,总结下php程序效率优化的一些策略:1. ...
- Android Studio里面配置Tesseract
网上大多是eclipse的项目,因为我用的是AS,所以说一下怎么配置. 身份证图片资料来自百度. 一.导入相关文件 其实我们不用自己编译,可以把别人项目编译好的jar包和so库直接拿来用.因为识别的效 ...