当前位置:网站首页>Database usage in QT
Database usage in QT
2022-06-30 12:48:00 【AlbertOS】
introduce
Qt To use the database in the project, we need to declare in the project file that SQL modular , then Qt The project will be connected to SQL Some header files of the module
stay . p r o .pro .pro Add code to file QT += sql
Whole . p r o .pro .pro The file will be in the following state , In the future, you may have some external connection libraries or add some Qt The internal modules and so on are all introduced here :

Qtsql The modules consist of different Qt Class support , Classes can be divided into three levels : Driver layer 、sql The interface layer 、 User level
| level | describe |
|---|---|
| Driver layer | The specific database and sql The underlying bridging of interfaces , The supported classes included are Q S q l D r i v e r 、 Q S q l D r i v e r C r e a t o r < T > 、 Q S q l D r i v e r C r e a t o r B a s e 、 Q S q l D r i v e r P l u g i n and Q S q l R e s u l t etc. QSqlDriver、QSqlDriverCreator<T>、QSqlDriverCreatorBase、QSqlDriverPlugin and QSqlResult etc. QSqlDriver、QSqlDriverCreator<T>、QSqlDriverCreatorBase、QSqlDriverPlugin and QSqlResult etc. |
| SQL The interface layer | Provides access to the database , among QSqlDatabase Class is used to create connections ,QSqlQuery Class can use SQL Statement to realize the interaction with the database |
| User interface layer | The data in the database is linked to the widget ( Using the model / View framework implementation ) |
Different database drivers
Qt Sql The module uses database driver plug-ins to communicate with different database interfaces ,Qt Some driver versions supported by default :
| Driver name | Database version |
|---|---|
| QSQLITE2 | SQLite2 edition |
| QSQLITE | SQLite3 edition |
| QMYSQL | Mysql |
| QODBC | sql service |
| QPSQL | PostgreSQL(>=7.3 edition ) |
Qt Provided SQLite database
Different database drivers are used to connect to different databases , and Qt Provides an in-process database SQLite, It's small and flexible , There is no need for additional installation and configuration, and most of them are supported ANSI SQL92 Standards for SQL sentence , Is a lightweight database
The main advantages :
- SQLite Is designed to achieve embedded SQL Database engine , Based on pure C The language code , The running speed is very high
- SQLite When you need persistent storage, you can directly read and write the data of the hard disk , You can also put the entire database into memory when you do not need persistent storage , Neither approach requires additional server processes (SQLite There is no need for a stand-alone database engine , It is equivalent to that you open Qt The application opens the database )
- Open source , The whole set of codes is less than 3 Line ten thousand , There are good notes and 90% The above test coverage ( It is widely used. Don't worry that it will collapse and no one will repair it )
- Less than 250KB Memory footprint of (gcc compile )
- Support views 、 Triggers and transactions , Support nested SQL function
- Provide virtual machines for processing SQL sentence
- No configuration required , No installation required 、 There's no need for an administrator
- Support most ANSI SQL92 Standard statements
- Most applications are faster than the common databases in front of them
- The programming interface is simple
Next, let's look at how to write code , For my convenience, I will go directly to main Function to handle the database connection
( Generally, you can write a separate class to manage database operations )
#include <QCoreApplication>
#include <QTextCodec>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QTime>
#include <QSqlError>
#include <QtDebug>
#include <QSqlDriver>
#include <QSqlRecord>
int main(int argc,char * argv[])
{
QCoreApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());// Set Chinese display
QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE");// With “QSQLITE” For database type , Create a in the process address space SQLite database .
db.setHostName("easybook-3313b0"); // Set the database host name
db.setDatabaseName("qtDB.db"); // The database created above is based on “qtDB.db” Name the database . It is SQLite The only name available when creating an in memory database .
db.setUserName("wang"); // Set the database user name
db.setPassword("123456"); // Set database password
db.open(); // Open the connection
// establish QSqlQuery object .
//QtSql Module QSqlQuery Class provides an implementation SQL Statement interface , And you can traverse the returned result set of the execution .
// except QSqlQuery Out of class ,Qt Three high-level classes for accessing databases are also provided ,
// namely QSqlQueryModel、QSqlTableModel and QSqlRelationTableModel.
// They do not need to be used SQL Statement to perform database operations , And you can easily show the results in a table
QSqlQuery query;
// Create database tables
bool success=query.exec("create table automobile
(id int primary key,
attribute varchar,
type varchar,
kind varchar,
nation int,
carnumber int,
elevaltor int,
distance int,
oil int,
temperature int)"); // Create database tables “automobil”, The watch has 10 A field . In execution exec() After function call , You can manipulate the returned results .
if(success)
qDebug()<<QObject::tr(" Database table created successfully !\n");
else
qDebug()<<QObject::tr(" Database table creation failed !\n");
// Inquire about
query.exec("select * from automobil");
QSqlRecord rec = query.record();
qDebug() << QObject::tr("automobil Number of table fields :" )<< rec.count();
// insert record
QTime t;
t.start(); // Start a timer , The statistics operation takes
query.prepare("insert into automobil values(?,?,?,?,?,?,?,?,?,?)"); // If you want to insert multiple records , Or avoid converting values to strings ( That is, escape correctly ), You can call... First prepare() The function specifies a that contains placeholders query, Then bind the value to be inserted .Qt Support for all databases Qracle Placeholders for types and ODBC Placeholder for type . Here we use ODBC Position placeholder for type
long records=100; // Insert any... Into the table 100 Bar record
for(int i=0;i<records;i++)
{
query.bindValue(0,i); // call bindValue() or addBindValue() Function binding the value to insert .
query.bindValue(1," Four rounds ");
query.bindValue(2," Sedan ");
query.bindValue(3," fukang ");
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);
success=query.exec(); // call exec() Function in query Insert the corresponding value in , after , Can continue to call bindValue() or addBindValue() Function binding new value , Then call... Again exec() Function in query Insert new value in .
if(!success)
{
QSqlError lastError=query.lastError();
qDebug()<<lastError.driverText()<<QString(QObject::tr(" Insert the failure "));
}
}
qDebug()<<QObject::tr(" Insert %1 Bar record , Time consuming :%2 ms").arg(records). arg(t.elapsed()); // Insert any... Into the table 100 Bar record , The time consumed by the output operation after the operation is successful .
// Sort
t.restart(); // Restart the timer
success=query.exec("select * from automobil order by id desc");
// Press id The descending order of the fields will query the 100 Sort records .
if(success)
qDebug()<<QObject::tr(" Sort %1 Bar record , Time consuming :%2 ms").arg(records).arg(t. elapsed()); // The output operation takes time
else
qDebug()<<QObject::tr(" Sorting failed !");
// Update record
t.restart(); // Restart the timer
for(int i=0;i<records;i++)
{
query.clear();
query.prepare(QString("update automobil set attribute=?,type=?,"
"kind=?,nation=?,"
"carnumber=?,elevaltor=?,"
"distance=?,oil=?,"
"temperature=? where id=%1").arg(i));
// The update operation is similar to the insert operation , Just using SQL The statements are different .
query.bindValue(0," Four rounds ");
query.bindValue(1," Sedan ");
query.bindValue(2," fukang ");
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);
success=query.exec();
if(!success)
{
QSqlError lastError=query.lastError();
qDebug()<<lastError.driverText()<<QString(QObject::tr(" Update failed "));
}
}
qDebug()<<QObject::tr(" to update %1 Bar record , Time consuming :%2 ms").arg(records).arg(t.elapsed());
// Delete
t.restart(); // Restart the timer
query.exec("delete from automobil where id=15"); // Execution deletion id by 15 Recorded operations .
// The output operation takes time
qDebug()<<QObject::tr(" Delete a record , Time consuming :%1 ms").arg(t.elapsed());
return 0;
//return a.exec();
}
Establish a connection to the database
Connect QSQLite database
The above code is the entire operation , Let's talk about the connection methods of different databases , Before doing database operations , Let's first establish a connection to the database 
Use SQLite When the driver connects to the database, it actually opens up a separate space in the process to store the database (), If you do not call the write function , The database will be placed in memory and will not interact with the hard disk data files for the time being
Connect Mysql database
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");// Add name QMYSQL Drive connection for
db.setHostName("127.0.0.1");
db.setDatabaseName("book");
db.setUserName("root");
db.setPassword("123456");
if(!db.open())// Security issues , If the connection is not successful, the connection failure will be printed
{
qDebug() << " Connect mysql Failure " << db.lastError().text();
}
// Let's create two named links to see the difference
QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL", "first");
QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL", "second");
After you create a connection, you can use it anywhere QSqlDatabase::database() The static function obtains the pointer to the database connection through the connection name , If the function is called without specifying the connection name, the default connection will be returned
QSqlDatabase defaultDB = QSqlDatabase::database();
QSqlDatabase firstDB = QSqlDatabase::database("first");
QSqlDatabase secondDB = QSqlDatabase::database("second");
To remove a database connection , You need to use it first QSqlDatabase::close() Close the database , Then use static functions QSqlDatabase::removeDatabase() Remove connection
perform sql sentence
Query data

QSqlQuery Class is one of the interface classes we use to operate the database , I have written the partial usage of this class interface function .
When you're done with query.exec("select * from student"); After the inquiry , Its internal pointer will point to the position before the return result .
We need to call QSqlQuery::next() To complete the traversal , The following is the way to traverse printing , We use it qDebug Print the results to the console :
while(query.next())
{
qDebug() << query.value(0).toInt() << query.value(1).toString();
}
stay QSqlQuery There are also many functions in the class to locate in the result set :
- next() Go to the next record
- previous() Go to the previous record
- first() Go to the first record
- last() Go to the last record
- seek(n) Locate to the first n Bar record
- The index of the current row can be accessed through at() return
- record() Function returns the current record
insert data
Insert a record :
query.exec("insert into student (id, name) values (1, 'albert')");
Inserting multiple records at the same time can be done using placeholders
- Name binding placeholder
query.prepare("insert into student (id, name) values (:id, :name)");
int idValue = 1;
QString nameValue = "albert";
query.bindValue(":id", idValue);
query.bindValue(":name", nameValue);
query.exec();
After occupying space id and idValue This variable is bound to 、name and nameValue This variable is bound to , adopt for Loop assignment exec You can insert multiple records
call QSqlQuery::prepare() once , Then use it many times bindValue() perhaps addBindValue() Function to bind the required data , Last call once exec() Function is OK .
I use the input stream expression here :
query.prepare("insert into student (id, name) values (?, ?)");
QVariantList ids;
ids << 1 << 2 << 3;
query.addBindValue(ids);
QVariantList names;
names << "albert" << "su" << "OS";
query.addBindValue(names);
if(!query.execBatch())
qDebug() << query.lastError();
Transaction processing
If the underlying database driver supports transactions ,QSqlDriver::hasFeature(QSqlDriver::Transactions) Returns the true. have access to QSqlDatabase::transaction() To start a transaction , Then write what you want to do in the transaction SQL sentence , Last call QSqlDatabase::commit() Submit or QSqlDatabase::rollback() Roll back . To use a transaction, you must start the transaction before creating the query
QSqlDatabase::database().transaction();// Start a transaction
QSqlQuery query;// Create a new operation object
query.exec("SELECT id FROM student WHERE name = 'albert'");
if (query.next())
{
int id = query.value(0).toInt();
query.exec("INSERT INTO project (id, name, ownerid) "
"VALUES (201, 'MProject', "
+ QString::number(id) + ')');
}
QSqlDatabase::database().commit();// Commit transaction
Qt Provided sql Model class
If you have learned other languages sql Connect , I know that some languages provide more advanced user interface classes , So that you can build in the language framework sql Model .
Especially the latest popular MVC frame , Put the model directly into the framework class , There is no need to maintain the database separately ,Qt This more advanced user interface is also provided .
Qt Provides 3 A higher-level class to access the database , Namely
QSqlQueryModel、QSqlTableModel and QSqlRelationalTableModel.
this 3 All classes are from QAbstractTableModel Derived from , It can be easily realized that the data in the database can be stored in QListView and QTableView And so on . Another benefit of using these classes is , This makes the code easy to adapt to other data sources . for example , If you start using QSqlTableModel, Later, it will be used instead XML File to store data , All you need to do is change a data model
QSqlQueryModel Model
QSqlQueryModel Provides a SQL Read only model of the query
QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select * from student");
model->setHeaderData(0, Qt::Horizontal, tr(" Student number "));
model->setHeaderData(1, Qt::Horizontal, tr(" full name "));
model->setHeaderData(2, Qt::Horizontal, tr(" Course "));
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
QSqlTableModel Model
QSqlTableModel It provides that only one... Can be operated at a time SQL Reading and writing model of tables , It is QSqlQuery A higher level substitute for , It can be browsed and modified independently SQL surface , And write very little code , And you don't need to know SQL grammar .
QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("student");
model->select();
// Set editing policy
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
QSqlRelationalTableModel Model
QSqlRelationalTableModel Inherited from QSqlTableModel, And extended it , Provides support for external keys .
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this);
model->setTable("student");
model->setRelation(2, QSqlRelation("course", "id", "name"));
model->select();
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
边栏推荐
- 图解使用Navicat for MySQL创建存储过程
- 视频按每100帧存一个文件夹,处理完再图片转视频
- 【目标跟踪】|pytracking 配置 win 编译prroi_pool.pyd
- Mysql中 begin..end使用遇到的坑
- Redis cache problem
- Charles break point modify request data & response data
- Redis的配置文件及新数据类型
- Sarsa notes
- 【MySQL】MySQL的安装与配置
- Lichuang EDA learning notes 10 common connector component identification and passive buzzer driving circuit
猜你喜欢

Why should offline stores do new retail?

Linux系统Redis的安装

Instructions for legend use in SuperMap iclient3d 11i for cesium 3D scene

"Xiaodeng" user personal data management in operation and maintenance

Qt读写Excel--QXlsx工作表显示/隐藏状态设置4

Some commonly used hardware information of the server (constantly updated)

【 surprise】 la vitesse de téléchargement de Thunderbolt n'est pas aussi rapide que celle de la machine virtuelle

Google refutes rumors and gives up tensorflow. It's still alive!

NoSQL - redis configuration and optimization

Shell编程概述
随机推荐
dataworks 同步maxcomputer 到sqlserver ,汉字变乱码了,请问怎么解决
Questionnaire star questionnaire packet capturing analysis
Redis - problèmes de cache
电机控制Clarke(α/β)等幅值变换推导
Visual studio configures QT and implements project packaging through NSIS
【惊了】迅雷下载速度竟然比不上虚拟机中的下载速度
Android development interview real question advanced version (with answer analysis)
JMeter's performance test process and performance test focus
How to select an OLAP database engine?
黑马笔记---集合(Collection的常用方法与遍历方式)
Idea has a new artifact, a set of code to adapt to multiple terminals!
The format of RTSP address of each manufacturer is as follows:
Qt中的事件处理
90. (cesium chapter) cesium high level listening events
FlinkSQL自定义UDATF实现TopN
【一天学awk】运算符
Inner join and outer join of MySQL tables
Vision based robot grasping: from object localization, object pose estimation to parallel gripper grasping estimation
MySQL判断执行条件为NULL时,返回0,出错问题解决 Incorrect parameter count in the call to native function ‘ISNULL‘,
Unity脚本的基础语法(4)-访问其他游戏对象