QT_数据库

时间:2024-04-13 14:34:33
查看QT支持的数据库类型

主要代码:

QStringList sl = QSqlDatabase::drivers();
foreach(QString str, sl)
{
    qDebug() << str;
}

程序输出:

"QSQLITE"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"

如果想使用其他数据库,需要自己手动添加

数据库操作
加载数据库

主要代码:

{
    //加载数据库,addDatabase第一个参数为数据库驱动名,第二个为连接名
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "connect-name");
    //设置数据库名字
    db.setDatabaseName("Live");
    if(db.open())
    {
        //success
        db.close();
    }
}
QSqlDatabase::removeDatabase("connect-name");

注意:

使用驱动程序类型和连接名称ConnectionName将数据库添加到数据库连接列表中。如果已经存在名为ConnectionName的数据库连接,则删除该连接。

数据库连接使用连接名来定义,而不是使用数据库名,可以向相同的数据库创建多个连接。
QSqlDatabase也支持默认连接的概念,默认连接就是一个没有命名的连接。

通过连接寻找数据库

主要代码:

QSqlDatabase db = QSqlDatabase:: database("connect-name");

注意:

  1. 数据库的连接是不能跨线程使用的,在主线程中加载数据库得到的连接名,只能在主线程中使用,而不能在子线程中使用。
  2. 如果想让数据库在子线程中使用,则必须在子线程中加载数据库,得到新的连接名,然后在子线程中使用这个新的连接找到数据库,然后对其操作。
执行SQL语句

QSqlQuery类提供了一个接口,用于执行SQL语句和浏览查询的结果集。要执行一个SQL语句,只需要创建一个QSqlQuery对象,然后调用QSqlQuery::exec()函数即可。

QSqlDatabase db = QSqlDatabase::database("connection-name");
QSqlQuery query(db);
query.exec("sql语句");

创建表

create table if not exists 表名(字段1,字段2,...)

新增数据

insert into 表名 values(数据1,数据2,...)

查询数据

select * from 表名

删除数据

delete from 表名 where 条件控制语句

更新数据

update 表名 set 字段1=数据1,字段2=数据2...
事务操作

事务可以保证一个复杂的操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,是不可分割的工作单位。
相关函数:

QSqlDriver::hasFeature(QSqlDriver::Transactions)
QSqlDatabase::transaction()
QSqlDatabase::commit()
QSqlDatabase::rollback()

事务操作实际上是将一系列操作后的结果进行缓存,在最后进行commit的时候,再一次性同步到数据库中,如果中间有操作失败,则调用rollback进行回滚,撤销缓存中的操作结果。

SQL模型类

Qt提供了3个更高层的类来访问数据库,分别是QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。
这3个类都是从QAbstractTableModel派生来的,可以很容易地实现将数据库中的数据在QListView和QTableView等视图类中进行显示。

QSqlQueryModel模型

主要代码

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite-connect");
db.setDatabaseName("data");
if(db.open())
{
    //success
    QSqlQuery query(db);
    query.exec("create table if not exists User(username,password,phoneNumber)");
}
QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select * from User",db);
ui->tableView->setModel(model);

QSqlQueryModel模型默认是只读的,所以我们在窗口上并不能对表格中的内容进行修改。但是我们可以创建自己的模型,然后按照我们自己的需要来显示数据和修改数据。如果要想使其可读写,需要自己的类继承自QSqlQueryModel,并且重写setData()和flags()两个函数,如果我们要改变数据的显示,就要重写data()函数。

QSqlTableModel模型

QSqlTableModel提供了,一个一次只能操作一个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需要编写很少的代码,而且不需要了解SQL语法。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite-connect");
db.setDatabaseName("data");
if(db.open())
{
    //success
    QSqlQuery query(db);
    query.exec("create table if not exists User(username,password,phoneNumber)");
}
QSqlTableModel *model = new QSqlTableModel(this,db);
model->setTable("User");
model->select();
model->setEditStrategy(QSqlTableModel::OnFieldChange);
ui->tableView->setModel(model);

QSqlTableModel::EditStrategy

Constant                        Value   Description
QSqlTableModel::OnFieldChange   0       tableView中数据一更改就同步到数据库中
QSqlTableModel::OnRowChange     1       修改一行,当点击另一行时,将修改的哪一行同步到数据库中
QSqlTableModel::OnManualSubmit  2       自己手动操作,submitAll() or revertAll()
QSqlRelationalTableModel模型

QSqlRelationalTableModel继承于QSqlTableModel
QSqlRelationalTableModel类为单个数据库表提供可编辑的数据模型,并具有外键支持。
QSqlRelationalTableModel类似于QSqlTableModel,但允许将列设置为其他数据库表的外键。

外键(foreign key): 如果一个A表的字段指向另一个B表的主键,则此字段就为A表的外键。用于表示表外之间的关系。存在外键的表,称之为从表(子表),外键指向的表,称之为主表(父表)。

这两张表都必须要有主键

主键(primary key):每个表只能有最多一个主键,具有主键的表中的每一行在其主键列中必须具有唯一的值组合。

QSqlRelationalTableModel设置外键关联表:

//设置当前表的关联表
void QSqlRelationalTableModel::setRelation(int column,const QSqlRelation &relation);

QSqlReltion::QSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn)

------------------------------------------------
tableModel->setRelation(外键的列号, QSqlRelation(关联_表名, 关联外键_字段名, 替换_字段(关联表)));

Qt中还提供了一个QSqlRelationalDelegate委托类,这个委托为一个外键提供了一个QComboBox部件来显示所有可选的数据。

ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));