QT在Windows中的技术总结(二):sqlite数据库QT接口的应用总结
来源:互联网 发布:双色球数据库查询系统 编辑:程序博客网 时间:2024/06/08 19:48
以前在Linux下使用sqlite 都是用到sqlite3.exe这函数的,当然这需要在Linux下安装sqlite3程序的安装包,这个就不再累述了(我也忘得差不多了。。。)
然而在Windows下,安装sqlite3貌似挺麻烦的,而且对Windows的陌生,使我我压根不敢碰Windows那些环境变量。
另外,我的项目是需要给客户安装使用的,太复杂我也不懂打包在安装包里面。
因此,我在Windows下使用了QT自带数据库函数,让QT能够顺利连接上数据库,但又不需要更改任何环境变量
回忆一下sqlite3.exe这种方法的几条命令 其中Command是QString类型的sqlite命令。
这显示方法是老师教的,是根据行和列,把数据一个个放到表格中。但是,当如果使用QT的数据库接口,显示数据就几句话的事情!!!
废话了一堆~下面开始入正题。。。
这相当于增加一个标识符,这时用db1连接的命名就用sqlite数据库类型,用db2连接的命名就用mysql数据库类型。
下面po一下的程序
这个比较多地方需要注意的。
首先是第3行的获取数据库的问题,我以往习惯是开个指针,然后从头到位就靠一个指针连着这个数据库进行操作的。但是在这里这个方法并不可行,addDatabase返回的并不是指针,出了构造函数之后对象就不存在了,但是这个连接仍旧是存在的,所以只能再次获取它。如果是使用多数据库的,就要在database()里面写那个标识符的参数,来返回对应的数据库连接。
然后比较重要的就是事务操作,因为我学嵌入式大概就花了半年时间,以前是学单片机的,所以对于很多相对基础的理论什么的都是不懂的。以前用数据库就只知道插入删除查询什么的,复杂一点就大概知道共享的时候要上个锁,看事务操作我也看了很久才勉强懂一点,错的地方还望高手指出。
一个人让我对事务操作感兴趣的就是回滚。当时那篇文章形容淘宝付款付到一半,然后系统挂了,那个帐到底是付了还是没付,这就涉及到回滚这个理论。
看了很多理论性的东西的结论,就是当要执行多个条命令同时,如果执行到最后不成功,那么就撤销之前的所有操作。
举个比较常用的例子,不知道大家之前再用sqlite3.exec的时候有没有试过,用删除和插入代替修改(个人觉得修改命令不怎么好用~)。那么在删除和插入这两条命令中,如果删除后程序挂掉了,那么这条数据就不见了。即使是先插入后删除,要是数据项有主键的话,不删除是不能插入的。
因此这时候引入事务操作,先把删除操作写入缓存中(我是这么理解的)再插入,等插入完毕再一次写进数据库中,如果不能够顺利插入,就连删除也一起取消操作。
从 Db.transaction() 开始进入事务操作,遇到Db.commit() 之后一次写入数据库中,如果写入失败就执行回滚操作Db.rollback() 。
这样,只要在query.exec(Text);中写入不同的命令Text,就能完成相关的数据库操作。
只要把查询命令Text放到model->setQuery(Text);中,查询结果就会返回到model中,比sqlite3的方便很多。
更方便的还不只这里,QSqlQueryModel配合TableView使用,显示只是一句话的问题!!!
没错,就是ui->TableView_Doctor->setModel(Model);就是这句话~一句话完成显示啊。。。当年老师肿么就不教我们用QT接口类呢~ 多简单啊
然而在Windows下,安装sqlite3貌似挺麻烦的,而且对Windows的陌生,使我我压根不敢碰Windows那些环境变量。
另外,我的项目是需要给客户安装使用的,太复杂我也不懂打包在安装包里面。
因此,我在Windows下使用了QT自带数据库函数,让QT能够顺利连接上数据库,但又不需要更改任何环境变量
回忆一下sqlite3.exe这种方法的几条命令 其中Command是QString类型的sqlite命令。
sqlite3_open("ServerDatabase.db",&sqlfd);;//打开数据库sqlite3_get_table(sqlfd,Command.toAscii().data(),&res,&row,&col,&errmsg);//查询数据库sqlite3_close(sqlfd);//关闭数据库
基本上用sqlite3的命令的调用都离不开这几条,但使用这几条命令若是要显示在TableWidget上其实是相当麻烦的。
void Server_Devices::Server_DataRe(QString Name,QString Text,int row,int col ,char** result){ if (Name != "Devices") { return; } ui->TableWidget_Device->clearContents(); ui->TableWidget_Device->setRowCount(0); int i,j; for(i = 0;i<row+1;i++) { int nrow = ui->TableWidget_Device->rowCount(); ui->TableWidget_Device->insertRow(nrow); for(j=0;j<col;j++) { QString res = *result; result++; if (i == 0) { continue; } QTableWidgetItem *item = new QTableWidgetItem(res); ui->TableWidget_Device->setItem(i-1,j,item); } ui->TableWidget_Device->removeRow(row); }}
这显示方法是老师教的,是根据行和列,把数据一个个放到表格中。但是,当如果使用QT的数据库接口,显示数据就几句话的事情!!!
废话了一堆~下面开始入正题。。。
在使用跟直接使用sqlite3不同,在使用QT数据库接口的时候,需要加载"QSQLITE"的数据库驱动,再把这个驱动和这个数据库连接起来:
QSqlDatabase Db = QSqlDatabase::addDatabase("QSQLITE"); //添加数据库驱动Db.setDatabaseName("DataBase.db"); //数据库连接命名
这个连接并没有正式打开数据库,只是吧Db和数据库连接起来了,看起来貌似比调用sqlite3函数复杂了些,但因为sqlite支持很多的数据库类型,也可以同时连接多个数据库。
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "first");QSqlDatabase db2 = QSqlDatabase::addDatabase("QMYSQL", "second");
这相当于增加一个标识符,这时用db1连接的命名就用sqlite数据库类型,用db2连接的命名就用mysql数据库类型。
下面po一下的程序
MemoryModule::MemoryModule(QObject *parent) : QObject(parent){ QSqlDatabase Db = QSqlDatabase::addDatabase("QSQLITE"); //添加数据库驱动 Db.setDatabaseName("DataBase.db"); //数据库连接命名 Db_Creat();}void MemoryModule::Db_Creat()//创建表格{ QSqlDatabase Db = QSqlDatabase::database();//获取当前已连接的数据库 if(!Db.open()) //打开数据库 { emit Data_ErrorReturn(QString("DataBase Open Error:%1").arg(Db.lastError().text())); qDebug()<<"DbOpen"<<"error"; } if(Db.driver()->hasFeature(QSqlDriver::Transactions))//判断系统是否支持事务操作 { if(Db.transaction()) //启动事务操作 { //下面执行各种数据库操作 QSqlQuery query; query.exec(/*创建命令*/); query.exec("create table Doctor(User text primary key,Password text,Name text,Contact text,Login text,Logout text)"); query.exec("insert into Doctor values(\"root\",\"123456\",\"root\",\" \",\" \",\" \")" ); if(!Db.commit()) { qDebug() << QSqlDatabase::database().lastError(); //提交 emit Data_DebugMessage(QSqlDatabase::database().lastError().text()); if(!Db.rollback()) { qDebug() << QSqlDatabase::database().lastError(); //回滚 emit Data_DebugMessage(QSqlDatabase::database().lastError().text()); } } } } Db.close();}
这个比较多地方需要注意的。
首先是第3行的获取数据库的问题,我以往习惯是开个指针,然后从头到位就靠一个指针连着这个数据库进行操作的。但是在这里这个方法并不可行,addDatabase返回的并不是指针,出了构造函数之后对象就不存在了,但是这个连接仍旧是存在的,所以只能再次获取它。如果是使用多数据库的,就要在database()里面写那个标识符的参数,来返回对应的数据库连接。
然后比较重要的就是事务操作,因为我学嵌入式大概就花了半年时间,以前是学单片机的,所以对于很多相对基础的理论什么的都是不懂的。以前用数据库就只知道插入删除查询什么的,复杂一点就大概知道共享的时候要上个锁,看事务操作我也看了很久才勉强懂一点,错的地方还望高手指出。
一个人让我对事务操作感兴趣的就是回滚。当时那篇文章形容淘宝付款付到一半,然后系统挂了,那个帐到底是付了还是没付,这就涉及到回滚这个理论。
看了很多理论性的东西的结论,就是当要执行多个条命令同时,如果执行到最后不成功,那么就撤销之前的所有操作。
举个比较常用的例子,不知道大家之前再用sqlite3.exec的时候有没有试过,用删除和插入代替修改(个人觉得修改命令不怎么好用~)。那么在删除和插入这两条命令中,如果删除后程序挂掉了,那么这条数据就不见了。即使是先插入后删除,要是数据项有主键的话,不删除是不能插入的。
因此这时候引入事务操作,先把删除操作写入缓存中(我是这么理解的)再插入,等插入完毕再一次写进数据库中,如果不能够顺利插入,就连删除也一起取消操作。
从 Db.transaction() 开始进入事务操作,遇到Db.commit() 之后一次写入数据库中,如果写入失败就执行回滚操作Db.rollback() 。
如果不是多条命令,仅仅是插入或删除,就不需要用到回滚。
void MemoryModule::Data_Add(QString Text)//添加数据库项{ qDebug()<<Text; QSqlDatabase Db = QSqlDatabase::database(); if(!Db.open()) //打开数据库 { emit Data_ErrorReturn(QString("DataBase Open Error:%1").arg(Db.lastError().text())); qDebug()<<"DbOpen"<<"error"; Re = -1; return; } QSqlQuery query; query.exec(Text); if(!query.isActive()) { emit Data_ErrorReturn(QString("DataBase Insert Error:%1").arg(query.lastError().text())); qDebug()<<"DbInsert"<<"error"; Re = -1; return; } Db.close(); Re = 0;}
这样,只要在query.exec(Text);中写入不同的命令Text,就能完成相关的数据库操作。
但是这种操作是无返回的,那么如何查询数据库呢?这里用到另一个类,也就是刚刚上面说的很简单的查询数据库方法。
void MemoryModule::Data_Search(QString Text)//查询数据库项{ QSqlDatabase Db = QSqlDatabase::database(); if(!Db.open()) //打开数据库 { emit Data_ErrorReturn(QString("DataBase Open Error:%1").arg(Db.lastError().text())); qDebug()<<"DbOpen"<<"error"; Re = -1; return; } QSqlQueryModel *model = new QSqlQueryModel; model->setQuery(Text); Db_Model = model; Db.close(); Re = 0;}
只要把查询命令Text放到model->setQuery(Text);中,查询结果就会返回到model中,比sqlite3的方便很多。
更方便的还不只这里,QSqlQueryModel配合TableView使用,显示只是一句话的问题!!!
void Doctor::Display_ResultData(QString Name,QSqlQueryModel* Model)//接收查询结果返回{ if(Name != "Doctor") { return; } if(Flg == 0)//普通查询 { Model->setHeaderData(0, Qt::Horizontal, tr("用户名")); Model->setHeaderData(2, Qt::Horizontal, tr("姓名")); Model->setHeaderData(3, Qt::Horizontal, tr("联系方式")); Model->setHeaderData(4, Qt::Horizontal, tr("上次登陆")); Model->setHeaderData(5, Qt::Horizontal, tr("上次登出")); ui->TableView_Doctor->setModel(Model); ui->TableView_Doctor->resizeColumnsToContents();//根据内容调节行宽 ui->TableView_Doctor->setRowHidden(0,true);//隐藏第0行 ui->TableView_Doctor->setColumnHidden(1,true);//隐藏第1列 ui->TableView_Doctor->horizontalHeader()->setHighlightSections(false);//点击表格的时候表头不下陷 SqlModel = Model; }}
没错,就是ui->TableView_Doctor->setModel(Model);就是这句话~一句话完成显示啊。。。当年老师肿么就不教我们用QT接口类呢~ 多简单啊
其实以上所有方法在Linux下都是可以用的,只是在Windows下不得不用到而已,所以归纳就写在这系列下了,下一个总结估计是写2D绘图,最近正在被它烦着呢,算坐标实在是纠结死姐了T T~ 串口通信其实也是个点,不过我已经解决了,直接借用别人的类,也不需要纠结太多, 有空也写写吧。
END
0 0
- QT在Windows中的技术总结(二):sqlite数据库QT接口的应用总结
- QT在Windows中的技术总结(一):sqlite的备份还原功能(调用cmd命令模式)
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- Qt数据库sqlite总结
- qt下sqlite数据库的应用(二)
- Qt数据库(sqlite) — 总结
- Qt数据库(sqlite) — 总结
- QT在Windows中的技术总结(四):做整套自定义程序窗口
- dfb在QT的应用总结。
- dfb在QT的应用总结。
- 关于qt 的sqlite数据库的使用总结
- Qt 操作sqlite总结
- The request sent by the client was syntactically incorrect.
- 如何使用Mezzanine
- Find Minimum in Rotated Sorted Array II
- MFC中一些窗口风格的设置以及去掉某些窗口风格的方式
- QT在Windows中的技术总结(一):sqlite的备份还原功能(调用cmd命令模式)
- QT在Windows中的技术总结(二):sqlite数据库QT接口的应用总结
- QT在Windows中的技术总结(三):从生成exe到NSIS初级自定义打包详述
- Xcode强大的多视图立体分层显示View UI Herarchy
- STL vector的使用(一)基础
- BZOJ1207: [HNOI2004]打鼹鼠
- QT在Windows中的技术总结(四):做整套自定义程序窗口
- MFC小练手:详解自绘右键菜单(继承CMenu)
- MFC笔记:从资源文件获取字体
- MFC笔记:关于透明和渐变