[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel

简介:
楼主
  发表于 2013-5-21 20:36:22  | 查看: 923 | 回复: 7
SQL表格模型QSqlTableModel

版权声明

该文章原创于作者yafeilinux,转载请注明出处!




导语

在上一篇我们讲到只读的QsqlQueryModel模型其实也可以实现编辑功能的,但是实现起来很麻烦。而QSqlTableModel提供了一个一次只能操作单个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。



环境: Windows Xp + Qt 4.8.4+QtCreator 2.6.2



目录

一、创建数据库
二、修改操作
三、查询操作
四、排序操作
五、删除操作
六、插入操作




正文


一、创建数据库


1. 新建Qt Gui 应用,项目名称为tableModel ,基类QMainWindow ,类名MainWindow


2. 完成后打开tableModel.pro 文件,将第一行代码更改为:
QT        += coregui sql
        然后保存文件。


3. 向项目中添加新的C++ 头文件,名称为connection.h 。完成后将其内容更改如下:
#ifndef   CONNECTION_H
#define   CONNECTION_H
#include   <QSqlDatabase>
#include   <QSqlQuery>
static   bool   createConnection()
{
     QSqlDatabase   db   =   QSqlDatabase ::addDatabase( "QSQLITE" );
     db.setDatabaseName( "database.db" );
     if (!db.open())   return   false ;
     QSqlQuery   query;
     query.exec( QString (
       "create tablestudent (id int primary key, name vchar)" ));
     query.exec( QString ( "insert into student values (0,' 刘明')" ));
     query.exec( QString ( "insert into student values (1,' 陈刚')" ));
     query.exec( QString ( "insert into student values (2,' 王红')" ));
     return   true ;
}
#endif   // CONNECTION_H
        这里因为语句中使用了中文,所以使用了QString() 进行编码转换,这个还需要在main() 函数中设置编码。


4. 下面将main.cpp 文件更改如下:
#include   "mainwindow.h"
#include   <QApplication>
#include   "connection.h"
#include   <QTextCodec>
int   main ( int   argc,   char   *argv[])
{
     QApplication   a(argc,   argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
     QTextCodec ::setCodecForCStrings( QTextCodec ::codecForLocale());
     if (!createConnection())
        return   1 ;
     MainWindow   w;
     w.show();
   
     return   a.exec();
}
     这里的setCodecForCStrings()就是用来设置字符串编码的。


5. 下面进入设计模式,向窗口上拖入Label Push Button Line Edit Table View 等部件,进行界面设计,效果如下图所示。
25-1.jpg


6. 完成后到mainwindow.h 文件中,先包含头文件:
#include   <QSqlTableModel>
然后添加私有对象声明:
QSqlTableModel   * model ;


7. mainwindow.cpp ,在构造函数添加如下代码:
model   =   new   QSqlTableModel ( this );
model ->setTable( "student" );
model ->setEditStrategy( QSqlTableModel :: OnManualSubmit );
model ->select();   // 选取整个表的所有行
// 不显示name属性列,如果这时添加记录,则该属性的值添加不上
// model->removeColumn(1);
ui -> tableView ->setModel( model );
// 使其不可编辑
//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

这里创建一个QSqlTableModel后,只需使用setTable()来为其指定数据库表,然后使用select()函数进行查询,调用这两个函数就等价于执行了“select * from student”这个SQL语句。这里还可以使用setFilter()来指定查询时的条件,在后面会看到这个函数的使用。在使用该模型以前,一般还要设置其编辑策略,它由QSqlTableModel::EditStrategy枚举变量定义,一共有三个值,如下图所示。用来说明当数据库中的值被编辑后,什么情况下提交修改。
25-2.jpg

运行程序,效果如下图所示。
25-3.jpg

       可以看到,这个模型已经完全脱离了SQL 语句,我们只需要执行select() 函数就能查询整张表。上面有两行代码被注释掉了,你可以取消注释,测试一下它们的作用。


二、修改操作


1. 我们进入“提交修改”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_3_clicked()
{
     model ->database().transaction();   // 开始事务操作
     if   ( model ->submitAll())   {
        model ->database().commit();   // 提交
     }   else   {
        model ->database().rollback();   // 回滚
        QMessageBox ::warning( this ,   tr( "tableModel" ),
                              tr( " 数据库错误: %1" )
                              .arg( model ->lastError(). text()));
     }
}
        这里用到了事务操作,真正起提交操作的是model->submitAll() 一句,它提交所有更改。

2. 进入“撤销修改”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_4_clicked()
{
     model ->revertAll();
}

3. 在mainwindow.cpp文件中包含 头文件:
#include   <QMessageBox>
#include   <QSqlError>


4. 现在运行程序,我们将陈刚改为李强,如果我们点击撤销修改,那么它就会重新改为陈刚,而当我们点击提交修改后它就会保存到数据库,此时再点击撤销修改就修改不回来了。
        可以看到,这个模型可以将所有修改先保存到model 中,只有当我们执行提交修改后,才会真正写入数据库。当然这也是因为我们在最开始设置了它的保存策略:
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
这里的OnManualSubmit表明我们要提交修改才能使其生效。


三、查询操作


1. 进入“查询”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_clicked()
{
     QString   name   =   ui -> lineEdit ->text();
     // 根据姓名进行筛选
     model ->setFilter( QString ( "name = '%1'" ).arg(name));
     // 显示结果
     model ->select();
}
        使用setFilter() 函数进行关键字筛选,这个函数是对整个结果集进行查询。


2. 进入“显示全表”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_2_clicked()
{
     model ->setTable( "student" );     // 重新关联表
     model ->select();     // 这样才能再次显示整个表的内容
}
为了再次显示整个表的内容,我们需要再次关联这个表。


3. 下面运行程序,输入一个姓名,点击查询按钮后,就可以显示该记录了。再点击显示全表按钮则返回。如下图所示。
25-4.jpg


四、排序操作

分别进入id 升序排序id 降序排序按钮的单击信号槽,更改如下:
//  升序
void   MainWindow ::on_pushButton_7_clicked()
{
     model ->setSort( 0 ,   Qt :: AscendingOrder );   //id 属性即第0列,升序排列
     model ->select();
}
//  降序
void   MainWindow ::on_pushButton_8_clicked()
{
     model ->setSort( 0 ,   Qt :: DescendingOrder );
     model ->select();   
}
这里使用了setSort()函数进行排序,它有两个参数,第一个参数表示按第几个属性排序,表头从左向右,最左边是第0个属性,这里就是id属性。第二个参数是排序方法,有升序和降序两种。运行程序,效果如下图所示。
25-5.jpg


五、删除操作

我们进入“删除选中行”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_6_clicked()
{
     // 获取选中的行
     int   curRow   =   ui -> tableView ->currentIndex().row();
   
     // 删除该行
     model ->removeRow(curRow);
   
     int   ok   =   QMessageBox ::warning( this ,tr( " 删除当前行!" ),tr( " 你确定"
                                                  " 删除当前行吗?" ),
                                   QMessageBox :: Yes , QMessageBox :: No );
     if (ok   ==   QMessageBox :: No )
     {
        model ->revertAll();   // 如果不删除,则撤销
     }
     else   model ->submitAll();   // 否则提交,在数据库中删除该行  
}

删除行的操作会先保存在model中,当我们执行了submitAll()函数后才会真正的在数据库中删除该行。这里我们使用了一个警告框来让用户选择是否真得要删除该行。运行程序,效果如下图所示。
25-6.jpg

我们点击第二行,然后单击“删除选中行”按钮,出现了警告框。这时你会发现,表中的第二行前面出现了一个小感叹号,表明该行已经被修改了,但是还没有真正的在数据库中修改,这时的数据有个学名叫脏数据(Dirty Data)。当我们按钮“Yes”按钮后数据库中的数据就会被删除,如果按下“No”,那么更改就会取消。


六、插入操作

        我们进入“添加记录”按钮的单击信号槽,更改如下:
void   MainWindow ::on_pushButton_5_clicked()
{
     int   rowNum   =   model ->rowCount();   // 获得表的行数
     int   id   =   10 ;
     model ->insertRow(rowNum);   // 添加一行
     model ->setData( model ->index(rowNum, 0 ),id);
     //model->submitAll(); // 可以直接提交
}
在表的最后添加一行,因为在student表中我们设置了id号是主键,所以这里必须使用setData()函数给新加的行添加id属性的值,不然添加行就不会成功。这里可以直接调用submitAll()函数进行提交,也可以利用“提交修改”按钮进行提交。运行程序,效果如下图所示。
25-7.jpg

按下“添加记录”按钮后,就添加了一行,不过在该行的前面有个星号,如果我们按下“提交修改”按钮,这个星号就会消失。当然,如果我们将上面代码里的提交函数的注释去掉,也就不会有这个星号了。


结语

可以看到这个模型很强大,而且完全脱离了SQL语句,就算你不怎么懂数据库知识,也可以利用它进行大部分常用的操作。我们也看到了,这个模型提供了缓冲区,可以先将修改保存起来,当我们执行提交函数时,再去真正地修改数据库。当然,这个模型比前面的模型更高级,前面讲的所有操作,在这里都能执行。





涉及到的源码:  tableModel.zip (3.98 KB, 下载次数: 11) 



相关文章
|
1月前
|
SQL 存储 关系型数据库
第二篇:关系型数据库的核心概念与 SQL 基础
本篇内容深入浅出地讲解了关系型数据库的核心概念与SQL基础,适合有一定计算机基础的学习者。文章涵盖数据库的基本操作(CRUD)、数据类型、表的创建与管理等内容,并通过实例解析SELECT、INSERT、UPDATE、DELETE等语句的用法。此外,还推荐了多种学习资源与实践建议,帮助读者巩固知识。学完后,你将掌握基础数据库操作,为后续高级学习铺平道路。
108 1
|
2月前
|
SQL 数据库 数据安全/隐私保护
数据库数据恢复——sql server数据库被加密的数据恢复案例
SQL server数据库数据故障: SQL server数据库被加密,无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密,文件名字被篡改。
|
29天前
|
人工智能 数据挖掘 API
基于neo4j数据库和dify大模型框架的rag模型搭建——后续补充
基于neo4j数据库和dify大模型框架的rag模型搭建——后续补充
176 21
基于neo4j数据库和dify大模型框架的rag模型搭建——后续补充
|
30天前
|
Java 数据库 Docker
基于neo4j数据库和dify大模型框架的rag模型搭建
基于neo4j数据库和dify大模型框架的rag模型搭建
284 35
|
2月前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
2月前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
3月前
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
93 16
|
3月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
2月前
|
SQL IDE 关系型数据库
JetBrains DataGrip 2025.1 发布 - 数据库和 SQL 跨平台 IDE
JetBrains DataGrip 2025.1 (macOS, Linux, Windows) - 数据库和 SQL 跨平台 IDE
157 0

推荐镜像

更多
  • qt