要是用Qt中的sqlite必须要知道如何使用Qt库,所以这一次是Qt操作数据库的整理,也是Sqlite的使用技巧梳理,各位看官,绝对让你享受不一样的视觉盛宴!!!
Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台
独立”,既包括操作系统平台,也包括各个数据库平台,Qt支持以下几种数据库:
驱动程序 | 数据库 |
---|---|
QDB2 | IBM DB2 7.1版以及更新的版本 |
QIBASE | Borland InterBase |
QMYSQL | MySQL |
QOCI | 甲骨文公司(Oracle Call Interface) |
QODBC | ODBC(包括微软公司的SQL服务器) |
QPSQL | PostgreSQL的7.3版以及更高级的版本 |
QSQLITE | SQLite第3版 |
QSQLITE2 | SQLite第2版 |
QTDS | Sybase自适应服务器 |
要使用QtSql 模块的话,需要在.pro文件中添加这么一句:
QT += sql
QSqlDatabase类提供了一个接口,用于通过连接访问数据。QSqlDatabase的一个实例表示连接。该连接通过受支持的数据库驱动程序之一提供对数据库的访问,该驱动程序派生自QSqlDriver。
检查连接、添加数据库驱动、设置数据库名称、数据库登录用户名、密码。
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("BoFengShuiMeng");
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分支后面两行,设置用户名和密码。用户名,密码都可以随便取,也可以省略。
通过 exec() 成员函数来执行DML(数据操作语言)语句,如SELECT、INSERT、UPDATE和DELETE,以及DDL(数据定义语言)语句等.
比如:
QSqlQuery query;
query.exec("DROP TABLE students"); //删除名为students的表
使用**open()**打开数据库,并判断是否成功。注意,在第一步检查连接是否存在时,如果连接存在,则在返回这个连接的时候,会默认将数据库打开
if (!database.open())
{
qWarning() << "Error: Failed to connect database." << database.lastError();
}
else
{
// do something
}
如果打开成功,则进入else分支。对数据库的操作都需要在else分支中进行。
数据库操作完成后,最好关闭。
database.close();
对数据库进行操作需要用到QSqlQuery类,操作前必须定义一个对象。下面举例说明操作方法。操作需要使用SQLite语句,本文中的几个例子会使用几个常用的语句,关于SQLite语句的具体信息请参考SQLite相关资料。
创建一个名为students 的表格,表格包含三列,第一列是id,第二列是名字,第三列是分数,第四列是班级。
QSqlQuery sql_query(database);
sql_query.exec("create table if not exists 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
///或者这样写
QString create_sql = "create table if not exists students ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(40) NOT NULL, "
"score INTEGER NOT NULL, "
"class VARCHAR(40) NOT NULL)";
sql_query.prepare(create_sql);
if(!sql_query.exec())
{
qWarning()<< "Error: Fail to create table." << sql_query.lastError();
}
else
{
qDebug() << "Table created!";
}
create table if not exists : 表示如果表格存在则不创建,否则创建该表格
"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班'
QString insert_sql = "INSERT INTO students (name, score,class) values (?, ?, ?)";
sql_query.prepare(insert_sql);
sql_query.addBindValue('小张');
sql_query.addBindValue(85);
sql_query.addBindValue('初2-1班');
if(!sql_query.exec())
{
qWarning() << sql_query.lastError();
}
else
{
qDebug() << "inserted finish!";
}
QString insert_sql = "INSERT INTO students (name, score,class) "
"VALUES (:name, :score, :class)");
sql_query.prepare(insert_sql );
//为每一列标题添加绑定值
sql_query.bindValue(":name", '小张'); //向绑定值里加入名字
sql_query.bindValue(":score", 85); //成绩
sql_query.bindValue(":class",'初2-1班'); //班级
if(!sql_query.exec())
{
qWarning() << sql_query.lastError();
}
else
{
qDebug() << "inserted finish!";
}
如果我们有大串数据需要导入时,也可以使用 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(QApplication::applicationDirPath()+"/MyDataBase.db");//在本目录下生成
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(); //加入库中
}
语句:
insert into <table_name> values (value1, value2,…);
insert into 是插入语句,students 是表格名称,values() 是要插入的数据。前面我们采用了不同方式来插入数据。
query.exec("UPDATE students SET score = 100 , name = '小A'");
//修改score和name所在的列内容
采用bindValue方法
QString update_sql = "UPDATE students SET score = :score , name = :name ";
sql_query.prepare(update_sql);
sql_query.bindValue(":score",100);
sql_query.bindValue(":name", "小A");
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "updated!";
}
query.exec("UPDATE students SET 结果='不合格' WHERE score<60 ");
query.exec("UPDATE students SET 结果='合格' WHERE score>=60 ");
语句:
update <table_name> set <f1=value1>, <f2=value2>… where <expression>;
更新(修改)的语句是update…set…,其中student是表格名称,name是表头名称(即第二列),:name是待定的变量,where 用于确定是哪一组数据,:score也是待定变量。
bindValue(" ", " ")函数用来把语句中的待定变量换成确定值。
查询成绩值为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()<<id<<name<<score<<classs;
}
判断成绩大于等于80,或者班级为初3-3班的语句
"SELECT * FROM students WHERE score >= 80 OR class == '初3-3班';"
//判断成绩大于等于80,或者班级为初3-3班的
"SELECT * FROM students WHERE class GLOB '*3-3*';"
// GLOB表示通配符,匹配班级带有"3-3"的名字
查询部分数据
QString select_sql = "select id, name from students ";
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 是查询指令;
上述语句是说查询 students 表中的 id 和 name 。执行查询之后,用sql_query.value(int) 来获得数据。同样地,value(0) 表示第一个数据,即 id,value(1)表示name。注意:value() 函数的返回值类型是 QVariant,因此要用 toInt() 等函数转换成特定的类型。也就是说使用toString() 也可以,看自己需要什么特定的类型。
删表内容有3个语句:
DROP: 用来删除整表,并且连表结构也会删除,删除后则只能使用CREATE TABLE来重新创建表
TRUNCATE: 在SQLite中没有该语句,在MySQL中有该语句,用来清楚表内数据,但是表结构不会删除.
DELETE: 删除部分记录,并且表结构不会删除,删除的速度比上面两个语句慢,可以配合WHERE来删除指定的某行
删除一条数据
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 的条目。
清空表格(删除所有)
QString clear_sql = "delete from student";
sql_query.prepare(clear_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "table cleared";
}
这里没有用where给出限制,就会删除所有内容。
删除数据库
QString clear_sql = "DROP TABLE students"; //删除名为students的表
sql_query.prepare(clear_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "table cleared";
}
语句
DROP from <table_name>
DROP 用于删除数据库
改表内容一般用下面两个语句:
UPDATE : 用来修改表中内容,可以通过WHERE语句来指定修改
ALTER TABLE: 用来重命名表,或者在已有的表中添加新的一列
ALTER 示例
query.exec("ALTER TABLE students RENAME TO new_students");
//将students重命名为new_students
query.exec("ALTER TABLE new_students ADD COLUMN 结果 VARCHAR(10)");
//向 new_students表里添加新的一列,标题为结果,内容格式为VARCHAR
UPDATE 上面已经讲解过了,好了,数据库 sqlit 的操作大法已经讲解完毕!!!