Qt连接Mysql

1、sql框架

sql类分为三层

  1. 驱动层

    包括QSqlDriver , QSqlDriverCreator , QSqlDriverCreatorBase , QSqlDriverPlugin ,和 QSqlResult.

    这一层提供了特定数据库和SQL API层之间的底层桥梁。

  2. SQL API 层

    提供了对数据库访问的功能, 连接使用 QSqlDatabase,数据库交互通过 QSqlQuery 实现。除了这两个类,这一层还支持 QSqlError , QSqlField , QSqlIndex ,和 QSqlRecord .

  3. 用户界面层

    将数据从数据库链接到用户界面上的widget。包括 QSqlQueryModel , QSqlTableModel ,和 QSqlRelationalTableModel 。这些类用于支持Qt的MVC框架。

2、数据库连接

通常开发不会设计到驱动层的修改,主要是使用API 和 界面层

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");		//指定Mysql驱动
    db.setHostName("127.0.0.1");							//主机名
    db.setPort(3306);										//端口号 可不加默认为3306
    db.setDatabaseName("mydb");								//数据库名
    db.setUserName("root");									//用户名
    db.setPassword("200291");								//用户密码
	bool ok = db.open();									//开启数据库

如果指定报了QSqlDatabase: QMYSQL driver not loaded错说明qt模块下没有mysql的动态链接库。可以产看qt缺少mysql驱动
解决。

如果想建立多个连接可以给QSqlDatabase::addDatabase()传递第二个参数获得命名连接,例如:

	QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL", "firstName");
	QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL", "secondName");

在建立连接后可以调用静态函数QSqlDatabase::database()来获取连接名,如果不传递任何参数,将会返回默认值。

 	QSqlDatabase defaultDB = QSqlDatabase::database();
    QSqlDatabase firstDB = QSqlDatabase::database("firstName");
    QSqlDatabase secondDB = QSqlDatabase::database("secondName");

删除数据库信息可以,先调用QSqlDatabase::close()关闭数据库连接,然后调用静态函数QSqlDatabase::removeDatabase()

	/* 删除默认数据库*/
	defaultDb.close();
	QSqlDatabase::removeDatabase();

	/* 删除命名数据库*/
	firstDB.close();
	QSqlDatabase()::removeDatabase(firstName);

3、执行Sql语句

查询语句需要引入QSqlQuery。exec()不仅可以使用DML(数据操纵语言,例如 insert, delete, updata, select),还可以使用DDL(数据定义语言,例如create table, 更改字段)。

查询结构

    QSqlQuery squery;
    if(!squery.exec("select * from user"))
        qDebug() << "query failed!";

    while(squery.next()) {
        QString value = squery.value(1).toString();
        qDebug() << value;
    }
  • exec()可以传入一个字符串,CRUD的任何一种。如果查询失败会返回false.
  • 查询成功后,查询到的数据以条为单元存储在QSqlQuery内,QSqlQuery的内部指针位于第一个记录之前的位置,所以要调用一次next()才可以读取数据。
  • value()有两个重载分别是value(int)value(const QString&)第一个重载传入的参数是该字段在数据库中是第几个字段,第二个重载传入的是数据库中字段的名。
  • 不同的数据库字段类型会自动映射到最接近的Qt等价类型中。这个为qt推荐类型的表 table .

获取读取数据的大小

​ 如果选用的数据库驱动支持QSqlDriver::QuserySize可以直接调用QSqlQuery::size()否则可使用QSqlQusery::last()跳转到最后一条语句,然后使用QSqlQuery::at()(当前是第几条记录,从0开始)。QMYSQL是支持的。

    if(db.driver()->hasFeature(QSqlDriver::QuerySize))
        qDebug() << squery.size();
    else {
        squery.last();
        qDebug() << squery.at() + 1;
    }

如果想获得所在记录有多少个字段可以使用record()获得一个QSqlRecord对象然后调用count()获取目前记录有几个字段。

	#include<QSqlRecord>
	qDebug() << squery.record().count();

PS:如果所有记录只调用next()就可以,可以QSqlQuery::setForwardOnly(true),这样会导致一些向前访问的函数无法使用,但是可以减少迭代器的开销,对于数据量比较大的结果,会有明显的优化。

	squery.setForwardOnly(true);

占位符使用

如果要执行多条结构相同的sql指令,使用占位符可以避免大量的字符串拼接操作。占位符由两种形式。

  1. 命名占位符

        QSqlQuery query;
        query.prepare("INSERT INTO employee (id, name, salary) "
                      "VALUES (:id, :name, :salary)");
        query.bindValue(":id", 1001);
        query.bindValue(":name", "Thad Beaumont");
        query.bindValue(":salary", 65000);
        query.exec();
    
  2. 匿名占位符

        QSqlQuery query;
        query.prepare("INSERT INTO employee (id, name, salary) "
                      "VALUES (?, ?, ?)");
        query.addBindValue(1001);
        query.addBindValue("Thad Beaumont");
        query.addBindValue(65000);
        query.exec();
    

    对于执行多个exec(),prepare()只需要设置一次。

事务

如果使用的数据库引擎支持事务,可以调用QSqlDatabase::transaction()来开启事务。可以使用QSqlDriver::hasFeature(QSqlDriver::Transactions)来检查使用的数据库是否支持。事务必须在查询语句使用之前开启。

    QSqlDatabase::database().transaction();
    QSqlQuery query;
    query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");
    if (query.next()) {
        int employeeId = query.value(0).toInt();
        query.exec("INSERT INTO project (id, name, ownerid) "
                   "VALUES (201, 'Manhattan Project', "
                   + QString::number(employeeId) + ')');
    }
    QSqlDatabase::database().commit();

4、Sql模型类

除了QSqlQuery,Qt还封装了更高层次的模型类来访问数据库。主要的有三个QSqlQueryModelQSqlTableModelQSqlRelationTableModel。这些类可以通过View类来展示数据。例如QListViewQTableView

QSqlQueryModel

    QSqlQueryModel model;
    model.setQuery("SELECT * FROM employee");
    for (int i = 0; i < model.rowCount(); ++i) {
        int id = model.record(i).value("id").toInt();
        QString name = model.record(i).value("name").toString();
        qDebug() << id << name;
    }

​ 在数据库连接建立的情况下,使用QSqlQuery::setQuery()来进行数据库的查询,调用 record()函数来分别处理每一条数据。

QSqlTableModel

  • 查询
    QSqlTableModel model;
    model.setTable("employee");
    model.setFilter("salary > 50000");
    model.setSort(2, Qt::DescendingOrder);
    model.select();
    for (int i = 0; i < model.rowCount(); ++i) {
        QString name = model.record(i).value("name").toString();
        int salary = model.record(i).value("salary").toInt();
        qDebug() << name << salary;
    }

QSqlTableModel进一步封装了对于数据库的查询,使用setTable()来指定需要查询的数据表,该类只支持单表查询。setFilter()可以设置查询条件。setSort()指定查询结果的排序,传入的一个int参数可以指定按照数据表的第几个字段进行排序,第二个参数指定排序方式。所有的设置必须在select()函数之前才可以生效。

  • 修改
    for (int i = 0; i < model.rowCount(); ++i) {
        QSqlRecord record = model.record(i);
        double salary = record.value("salary").toInt();
        salary *= 1.1;
        record.setValue("salary", salary);
        model.setRecord(i, record);
    }
    model.submitAll();

调用setValue()可以修改数据条里的数据,setRecord()可以修改数据表里的数据。调用submitAll()可以保存所有的修改。同时也可以调用 model.setData(model.index(row, column), value)来指定修改的那一条记录。

  • 插入
    model.insertRows(row, 1);
    model.setData(model.index(row, 0), 1013);
    model.setData(model.index(row, 1), "Peter Gordon");
    model.setData(model.index(row, 2), 68500);
    model.submitAll();

用法和修改类似。

  • 删除
    model.removeRows(row, 5);
    model.submitAll();

QSqlRelationTableModel

该类支持把当前表的外键转换成外键表的其他字段

    model->setTable("employee");
    model->setRelation(2, QSqlRelation("city", "id", "name"));
    model->setRelation(3, QSqlRelation("country", "id", "name"));

其他用法和QSqlTableModel类似。

submit的策略

可以调用QSqlTableModel:: setEditStrategy来修改model提交数据的策略。

常量描述
QSqlTableModel::OnFieldChange0对模型的所有更改都将立即应用于数据库
QSqlTableModel::OnRowChange1当用户选择不同的行时,将应用对行的更改。
QSqlTableModel::OnManualSubmit2所有的更改都将缓存在模型中,直到 submitAll () 或 revertAll () 被调用。

5、在视图中展示数据

给view的widget设置model就可以在试图中显示数据。

    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

对于可以读写的model,如果不希望用户修改数据可以调用setEditTriggers()来禁止用户修改数据

 view->setEditTriggers(QAbstractItemView::NoEditTriggers);

对于查询出来的数据可以使用setHeadrData()来重命名字段名。

    model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("City"));
    model->setHeaderData(3, Qt::Horizontal, QObject::tr("Country"));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值