Qt development summary (28) - Database

 

This sum up the Qt database operations. This article may involve a number of database statements, I do not do too much to explain here, if you have less knowledge database, you can also probably understand, it is not, I had to go to the next tutorial SQL knowledge, at least to learn about SQL statements.

Outline

Qt provides QtSql module to provide platform-independent SQL-based database operations. Here we call "platform independent", both operating system platforms, and includes various database platforms. Qt database operations can also easily integrate with model / view architecture. Generally speaking, we operate on the database that the operation of the database table more, and this is a long term model / view architecture.

To enable Qt SQL in the project, please add this directive to the C ++ file:

  #include <QtSql>

To link to Qt SQL module, add this line to the project file:

  QT + = SQL

Database related classes are:

The class name

description

QSqlDatabase

It represents a database link

QSqlDriverCreator

Provide a specific driver type of SQL template class driver factory

QSqlDriverCreatorBase

QSqlDriverCreator base class

QSqlDriver

For accessing specific SQL abstract base class database

QSqlError

SQL Database Error Messages

QSqlField

Processing SQL database tables and views in the field

QSqlIndex

Manipulation and function description database index

QSqlQuery

Execution and manipulate SQL statements method

QSqlRecord

Package record database

QSqlResult

For the specific SQL abstract interface to access database data

QSql

Contained in the entire Qt SQL other identifiers used by the module

QSqlQueryModel

SQL read-only data sets of model results

QSqlRelationalTableModel

A single database table with the foreign key data model supported editable

QSqlTableModel

A single database table data model editable

From the above table it can be summarized Qt SQL database support three levels of functionality:

Driver layer:

QSqlDriver, QSqlDriverCreator, QSqlDriverCreatorBase, QSqlDriverPlugin, QSqlResult. This level provides a low-level bridge between specific databases and SQL API.

SQL API layer:

QSqlDatabase, QSqlQuery, QSqlError, QSqlField, QSqlIndex, QSqlRecord. This layer provides access to this database.

User interface layer:

QSqlQueryModel, QSqlTableModel, QSqlRelationalTableModel. This level of the data from the database is displayed on the widget, to fit model / view use frame Qt.

Database driver support

Qt SQL driver plug-in module (plugins) API to communicate with different databases. Since the independent Qt SQL API module and the database, all database-specific code included in these drivers. Qt itself provides several drivers, another user can add other custom drivers. For this reason, Qt provides the driver source code, can be used as a model to write their own drivers.

Qt itself already supported database drivers are:

drive

database

QDB2

IBM DB2 (version 7.1 and above)

QIBASE

Borland InterBase

QMYSQL

MySQL

QOCI

Oracle Call Interface Driver

QODBC

Open Database Connectivity (ODBC) - Microsoft SQL Server and other ODBC-compliant databases

QPSQL

PostgreSQL (versions 7.3 and above)

QSQLITE2

SQLite version 2

QSQLITE

SQLite version 3

QTDS

Sybase Adaptive Server; Note: After Qt 4.7 it is not supported from

Users can also compile their own database-driven needs. Worked in Qt4 age, I used Qt4.6 own compiled MySQL drivers (Qt5.9 already supports MySQL the default). The process is similar to compile, we can venue to visit my other blog post: Compile MySQLQt4 drive .

The core idea is to open the driver source code, execute qmake and nmake:

cd %QTDIR%\qtbase\src\plugins\sqldrivers

qmake -- MYSQL_INCDIR=C:/MySQL/include "MYSQL_LIBDIR=C:/MYSQL/MySQL Server <version>/lib/opt"

nmake sub-mysql

For Oracle Database OCI, Qt5 also need to compile its own drive. Qt OCI plugin supports Oracle 9i, 10g and later. Construction of OCI plug-in on Windows to first select Oracle Client Installer in the "Programmer" option from the Oracle Client Installation CD in. For some versions of Oracle Client, you may also need to select "Call Interface (OCI)" option (if any).

cd %QTDIR%\qtbase\src\plugins\sqldrivers

qmake -- OCI_INCDIR=c:/oracle/oci/include OCI_LIBDIR=c:/oracle/oci/lib/msvc

nmake sub-oci

If you do not use the Microsoft compiler, please replace nmake in the line above is mingw32-make.

If you are not sure of what drives support Qt, you can () to find the name list of all of the available database-driven with QSqlDatabase :: drivers.

Database operations

Qt will be specific to the operation of MySQL database operations, for example summary Qt.

Connect to the database

QSqlDatabase responsible for loading and managing database driver plug-ins. After adding a database (see QSqlDatabase :: addDatabase ()), will load the appropriate driver plug-in (using QSqlDriverPlugin). QSqlDatabase rely on the driver plug-in provides an interface to QSqlDriver and QSqlResult. So, first you need to add the database engine:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
//其次就是设置数据库的地址、用户、密码等信息连接它:
db.setHostName("127.0.0.1");   //数据库服务器ip
db.setUserName("root");        //数据库用户名
db.setPassword("123456");      //密码
db.setDatabaseName("info");    //使用哪个数据库
//打开数据库
if(!db.open())
{
    QMessageBox::warning(this, "错误", db.lastError().text());
    return;
}

 

CRUD

A typical operation of the database has CRUD. QSqlQuery class can support almost all of the database statement. We can also use QSqlQuery :: isActive () function to check the implementation of the statement is correct or not. If QSqlQuery object is active, the function returns true. The so-called "active", meaning that the object is successfully executed exec () function, but is not yet complete. If you need to set to inactive, you can use finish () or clear () function, or simply relieved that QSqlQuery object.

QSqlQuery query(db);//绑定要访问的数据库
query.exec(" create table student(id int primary key auto_increment, name varchar(255), age int, score int);");

 

// insert single data

query.exec(" insert into student(id, name, age, score) values(1, 'mike', 18, 76);");

If we need to insert pieces of data, then you can use QSqlQuery :: exec () function to insert data one by one, but here we have chosen another method: the batch execution. First, we use QSqlQuery :: prepare () function to this article SQL statement placeholders pretreatment, indicating that in the future we can replace these locations with the actual data. Briefly explain, pretreatment is a feature provided by the database, it will be compiled SQL statements, performance and security better than an ordinary SQL processing. Then we call QSqlQuery :: execBatch () batch execution SQL, after the end of the object. In this way, the insert operation is complete.

//预处理语句:占位符: +自定义名字
query.prepare(" insert into student(name, age, score) values(:name, :age, :score);");
//给字段设置内容 list
QVariantList nameList,ageList, scoreList;
nameList << "小米" << "华为" << "三星";
ageList <<33 <<43 <<55;
scoreList << 59 << 69 << 100;
//给字段绑定(可以不按照顺序,有占位符: +自定义名字)
query.bindValue(":name",nameList);
query.bindValue(":age",ageList);
query.bindValue(":score",scoreList);
//执行预处理命令
query.execBatch();

 

Find data that is to execute the select statement in the SQL language:

query.exec("select * from student where name = '华为'");//从表中遍历name为华为的行
while(query.next())//一行一行遍历
{
    //取出当前行的内容,取得时候按列来取
    qDebug() << query.value(0).toInt()
            << query.value(1).toString()
            << query.value("age").toInt()
            << query.value("score").toInt();
}

 

Modify or update data call with an update statement:

query.exec("update student set score = 100 where name = '华为'");

To delete a delete statement:

query.exec("delete from student where name = '华为'");

Shut down the database:

db.close();

In short, the operation of the database is to execute SQL statements can be used exec. As SQL statements may differ from the database also some differences. When used to pay attention.

Operation of things

Some scenarios need to use things the database. Including: transaction (), commit () submitted, rollback () rollback. Note: Before operating the transaction, first determine whether the database supports the transaction operations. hasFeature class function is QSQLDriver

//插入一条记录,然后提交事务
if (QSqlDatabase::database().driver()->hasFeature(QSqlDriver::Transactions))
{
 ... 
} 
//
QSqlDatabase::database().transaction();  
QSqlQuery query;  
query.exec("SELECT * FROM T_STUDENT WHERE age=12");  
if (query.next())  
{  
    query.exec("INSERT INTO T_STUDENT (name,age,score) VALUES ('小李',13,99)");  
}  
if(!QSqlDatabase::database().commit())
{
    QMessageBox::critical(this,"Error","操作失败,将要回滚");
    if(!QSqlDatabase::database().rollback())
    {
        QMessageBox::critical(this,"Error","回滚失败");
    }
}  

Model / View application

Qt SQL user interface layer provides a very convenient use of several classes, these classes of data from the database linked to the data-aware widgets. They include QSqlQueryModel, QSqlTableModel and QSqlRelationalTableModel. These classes are intended for use with Qt model / view framework. About Qt model / view architecture, I've been in Model / View summary over the years.

This model-based process QSqlTableModel more advanced, if not familiar with SQL statements, and does not require a lot of complex queries, such QSqlTableModel basic model to meet the general needs. It is noteworthy that, QSqlTableModel does not necessarily have to be combined QListView or QTableView use, we can use it to make a general process.

Operation and connection to the database is still the same as described above, when the connection is successful, we can perform database operations through QSqlTableModel.

model->setTable ("student");//设定表名
model->setEditStrategy (QSqlTableModel::OnManualSubmit);//所有的操作都将被缓存,直到submitAll() or revertAll()被调用.
model->select ();//选取整个表的所有行
ui->tableView->setModel (model);

Table setTable use () function to set the required operation, () to select the entire table with select, setModel interfaces with the view to the entire table of the UI displayed in the table. If you want to query and display parts, just set filters on it:

model.setFilter("age > 20 and age < 25");

WHERE statement is needed parts. The above example, the operation code corresponding to the actual SQL statements

SELECT * FROM student WHERE age > 20 and age < 25

We can also traverse the data in the following way:

if (model.select()) 
{
for (int i = 0; i < model.rowCount(); ++i)
{
    	QSqlRecord record = model.record(i);
    	QString name = record.value("name").toString();
    	int age = record.value("age").toInt();
    	qDebug() << name << ": " << age;
    }
}

 

Use QSqlTableModel :: select () function to operate, which is executed queries. If the query is successful, the function returns true, which determine whether an error occurred. If no error, we use the Record () function fetches a row record, which is given in the form of QSqlRecord, and QSqlRecord :: value () is taken of the actual data values ​​in a column. Note that since QSqlTableModel const_iterator walker is not provided, the macro can not be used foreach traversal.

Also note that, due to the QSqlTableModel just a high-level operation, certainly not easy actual SQL statement. Specifically, we use only QSqlTableModel SELECT * query, where the data can not be queried only certain columns.

The following piece of code shows how to use the insertion operation QSqlTableModel:

QSqlTableModel model;
model.setTable("student");
int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 1), "Cheng");
model.setData(model.index(row, 2), 24);
model.setData(model.index(row, 3), 99);
model.submitAll();

 

Insert is also very simple: model.insertRows (row, 1); that we want to insert a new row of data in the location index 0. Use setData () function is ready to begin the actual data to be inserted. Note that we write to the first position row of Cheng (by model.index (row, 1), recall that we model as a two-dimensional table, the coordinates correspond to the first row row, column 1), and the remaining and so on. Finally, call submitAll () function to submit all changes. Performing the operations herein can be represented by the following SQL:

INSERT INTO student (name, age,score) VALUES ('Cheng', 24,99)

When we removed the data already exists, modify it, and then re-written to the database, to complete the update operation:

record.setValue("age", 26);
model.setRecord(0, record);
model.submitAll();
//或者:
model.setData(model.index(0, 1), 26);

 

We note that the first two columns of age, an index value, where the update can be expressed by the following SQL:

UPDATE student SET age = 26 WHERE age = 25

Delete as follows:

model.removeRows(0, 1);
model.submitAll();

This is equivalent to:

DELETE FROM student WHERE age = 25

In addition, model also provides sorting:

model->setSort (0, Qt::AscendingOrder);
model->select ();

Operation of things:

model->database ().transaction ();  //开始事物操作
if(model->submitAll ())
    model->database ().commit ();//提交
else
{
    model->database ().rollback ();//回滚
    QMessageBox::warning (this, tr("tableModel"), tr("数据库错误:%1").arg (model->lastError ().text ()));
}

 

Revoked:

model->revertAll ();//撤销修改

example

And finally put two examples, one with a database language, and the other is achieved by the model / view framework: Examples

Published 79 original articles · won praise 65 · views 50000 +

Guess you like

Origin blog.csdn.net/bjtuwayne/article/details/105161693