认识
数据库是用于存储、管理和检索数据的系统化集合。它是一种按照特定结构组织数据的存储方式,通过软件(数据库管理系统,DBMS)来实现数据的高效存储、查询、更新和管理。通过文件存储数据适用于少量的数据,而当拥有几十万上百万条数据时,通过文件读写数据所耗的时间就非常长,因此当数据量很大时,就需要使用数据库来存储数据。本文主要介绍了SQLITE的用法。
导入数据库模块
在CMakeLists.txt文件中加入Sql模块
如果使用qmake编译,则在.pro文件中加入以下代码
QT += core gui sql
引用头文件QSqlDatabase查看模块是否导入成功
#include "mainwindow.h"#include <QApplication>
#include <QSqlDatabase>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;qDebug()<<QSqlDatabase::drivers(); // 查看支持的驱动w.show();return a.exec();
}
打开数据库
void openDatabase()
{qDebug()<<QSqlDatabase::drivers(); // 查看支持的驱动// 添加数据库auto database = QSqlDatabase::addDatabase("QSQLITE");// 设置数据库名称database.setDatabaseName("student.db");// 打开数据库if(!database.open()){qDebug()<<database.databaseName()<<"open failed:"<< database.lastError();return;}qDebug()<<"打开数据库成功!";
}
打开数据库成功后会创建一个student.db的文件用于存放数据信息
创建表
// 创建表QSqlQuery query(database); // 连接到database数据库上auto res = query.exec(R"(CREATE TABLE IF NOT EXISTS students (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER))");// 判断表是否创建成功if(!res){qDebug()<<query.lastError().text();return;}qDebug()<<"表创建成功!";
SQL语句解读:
1.
CREATE TABLE IF NOT EXISTS users
CREATE TABLE
:这是 SQL 语句的开头,表示要创建一个新的表。
IF NOT EXISTS
:这是一个可选的条件,用于检查表是否已经存在。如果表已经存在,则不会重复创建,避免了因重复创建表而导致的错误。
students
:这是新表的名称,表示要创建一个名为students
的表。2.
id INTEGER PRIMARY KEY AUTOINCREMENT
id
:这是表中的一个字段名称,表示每个用户的唯一标识符。
INTEGER
:这是字段的数据类型,表示id
字段存储整数类型的数据。
PRIMARY KEY
:这是一个约束,表示id
字段是表的主键。主键用于唯一标识表中的每一行记录,不能有重复值。
AUTOINCREMENT
:这是一个特殊的约束,表示id
字段的值会自动递增。每次插入新记录时,如果未指定id
的值,SQLite 会自动为该字段生成一个唯一的整数值。3.
name TEXT NOT NULL
name
:这是表中的另一个字段名称,表示用户的姓名。
TEXT
:这是字段的数据类型,表示name
字段存储文本类型的数据。
NOT NULL
:这是一个约束,表示name
字段不能为空。在插入或更新数据时,必须为该字段提供一个值,否则会报错。4.
age INTEGER
age
:这是表中的另一个字段名称,表示用户的年龄。
INTEGER
:这是字段的数据类型,表示age
字段存储整数类型的数据。没有约束:这里没有为
age
字段指定NOT NULL
约束,因此age
字段可以为空(即允许插入NULL
值)。
查看字段
// 查看当前数据库有哪些表qDebug()<<database.tables();// 查看表中字段QSqlRecord record = database.record("students");qDebug()<<"有"<<record.count()<<"个字段";for(size_t i = 0;i<record.count();++i){qDebug()<<record.fieldName(i);}
插入数据
// 只能作为初始化插入一次,否则会报错auto sql = R"(INSERT INTO students(id,name,age) VALUES (1,'张三',18),(2,'李四',20),(3,'王五',50);)";if(!query.exec(sql)){qDebug()<<"插入数据失败:"<<query.lastError();return;}
// 插入固定数据(单条)int id = 5;QString name = "超人强";int age = 18;// 准备语句,使用?作为占位符if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}else{// 使用bindValue来绑定// query.bindValue(0,id);// query.bindValue(1,name);// query.bindValue(2,age);// 默认从0开始绑定query.addBindValue(id);query.addBindValue(name);query.addBindValue(age);if(!query.exec()){qDebug()<<"error"<<query.lastError();}}
// 插入多条数据QVariantList id_list{7,8,9};QVariantList name_list{"猪猪侠","小猪猪","ggbond"};QVariantList age_list{18,18,18};if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}query.addBindValue(id_list);query.addBindValue(name_list);query.addBindValue(age_list);// 批量插入if(!query.execBatch()){qDebug()<<"批量插入失败"<<query.lastError();return;}
删除数据
// 删除数据if(!query.exec(R"(DELETE FROM students WHERE id = 1)")){qDebug()<<"数据删除失败!"<<query.lastError();return;}
修改数据
// 修改数据if(!query.exec(R"(UPDATE students SET name = '王八蛋' WHERE name = '李四')")){qDebug()<<"更新数据失败!"<<query.lastError();return;}
查询数据
// 查询数据if(!query.exec("SELECT * FROM students")){qDebug()<<"查询数据失败"<<query.lastError();return;}
打印数据
// 打印全部数据while(query.next()){QSqlRecord record = query.record();qDebug()<<record.value("id")<<record.value("name")<<record.value("age");}
测试代码
void test_database()
{qDebug()<<QSqlDatabase::drivers(); // 查看支持的驱动// 添加数据库auto database = QSqlDatabase::addDatabase("QSQLITE","connect");// 设置数据库名称database.setDatabaseName("student.db");// 打开数据库if(!database.open()){qDebug()<<database.databaseName()<<"open failed:"<< database.lastError();return;}qDebug()<<"打开数据库成功!";// 创建表QSqlQuery query(database); // 连接到database数据库上auto res = query.exec(R"(CREATE TABLE IF NOT EXISTS students (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER))");// 判断表是否创建成功if(!res){qDebug()<<query.lastError().text();return;}qDebug()<<"表创建成功!";// 查看当前数据库有哪些表qDebug()<<database.tables();// 查看表中字段QSqlRecord record = database.record("students");qDebug()<<"有"<<record.count()<<"个字段";for(size_t i = 0;i<record.count();++i){qDebug()<<record.fieldName(i);}// 插入数据// 只能作为初始化插入一次,否则会报错// auto sql = R"(INSERT INTO students(id,name,age) VALUES (1,'张三',18),(2,'李四',20),(3,'王五',50);)";// if(!query.exec(sql))// {// qDebug()<<"插入数据失败:"<<query.lastError();// return;// }// 插入固定数据(单条)int id = 5;QString name = "超人强";int age = 18;// 准备语句,使用?作为占位符if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}else{// 使用bindValue来绑定// query.bindValue(0,id);// query.bindValue(1,name);// query.bindValue(2,age);// 默认从0开始绑定query.addBindValue(id);query.addBindValue(name);query.addBindValue(age);if(!query.exec()){qDebug()<<"error"<<query.lastError();}}// 插入多条数据QVariantList id_list{7,8,9};QVariantList name_list{"猪猪侠","小猪猪","ggbond"};QVariantList age_list{18,18,18};if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}query.addBindValue(id_list);query.addBindValue(name_list);query.addBindValue(age_list);// 批量插入if(!query.execBatch()){qDebug()<<"批量插入失败"<<query.lastError();return;}// 删除数据if(!query.exec(R"(DELETE FROM students WHERE id = 1)")){qDebug()<<"数据删除失败!"<<query.lastError();return;}// 修改数据if(!query.exec(R"(UPDATE students SET name = '王八蛋' WHERE name = '李四')")){qDebug()<<"更新数据失败!"<<query.lastError();return;}// 查询数据if(!query.exec("SELECT * FROM students")){qDebug()<<"查询数据失败"<<query.lastError();return;}// 打印全部数据while(query.next()){QSqlRecord record = query.record();qDebug()<<record.value("id")<<record.value("name")<<record.value("age");}// 关闭数据库database.close();
}
接口封装
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>// 初始化数据库(创建表)
void initDatabase(QSqlQuery& q)
{auto sql = R"(CREATE TABLE IF NOT EXISTS manager(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,age INTEGER))";if(!q.exec(sql)){qDebug()<<"创建表失败!"<<q.lastError();return;}qDebug()<<"创建表成功!";
}// 增加数据
void insertData(QVariant id,QVariant name,QVariant age,QSqlQuery& q)
{// 准备语句,使用?作为占位符if(!q.prepare(R"(INSERT INTO manager(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<q.lastError();return;}else{// 插入单条数据q.addBindValue(id);q.addBindValue(name);q.addBindValue(age);if(!q.exec()){qDebug()<<"error"<<q.lastError();return;}qDebug()<<"插入数据成功!";}
}// 删除数据
void deleteData(QVariant id,QSqlQuery& q)
{// 准备删除语句if (!q.prepare("DELETE FROM manager WHERE id = :id")){qDebug() << "准备删除语句失败:" << q.lastError();return;}// 绑定参数q.bindValue(":id", id.toInt());// 执行删除操作if (!q.exec()){qDebug() << "数据删除失败!" << q.lastError();return;}qDebug() << "删除数据成功!";
}
// 修改数据
void modifyData(QSqlQuery& q,QVariant name,QVariant newName)
{// 修改数据if(!q.prepare("UPDATE manager SET name = :newName WHERE name = :name")){qDebug()<<"准备更新数据失败!"<<q.lastError();return;}q.bindValue(":newName",newName.toString());q.bindValue(":name",name.toString());if(!q.exec()){qDebug()<<"更新数据失败!"<<q.lastError();return;}qDebug()<<"修改数据成功!";}
// 查询数据
void searchData(QSqlQuery& q,QVariant name)
{// 查询数据if(!q.exec("SELECT * FROM manager")){qDebug()<<"查询数据失败"<<q.lastError();return;}while(q.next()){QSqlRecord rec = q.record();if(name == rec.value("name")){qDebug()<<"查询数据成功:"<<rec.value("id")<<rec.value("name")<<rec.value("age");}}
}
// 打印所有数据
void printData(QSqlQuery& q)
{// 执行查询语句if (!q.exec("SELECT * FROM manager")) {qDebug() << "查询失败:" << q.lastError();return;}while(q.next()){QSqlRecord rec = q.record();qDebug()<<rec.value("id")<<rec.value("name")<<rec.value("age");}
}int main(int argc, char *argv[])
{QApplication a(argc, argv);auto db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("manager.db");if(!db.open()){qDebug()<<"数据库打开失败"<<db.lastError();return -1;}qDebug()<<"数据库创建成功!";QSqlQuery query(db);initDatabase(query);insertData(1,"张三",18,query);printData(query);deleteData(1,query);printData(query);modifyData(query,"张三","张无忌");printData(query);searchData(query,"张三");return a.exec();
}