title: “ Qt数据库操作\t\t”
tags:

  • qt
  • sqlite
  • 数据库
    url: 335.html
    id: 335
    categories:
  • Qt
    date: 2017-11-25 21:59:37

基本操作

连接

  1. if(!QSqlDatabase::contains()) {
  2. QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");//第二参数不提供名字,使用默认名称,第一个参数为数据库类型名
  3. database.setDatabaseName(m_db_file_name);//数据库名--sqlite是文件名,sqlite不用写下面的配置
  4. database.setHostName("techieliang.com"); //数据库主机名
  5. database.setUserName("user"); //数据库用户名
  6. database.setPassword("******"); //数据库密码
  7. if(!database.open()) {
  8. qDebug()<<database.lastError();
  9. }
  10. }

注意addDatabase有两个参数,第二个参数是用于给此连接命名的,若不命名则为默认名称。 默认名称为:qt_sql_default_connection

  1. static QSqlDatabase addDatabase(QSqlDriver* driver,
  2. const QString& connectionName = QLatin1String(defaultConnection));

断开连接

虽然关闭程序以后默认会断开,不会导致文件永久占用,但是建议数据库用完主动断开

  1. QSqlDatabase database = QSqlDatabase::database();//根据连接名称获取数据库,不填写则为默认连接名
  2. database.close();

sql指令操作

简单一次操作:

  1. const static QString mInsertCategorySql =
  2. "insert into category values (null,?)";//增,name名字

如果有自增量,或其他不需要输入的字段,只需要在对应位置输入null即可,注意不是字符串null

对于需要填充的地方可以用?代替,后续可直接用addBindValue或者bindValue指令替换,按照?出现顺序替换

  1. bool SqlManager::InsertCategorySql(QString name) {
  2. QSqlQuery sql_query;//默认构造使用默认数据库
  3. sql_query.prepare(mInsertCategorySql);
  4. sql_query.addBindValue(name);
  5. if(!sql_query.exec()) {
  6. qDebug() << sql_query.lastError();
  7. return false;
  8. }
  9. return true;
  10. }

多字段:

  1. const static QString mInsertJournalSql =
  2. "insert into journal values (null,:catagory,:date,:value,:remark,:auditing)";

使用”:XXXX”作为占位符,使用bindValue指令替换

注意,只需要给出对应类型即可,Qt会自动进行转换,包括日期、时间均只给出Qt对应类型即可

在Sqlite中日期格式AAAA-BB-CC,也可以以字符串形式输入但需要保证格式正确,不建议自行转换格式

  1. bool SqlManager::InsertJournalSql(int catagory_id,
  2. QDate date,
  3. float value,
  4. QString remark,
  5. bool auditing) {
  6. QSqlQuery sql_query;//默认构造使用默认数据库
  7. sql_query.prepare(mInsertJournalSql);
  8. sql_query.bindValue(":catagory",catagory_id);
  9. sql_query.bindValue(":date",date);
  10. sql_query.bindValue(":value",value);
  11. sql_query.bindValue(":remark",remark);
  12. sql_query.bindValue(":auditing",auditing);
  13. if(!sql_query.exec()) {
  14. qDebug() << sql_query.lastError();
  15. return false;
  16. }
  17. return true;
  18. }

有返回值的操作:

  1. const static QString mSelectAllJournalSql =
  2. "select * from journal ORDER BY data DESC";//查询所有
  1. struct JournalStruct {
  2. long long id;//分类id
  3. QString catagory;//分类
  4. QString date;//日期
  5. float value;//值
  6. QString remark;//备注
  7. };
  8. QList<JournalStruct> SqlManager::SelectUnauditJournalSql(bool is_all) {
  9. QSqlQuery sql_query;//默认构造使用默认数据库
  10. if(is_all)
  11. sql_query.prepare(mSelectAllJournalSql);
  12. else
  13. sql_query.prepare(mSelectUnauditJournalSql);
  14. QList<JournalStruct> s;
  15. if(!sql_query.exec()) {
  16. qDebug() << sql_query.lastError();
  17. return s;
  18. }
  19. else {
  20. //建立类型索引
  21. auto cates = SelectCategorySql();
  22. while(sql_query.next()) {
  23. s.append({sql_query.value(0).toLongLong(),
  24. sql_query.value(1).toInt(),
  25. sql_query.value(2).toString(),
  26. sql_query.value(3).toFloat(),
  27. sql_query.value(4).toString()});
  28. }
  29. return s;
  30. }
  31. }

注意:QSqlQuery 结果默认指向空,必须先调用一次next()会指向第一个结果值,通过.value(0)取对应字段值,通过toXXX转换为对应格式。 详细操作代码请见流水账记录软件→GitHub

其他

多数据库情况下QSqlQuery 的使用

上述所有操作,均使用了Qt默认名称数据库,故可以直接通过 QSqlQuery XX构造实例。 若指定了特定的数据库名称,或者有多个数据库需要使用

QSqlQuery(QSqlDatabase db);

其中db可以下面的函数获取

  1. static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection),
  2. bool open = true);
  3. QSqlQuery query(QSqlDatabase::database("connectionName"));

Qt支持的数据库

Driver Type Description
QDB2 IBM DB2
QIBASE Borland InterBase Driver
QMYSQL MySQL Driver
QOCI Oracle Call Interface Driver
QODBC ODBC Driver (includes Microsoft SQL Server)
QPSQL PostgreSQL Driver
QSQLITE SQLite version 3 or above
QSQLITE2 SQLite version 2
QTDS Sybase Adaptive Server

上述数据取自Qt帮助文档中QSqlDatabase的描述,其中sqlite驱动默认集成,其余数据库需要安装对应驱动否则无法使用

关于驱动的具体说明请见:SQL Database Drivers帮助文档

建议使用QSqlQuery及bindValue操作

不建议使用qstring的arg()方法自行拼接字符串,使用bindValue可以有效的防止SQL注入。

同时此方式可读性强,也对对特殊字符具有良好的支持性。