Qt数据库操作

基本操作

连接

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 TypeDescription
QDB2IBM DB2
QIBASEBorland InterBase Driver
QMYSQLMySQL Driver
QOCIOracle Call Interface Driver
QODBCODBC Driver (includes Microsoft SQL Server)
QPSQLPostgreSQL Driver
QSQLITESQLite version 3 or above
QSQLITE2SQLite version 2
QTDSSybase Adaptive Server

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

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

建议使用QSqlQuery及bindValue操作

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

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


| 版权声明: 本站文章采用 CC 4.0 BY-SA 协议 进行许可,转载请附上原文出处链接和本声明。
| 本文链接: Cologic Blog - Qt数据库操作 - https://www.coologic.cn/2017/11/335/

留下评论