QT中sqlite的使用

1. 创建连接

QSqlDatabase  db1=QSqlDatabase::addDatabase("QSQLITE","connect1");
db1.setDatabaseName("memory.db");

1.1 db1是数据库对象,其中打开数据库,查找数据库时要用到这个对象。这个对象只能在创建的线程调用;

1.2 connect1是可选填参数,表示的是连接名。如果不指定连接名,则使用默认的qt_sql_default_connection名字。连接名是一个QString,没有说明限制多长的字符串,实测127个字符也没问题。一个数据库可以有多个连接名,不同连接名可以在不同线程中同时操作。

  • 1.3 memory.db就是数据库的名字。
  • 创建连接后该连接就拥有相应数据库的功能了。

2. 往连接里创建表格

QSqlQuery::exec(“create table student(id int““primary key,name varcher(40)”);

括号里面的字符串是SQLite的命令语句,通过该函数几乎可以运行SQLite的所有命令。但具体用法不是这样,正确的用法如下:

// QSqlQuery query1;//这里没有指定db1,则使用默认连接
QSqlQuery query1(db1); // 这里指定使用连接db1。如果没有创建相应的连接,则会执行错误。
bool ret = query1.exec(“create table student(id int““primary key,name varcher(40)”);
if(ret == false){// 数据库操作失败
    qDebug()<< query.lastError(); //打印错误信息
}


提示: 使用指定连接的好处有两:

  • 一、当一个程序要操作多个数据库时,指定的连接可以对应指定的数据库。
  • 二、当一个程序要多线程操作一个数据库时,就要创建多个连接,不同的线程要用不同的连接。执行QSqlQuery 就要指定数据库连接。(尽量不要多线程操作数据库)

2.1 创建例程运行

创建表格后,运行程序,工程目录下会生成一个.db文件,就是数据库文件。该文件包含了表格内容,需要用相应工具软件打开,如:Navicat(可惜这个工具是收费的),直接百度搜sqlite工具也能找到很多免费的好用工具。同时,里面的数据也可以用该软件导出成其他文本格式。

3. QSqlDatabase类简介

一个数据库可以创建多个连接。

连接的作用就是在qt中操作数据库。

4. QSqlQuery类使用简介

接口API 功能描述
exec(const QString &query) 运行数据库命令,输入字符串。
exec("select * from books" 查询当前连接的books表格所有字段的记录;只有执行了这句,下面的语句才能正常运行。
value(int)  获取当前索引下记录中某个字段的值,输入参数表示几号字段。
int size()

获取当前连接下,正在查询的表格的记录数(行数),并不是所有数据库都支持,SQLite就不支持。可以使用下面方法查询一下,

QSqlDatabase ::hasFeature(QSqlDriver::QuerySize);

如果要查询sqlite的行数,可以使用

QString("SELECT count(*) from %1;").arg(tableName);

last()

将当前连接正在查询的表格定位到最后一条记录,当用其他函数取值时取的就是最后一条记录的值。

当数据量超过10万条时,此函数的耗时会明显增多。

at() 

返回当前跟踪的表格的索引index,类似于数组的下标。字段里的id与这个不一样,字段的值都是自己输入到表格,字段名也可改为不叫id。

seek(int) 将当前跟踪定位到指定位置index。

另外相关的类还有:

QSqlRecord record():获取当前索引的记录,然后可以调用value(const QString &name)获取相应字段的值。调用field(int)可以定位字段。详情可翻看帮助手册。

5. 往表格插入、删除、更新数据

这里直接使用如下api来调用数据库命令即可。

QSqlQuery::exec(const QString &query)

数据库命令可以直接看数据库的命令手册。如下面这些命令:

"select * from books"该句表示查找books表格中所有字段的记录。select是SQLite关键字, "select column1, column2 from books" 这样就是指定查两个字段的值。

"insert into books (id,name) values(4,'The Little Prince')"从books表格尾部加一条记录。

"insert into books (id,name) values(:id,:name)"使用名称占位符插入记录,这样就可以使用变量,可以同时插入多条记录。还有位置占位符形式,:id,:name会变成?,?,详情看QT的教程。

使用示例如下:

QSqlQuery.exec("select * from books"); 
QSqlQuery.exec("select column1, column2 from books");

5.1 列操作

ALTER TABLE tableName ADD COLUMN newColumName BLOB #增加列
ALTER TABLE tableName DROP COLUMN columName #删除列

6. 注意

6.1 多线程操作数据库可能引发程序崩溃。

解决方法:增加互斥量操作数据库。

首先qt中创建数据库连接返回的对象只能在当前线程使用,但是连接名可以多线程使用。如下:

db1对象只能在当前线程使用;

connect1可以在多个线程使用;

QSqlDatabase  db1=QSqlDatabase::addDatabase("QSQLITE","connect1");
db1.setDatabaseName("memory.db");

然后,多线程使用sqlite时,存在资源竞争问题。

默认情况下,在sqlite内部有5中锁状态,某个线程在访问数据库的时候(读或写),都会给数据库上锁,等该线程释放锁后,其他线程才能访问数据库。

推荐阅读《SQLite权威指南》,有中文版翻译。

6.2 同一个线程开了数据库要关闭

如:错误代码示例

// 错误代码示例
QSqlDatabase _db;
_db = QSqlDatabase::database(name);
_db.open();
QSqlQuery query(_db);
query.exec("select * from tableName");
query.next();
...
{
    QSqlDatabase _db;
    _db = QSqlDatabase::database(name2);
    _db.open();
    // ...查询,插入等等操作;
    _db.close();
}

_db.close();

这样操作会导致数据库被锁。

你可能感兴趣的:(qt,数据库,sqlite,qt,数据库)