基本操作
连接
if(!QSqlDatabase::contains()) { QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");//第二参数不提供名字,使用默认名称,第一个参数为数据库类型名 database.setDatabaseName(m_db_file_name);//数据库名--sqlite是文件名,sqlite不用写下面的配置 database.setHostName("www.coologic.cn"); //数据库主机名 database.setUserName("user"); //数据库用户名 database.setPassword("******"); //数据库密码 if(!database.open()) { qDebug()<<database.lastError(); } }
注意addDatabase有两个参数,第二个参数是用于给此连接命名的,若不命名则为默认名称。
默认名称为:qt_sql_default_connection
static QSqlDatabase addDatabase(QSqlDriver* driver, const QString& connectionName = QLatin1String(defaultConnection));
断开连接
虽然关闭程序以后默认会断开,不会导致文件永久占用,但是建议数据库用完主动断开
QSqlDatabase database = QSqlDatabase::database();//根据连接名称获取数据库,不填写则为默认连接名 database.close();
sql指令操作
简单一次操作:
const static QString mInsertCategorySql = "insert into category values (null,?)";//增,name名字
如果有自增量,或其他不需要输入的字段,只需要在对应位置输入null即可,注意不是字符串null
对于需要填充的地方可以用?代替,后续可直接用addBindValue或者bindValue指令替换,按照?出现顺序替换
bool SqlManager::InsertCategorySql(QString name) { QSqlQuery sql_query;//默认构造使用默认数据库 sql_query.prepare(mInsertCategorySql); sql_query.addBindValue(name); if(!sql_query.exec()) { qDebug() << sql_query.lastError(); return false; } return true; }
多字段:
const static QString mInsertJournalSql = "insert into journal values (null,:catagory,:date,:value,:remark,:auditing)";
使用”:XXXX”作为占位符,使用bindValue指令替换
注意,只需要给出对应类型即可,Qt会自动进行转换,包括日期、时间均只给出Qt对应类型即可
在Sqlite中日期格式AAAA-BB-CC,也可以以字符串形式输入但需要保证格式正确,不建议自行转换格式
bool SqlManager::InsertJournalSql(int catagory_id, QDate date, float value, QString remark, bool auditing) { QSqlQuery sql_query;//默认构造使用默认数据库 sql_query.prepare(mInsertJournalSql); sql_query.bindValue(":catagory",catagory_id); sql_query.bindValue(":date",date); sql_query.bindValue(":value",value); sql_query.bindValue(":remark",remark); sql_query.bindValue(":auditing",auditing); if(!sql_query.exec()) { qDebug() << sql_query.lastError(); return false; } return true; }
有返回值的操作:
const static QString mSelectAllJournalSql = "select * from journal ORDER BY data DESC";//查询所有
struct JournalStruct { long long id;//分类id QString catagory;//分类 QString date;//日期 float value;//值 QString remark;//备注 }; QList<JournalStruct> SqlManager::SelectUnauditJournalSql(bool is_all) { QSqlQuery sql_query;//默认构造使用默认数据库 if(is_all) sql_query.prepare(mSelectAllJournalSql); else sql_query.prepare(mSelectUnauditJournalSql); QList<JournalStruct> s; if(!sql_query.exec()) { qDebug() << sql_query.lastError(); return s; } else { //建立类型索引 auto cates = SelectCategorySql(); while(sql_query.next()) { s.append({sql_query.value(0).toLongLong(), sql_query.value(1).toInt(), sql_query.value(2).toString(), sql_query.value(3).toFloat(), sql_query.value(4).toString()}); } return s; } }
注意:QSqlQuery 结果默认指向空,必须先调用一次next()会指向第一个结果值,通过.value(0)取对应字段值,通过toXXX转换为对应格式。
详细操作代码请见流水账记录软件→GitHub
其他
多数据库情况下QSqlQuery 的使用
上述所有操作,均使用了Qt默认名称数据库,故可以直接通过 QSqlQuery XX构造实例。
若指定了特定的数据库名称,或者有多个数据库需要使用
QSqlQuery(QSqlDatabase db);
其中db可以下面的函数获取
static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection), bool open = true); 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注入。
同时此方式可读性强,也对对特殊字符具有良好的支持性。
最新评论