登录
转载

QtSql简单的用法

发布于 2021-04-13 阅读 323
  • 数据库
  • SQL
转载

目录

QtSql模块层次结构

QtSql模块提供的数据库驱动插件

QtSql提供的高层接口

小例子

1、创建数据库连接和表

2、插入数据

3、查找数据

4、更新数据

5、删除数据

6、主函数

7、*.pro


QtSql模块层次结构

 

层次结构图
层次描述
驱动层实现了特定数据库与SQL接口的底层桥接,包括的支持类有QSqlDriver、QSqlDriverCreator<T>、QSqlDriverCreatorBase、QSqlDriverPlugin和QSqlResult
数据库接口层QSqlDatabase类提供了数据库访问类、数据库连接操作,QSqlQuery类提供了与数据库的交互操作,其他支持类还包括QSqlError、QSqlField、QSqlTableModel和QSqlRecord
用户结构层提供从数据库数据到用于数据表示的窗体的映射,包括的支持类有QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel,这些类均依据Qt的模型/视图结构设计

QtSql模块提供的数据库驱动插件

QtSql模块提供的不同数据库驱动插件

驱    动

数据库管理系统

QDB2

IBM DB2及其以上版本

QIBASE

Borland InterBase

QMYSQL

MySQL

QOCI

Oracle Call Interface Driver

QODBC

Open Database Connectivity(ODBC)包括微软SQL Server和其他ODBC兼容数据库

QPSQL

PostgreSQL版本6.x和7.x

QSQLITE

SQLite版本3及其以上版本

QSQLITE2

SQLite版本2

QTDS

Sybase Adaptive Server

QtSql提供的高层接口

高层接口

类    名

用    途

QSqlQueryModel

基于任意SQL语句的只读模型

QsqlTableModel

基于单个表的读写模型

QSqlRelationalTableModel

QSqlTableModel的子类,增加了外键支持

小例子

1、创建数据库连接和表

 void CreateSqlTable(QSqlDatabase& db, QSqlQuery& query)
{
    //该数据库只在程序运行期间有效,等程序运行结束时就会将其销毁
    db.setDatabaseName(":memory:");
    //db.setHostName("LM123456");                 //设置数据库主机名
    db.setDatabaseName("qtDB.db");              //设置数据库名
    db.setUserName("LiuXiaoMing");              //设置数据库用户名
    db.setPassword("123456");                   //设置数据库密码
    db.open();                             		//打开连接
    qDebug()<< db.isValid();//true
    qDebug()<< db.isOpen(); //true

    //创建数据库表
    //id:变量名;int:类型;primary key:主键
    bool success=query.exec("create table automobil(id int primary key,attribute varchar"
                            ",type varchar,kind varchar,nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
    if(success)
        qDebug()<<QObject::tr("数据库表创建成功!\n");
    else
        qDebug()<<QObject::tr("数据库表创建失败!\n");
}

2、插入数据

void InsertInto(QSqlQuery& query)
{
    QTime t;
    t.start();
    //调用prepare()函数指定一个包含占位符的query,然后绑定要插入的值
    query.clear();
    query.prepare("insert into automobil values(?,?,?,?,?,?,?,?,?,?)");

    long records = 10;
    for(int i  =0;i < records; ++i)
    {
        query.bindValue(0,i);//调用bindValue()或addBindValue()函数绑定要插入的值
        query.bindValue(1,"四轮");
        query.bindValue(2,"轿车");
        query.bindValue(3,"富康");
        query.bindValue(4,rand()%100);
        query.bindValue(5,rand()%10000);
        query.bindValue(6,rand()%300);
        query.bindValue(7,rand()%200000);
        query.bindValue(8,rand()%52);
        query.bindValue(9,rand()%100);
        //query.addBindValue(id); 插值单个值

        bool success=query.exec();
        if(!success)
        {
            QSqlError lastError=query.lastError();  //返回语句执行错误原因
            qDebug()<< i << "    "<<lastError.driverText()<<QString(QObject::tr("插入失败"));
        }
    }
    qDebug()<<QObject::tr("插入 %1 条记录,耗时:%2 ms").arg(records).arg(t.elapsed());
#if 0
    //批处理操作
    query.prepare("insert into student values (:id, :name)");
    QVariantList ints;
    ints << 10 << 11 << 12 << 13;
    query.addBindValue(ints);   //插值一列
    QVariantList names;
    // 最后一个是空字符串,应与前面的格式相同
     names << "xiaoming" << "xiaoliang"
                    << "xiaogang" << QVariant(QVariant::String);
    query.addBindValue(names);
    if (!query.execBatch()) //进行批处理,如果出错就输出错误
       qDebug() << query.lastError();
#endif
}

3、查找数据

void SelectData(QSqlQuery& query)
{
/*
    seek(int n) :query指向结果集的第n条记录;
    first() :query指向结果集的第一条记录;
    last() :query指向结果集的最后一条记录;
    next() :query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录;
    previous() :query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录;
    record() :获得现在指向的记录;
    value(int n) :获得属性的值。其中n表示你查询的第n个属性。 获取第几列数据。
    at() :获得现在query指向的记录在结果集中的编号。

   刚执行完query.exec("select *from student");这行代码时,
    query是指向结果集以外的,我们可以利用query.next()使得 query指向结果集的第一条记录。
    当然我们也可以利用seek(0)函数或者first()函数使query指向结果集的第一条记录。
    但是为了节省内存开销,推荐的方法是,在query.exec("select * from student");
    这行代码前加上query.setForwardOnly(true);这条代码,此后只能使用next()和seek()函数。
*/
    query.exec("select * from automobil");  //执行标准Sql语句
    qDebug() << "exec next() :";
    //开始就先执行一次next()函数,那么query指向结果集的第一条记录
    if(query.next())
    {
       //获取query所指向的记录在结果集中的编号
       int rowNum = query.at();
       //获取每条记录中属性(即列)的个数
       int columnNum = query.record().count();
       //获取"name"属性所在列的编号,列从左向右编号,最左边的编号为0
       int fieldNo = query.record().indexOf("id");
       //获取id属性的值,并转换为int型
       int id = query.value(0).toInt();
       //获取name属性的值
       QString name = query.value(fieldNo).toString();
       //将结果输出
       qDebug() << "rowNum is : " << rowNum
                 << " id is : " << id
                 << " name is : " << name
                 << " columnNum is : " << columnNum;
    }
    //定位到结果集中编号为2的记录,即第三条记录,因为第一条记录的编号为0
    qDebug() << "exec seek(2) :";
    if(query.seek(2))
    {
       qDebug() << "rowNum is : " << query.at()
                 << " id is : " << query.value(0).toInt()
                 << " name is : " << query.value(1).toString();
    }
    //定位到结果集中最后一条记录
    qDebug() << "exec last() :";
    if(query.last())
    {
       qDebug() << "rowNum is : " << query.at()
                 << " id is : " << query.value(0).toInt()
                 << " name is : " << query.value(1).toString();
    }

}

4、更新数据

void Update(QSqlQuery& query)
{
    QTime t;
    //更新记录
    t.restart();
    for(int i = 0;i < 10; ++i)
    {
       query.clear();
       query.prepare(QString("update automobil set attribute=?,type=?,"
                             "kind=?,nation=?,"
                             "carnumber=?,elevaltor=?,"
                             "distance=?,oil=?,"
                             "temperature=? where id=%1").arg(i)); // i 对应 %1

       query.bindValue(0,"双轮");
       query.bindValue(1,"摩托");
       query.bindValue(2,"大江");
       query.bindValue(3,rand()%100);
       query.bindValue(4,rand()%10000);
       query.bindValue(5,rand()%300);
       query.bindValue(6,rand()%200000);
       query.bindValue(7,rand()%52);
       query.bindValue(8,rand()%100);

       bool success=query.exec();
       if(!success)
       {
           QSqlError lastError=query.lastError();
           qDebug()<< i << " "<<lastError.driverText()<<QString(QObject::tr("更新失败"));
       }
    }
    qDebug()<<QObject::tr("更新 %1 条记录,耗时:%2 ms").arg(10).arg(t.elapsed());
}

5、删除数据

void Delete(QSqlQuery& query)
{
    QTime t;
    //删除
    t.restart();
    query.exec("delete from automobil where id=15"); //执行删除id为15的记录的操作
    qDebug()<<QObject::tr("删除一条记录,耗时:%1 ms").arg(t.elapsed());
}

6、主函数

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
    QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE");

    QSqlQuery query;
    CreateSqlTable(db,query);
    InsertInto(query);
    SelectData(query);
    Update(query);
    Delete(query);

    system("pause");
    return 0;
    //return a.exec();
}

7、*.pro


QT += core
QT -= gui
QT += sql
CONFIG += c++11

TARGET = QSQLiteEx
CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 

评论区

零00
7粉丝

时光荏苒,我自清欢

0

0

0

举报