Qt操作中你需要知道的Sqlite 玩法,隔壁Java、Python等一系列大爷看了都直呼内行!!!

前言

要是用Qt中的sqlite必须要知道如何使用Qt库,所以这一次是Qt操作数据库的整理,也是Sqlite的使用技巧梳理,各位看官,绝对让你享受不一样的视觉盛宴!!!

Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台
独立”,既包括操作系统平台,也包括各个数据库平台,Qt支持以下几种数据库:

文档如下:
在这里插入图片描述
下面是整理的表格中文描述:

驱动程序数据库
QDB2IBM DB2 7.1版以及更新的版本
QIBASEBorland InterBase
QMYSQLMySQL
QOCI甲骨文公司(Oracle Call Interface)
QODBCODBC(包括微软公司的SQL服务器)
QPSQLPostgreSQL的7.3版以及更高级的版本
QSQLITESQLite第3版
QSQLITE2SQLite第2版
QTDSSybase自适应服务器
  • QT自带SQLITE数据库,不需要再安装
  • QTDS在Qt4.7起已经被移除

QtSql

要使用QtSql 模块的话,需要在.pro文件中添加这么一句:

QT += sql 

QSqlDatabase

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分支后面两行,设置用户名和密码。用户名,密码都可以随便取,也可以省略。

QSqlQuery类介绍

通过 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!";
}
采用占位符:XXX 插入

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() 是要插入的数据。前面我们采用了不同方式来插入数据。

  • 采用方式一插入数据的时候,则是直接写出完整语句。
  • 采用方式二插入数据数据的时候,用addBindValue来替代语句中的?,替代的顺序与addBindValue调用的顺序相同。
  • 采用方式三插入数据数据的时候,用 bindValue(" ", " ")函数用来把语句中的待定变量换成确定值。

更新数据(修改数据)

  1. 不使用WHERE,直接修改某列
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!";
}
  1. 使用WHERE,判断小于60的设为不合格,否则设为合格
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 是查询指令;<f1> 等等是要查询的变量(即表头),中间用逗号隔开;**from …**指定表格。

上述语句是说查询 students 表中的 idname 。执行查询之后,用sql_query.value(int) 来获得数据。同样地,value(0) 表示第一个数据,即 idvalue(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 的操作大法已经讲解完毕!!!

评论 63
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fu_Lin_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值