• 17217阅读
  • 45回复

自用的数据库访问封装类(20140423更新) [复制链接]

上一主题 下一主题
离线realfan
 

只看楼主 倒序阅读 楼主  发表于: 2014-03-03
— 本帖被 XChinux 设置为精华(2014-03-04) —
DBProcess20140423.zip (6 K) 下载次数:514
详细说明见1楼

自用的数据访问封装类,可以操作sqlite mysql sqlserver access
m_pDbProcPic = new CDBProcess("sqlserver");
m_pDbProc->openDB("mysvr", "mydb", "myusername", "mypwd");

m_pDbProcPic = new CDBProcess("mysql");
m_pDbProc->openDB("localhost", "mydb", "root", "password");

m_pDbProcPic = new CDBProcess("access");
m_pDbProc->openDB("", strMDB, "sa", "password");

m_pDbProcPic = new CDBProcess("sqlite");
m_pDbProcPic->openDB("", "mysqlitedb");





离线realfan

只看该作者 1楼 发表于: 2014-03-04
CDBProcess使用说明

构造函数:
CDBProcess(const QString strType);
参数:为数据库类型,不区分大小写,支持的类型有
sqlite access sqlserver
( mysql  可能一些方法不支持,因本人没环境,未测试。感谢行潇提醒!)
例:
CDBProcess db("sqlite");
--------------------------------------------------
打开数据库
bool openDB(const QString strSvrName,     //服务器名
            const QString strDBname,     //数据库名
            const QString strUserID="",   //用户名
            const QString strUserPwd=""); //密码
打开数据库成功,返回true,否则返回false
对于sqlite,只有strDBname有效,其它参数忽略,如db.openDB("", "mysqlite.db")
对于MS Access数据库,strSvrName为空,用户名默认为"sa",如db.openDB("", "myaccess.mdb");
对MSAccess数据库,也可通过一个UDL文件,打开,如db.openDB("my.udl", "");
mysql和sqlserver,就是各个参数依次提供,如db.openDB("svr1", "mydb", "user1", "abcd");
-----------------------------------------------------
关闭数据库,CDBProcess析构时,亦会自动关闭数据库
void closeDB();  //db.closeDB();
------------------------------------------------------
执行Sql语句
bool excuteSQL(const QString);
-------------------------------------------------------
打开记录集
bool openRecordsetBySql(const QString strSql, //Sql语句
                        int idx = -1);         //记录集id,用于标识记录集,默认值为-1
例:
db.openRecordsetBySql("SELECT * FROM TB1", 5);
打开一个记录集,标识号为5,后面操作这个记录集,也要提供这个标识号
--------------------------------------------------------
关闭记录集
void closeRecordset(int idx = -1);
例:
db.closeRecordset(5); 关闭之前打开的标识为5的记录集
-----------------------------------
数据库是否处在打开状态
bool isOpen() const;
------------------------------------
记录集游标是否在结尾,参数为记录集标识
bool recEOF(int idx = -1) const;
例:bool b = db.RecBOF(5);
------------------------------------
记录集游标是否在第一条记录之前,参数为记录集标识
bool recBOF(int idx = -1) const;
----------------------------------------
删除一个表
bool dropTable(const QString);
---------------------------------------------
读取标识为idx记录集的当前记录的各字段值,方法如示例:
bool getFieldsValueFromRec(int idx, const char* szFldInfo, ...) const;

int iSN;
QString strName;
double dHeight;
QDateTime dt;
QByteArray ba;
db.getFieldsValueFromRec(5,                     //记录集id
                        "sn%d", &iSN,           //字段名加类型 sn为字段名%d表示整型,&iSN传入指针,保存返回字段值
                        "name%s", &strName,     //字段名加类型 name为字段名%s表示字符串(QString)
                        "height&f", &dHeight,   //字段名加类型 height为字段名%f表示小数(double)
                        "birthday%t", &dt,      //字段名加类型 birthday为字段名%t表示时间(QDateTime)
                        "photo%b", &ba,         //字段名加类型 photo为字段名%b表示二进制流(QByteArray)
                        CDBProcess::szEnd);     //结束标志,"|"
执行后,各字段值就保存在iSN, strName等变量中了。
参数:第一个参数为记录集id
后面可变参数,字段%类型标识,用于保存返回值的指针,
类型标识:%d-int  %s-QString   %f-double   %t-QDateTime    %b-QByteArray  
---------------------------------------------------------------------------
向一个数据表中填加一条记录
bool addFieldsValueToTbl(const QString strTbl, const char* szFldInfo, ...);
参数:第一个参数strTbl,为表名
后面是可变参数,为"字段%类型标识",值(或指针),注int,double类型直接传值,其它传指针
例:
db.addFieldsValueToTbl("TB1",                  //表名
                        "sn%d", iSN,           //字段名加类型 sn为字段名%d表示整型,iSN传入值
                        "name%s", &strName,     //字段名加类型 name为字段名%s表示字符串(QString), 传入QString变量指针
                        "height&f", dHeight,   //字段名加类型 height为字段名%f表示小数(double),dHeight传入值
                        "birthday%t", &dt,      //字段名加类型 birthday为字段名%t表示时间(QDateTime),传入指针
                        "photo%b", &ba,         //字段名加类型 photo为字段名%b表示二进制流(QByteArray),传入指针
                        CDBProcess::szEnd);     //结束标志,"|"

-----------------------------------------------------------
修改表中符合WHERE子句条件的记录
bool updateTblFieldsValue(const QString strTbl, QString strWhere, const char * szFldInfo, ... );
strTbl表名
strWhere SQL WHERE子句,如"WHERE sn=20"
const char * szFldInfo, ...可变参数,同addFieldsValueToTbl
例:
db.updateTblFieldsValue("TB1", "WHERE sn=20", "height&f", dHeight, "photo%b", &ba, CDBProcess::szEnd);
----------------------------------------------------------------
以下几个函数分别是获取记录数,和记录光标移动。参数为记录集标识
long getRecordCount(int idx = -1) const;
bool moveFirst(int idx = -1) const;
bool movePrevious(int idx = -1) const;
bool moveNext(int idx = -1) const;
bool moveLast(int idx = -1) const;
bool moveTo(int n, int idx = -1) const;
--------------------------------------------------------------------
返回数据库名
QString getDbName() const;
------------------------
以下几个函数未验证
bool execStoreProcOfArgList(int idx, const QString strStoreProc, const char* szFldsInfo, ...);
bool exexProc(const QString strStoreProc, QString str1, QString& str2);
bool transaction();
bool commit();
bool rollback();
离线wjian10

只看该作者 2楼 发表于: 2014-03-04
感谢分享
离线qhxnwrz

只看该作者 3楼 发表于: 2014-03-05
感谢分享,谢谢
离线libaineu2004

只看该作者 4楼 发表于: 2014-03-06
灰常好!感谢版主!!
离线圣域天子

只看该作者 5楼 发表于: 2014-03-10
此类在线程中使用可能造成不安全~~~
离线realfan

只看该作者 6楼 发表于: 2014-03-10
回 圣域天子 的帖子
圣域天子:此类在线程中使用可能造成不安全~~~ (2014-03-10 09:17) 

这个类是很早写的代码。
因为我当时是对数据库操作集中在一处,在调用这个类操作时,加了锁。所以这类里面没有考虑多线程的问题。
等有空完善下,谢谢提醒。
离线abcdlcq

只看该作者 7楼 发表于: 2014-04-18
建议加上port
离线行潇

只看该作者 8楼 发表于: 2014-04-22
很有奉献精神,刚才下载看了一下,觉得有些变量和函数都没有写上注释,如    QMap<int, QSqlQuery *> m_mapQry;这个变量我琢磨了很久;还有类似    bool addFieldsValueToTblArgList(const QString, const char *szFldsInfo, va_list arg_ptr);这些函数的作用和用法也不是很清楚,希望LZ快点更新,造福群众!

离线realfan

只看该作者 9楼 发表于: 2014-04-22
回 行潇 的帖子
行潇:很有奉献精神,刚才下载看了一下,觉得有些变量和函数都没有写上注释,如    QMap<int, QSqlQuery *> m_mapQry;这个变量我琢磨了很久;还有类似    bool addFieldsValueToTblArgList(const QString, const char *szFldsInfo, va_li .. (2014-04-22 15:25) 

这两天把代码好好整理一下,同时给个说明。
离线realfan

只看该作者 10楼 发表于: 2014-04-23
回 行潇 的帖子
行潇:很有奉献精神,刚才下载看了一下,觉得有些变量和函数都没有写上注释,如    QMap<int, QSqlQuery *> m_mapQry;这个变量我琢磨了很久;还有类似    bool addFieldsValueToTblArgList(const QString, const char *szFldsInfo, va_li .. (2014-04-22 15:25) 

使用说明已经加上
离线行潇

只看该作者 11楼 发表于: 2014-04-24
挺有速度,也很有信任,不错,谢谢!

内容来自[短消息]
离线wjian10

只看该作者 12楼 发表于: 2014-04-24
感谢分享源码
离线realfan

只看该作者 13楼 发表于: 2014-04-24
回 行潇 的帖子
行潇:挺有速度,也很有信任,不错,谢谢!
内容来自[短消息]  (2014-04-24 09:17) 

代码也做了更新
离线行潇

只看该作者 14楼 发表于: 2014-04-24
好的,多谢提醒!
离线行潇

只看该作者 15楼 发表于: 2014-04-25
回 realfan 的帖子
realfan:CDBProcess使用说明
构造函数:
CDBProcess(const QString strType);
....... (2014-03-04 08:47) 

楼主,我用下面的语句试了一下,发现“bool CDBProcess::getFieldsValueFromRec(int idx, const char* szFldInfo, ...) const”这个函数,没有显示效果,下面是我的语句:

CDBProcess *db = new CDBProcess("mysql");
    db->openDB("", "ordersys", "", "");
    db->openRecordsetBySql("select * from test", 15);

QString tmpGoods;
    int tmpNumber;
    QString tmpTime;

db->getFieldsValueFromRec(15, "goods:%s", &tmpGoods, "number%d", tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
    qDebug()<<tmpGoods<<"   "<<";    "<<tmpNumber<<";   "<<tmpTime<<endl;

输出tmpGoods等变量的结果都为空,请问这是什么原因呢?
离线realfan

只看该作者 16楼 发表于: 2014-04-25
回 行潇 的帖子
行潇:楼主,我用下面的语句试了一下,发现“bool CDBProcess::getFieldsValueFromRec(int idx, const char* szFldInfo, ...) const”这个函数,没有显示效果,下面是我的语句:
CDBProcess *db = new CDBProcess("mysql");
    db->openDB("&q .. (2014-04-25 16:54) 

db->getFieldsValueFromRec(15, "goods:%s", &tmpGoods, "number%d", &tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
goods字段名后,多个冒号
tmpNumber要加个取址符,因为数据要写回来的,专变量过去不行。
改成下面的样子试试:
db->getFieldsValueFromRec(15, "goods%s", &tmpGoods, "number%d", &tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
离线realfan

只看该作者 17楼 发表于: 2014-04-25
回 行潇 的帖子
行潇:楼主,我用下面的语句试了一下,发现“bool CDBProcess::getFieldsValueFromRec(int idx, const char* szFldInfo, ...) const”这个函数,没有显示效果,下面是我的语句:
CDBProcess *db = new CDBProcess("mysql");
    db->openDB("&q .. (2014-04-25 16:54) 

db->getFieldsValueFromRec(15, "goods:%s", &tmpGoods, "number%d", &tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
goods字段名后,多个冒号
tmpNumber要加个取址符,因为数据要写回来的,专变量过去不行。
改成下面的样子试试:
db->getFieldsValueFromRec(15, "goods%s", &tmpGoods, "number%d", &tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
离线行潇

只看该作者 18楼 发表于: 2014-04-26
回 realfan 的帖子
realfan:db->getFieldsValueFromRec(15, "goods:%s", &tmpGoods, "number%d", &tmpNumber, "time%s", &tmpTime, CDBProcess::szEnd);
goods字段名后,多个冒号
tmpNumber要加个取址符,因为数据要写回来的,专变量过去不行。
改成下面的样 .. (2014-04-25 16:59) 

用    qDebug()<<tmpGoods<<"   "<<";    "<<tmpNumber<<";   "<<tmpTime<<endl;输出的结果还好:

""     ;     0 ;    ""
离线liuyuanan

只看该作者 19楼 发表于: 2014-05-05
    
离线枫界易城

只看该作者 20楼 发表于: 2014-05-06
     ,学习了!
离线smshandsome

只看该作者 21楼 发表于: 2014-05-18
好东西,看看。问楼主有没有unix下的oralce连接的库
离线awq9527

只看该作者 22楼 发表于: 2014-05-22
谢谢,代码看着好麻烦,看了一上午,终于还是弄明白了
离线yanche

只看该作者 23楼 发表于: 2014-05-26
版主的这个访问方式是ORM的吗?感觉不像
具有十年研发经验的团队,专注于C++、Qt、Python等语言,专业软件开发团队,致力于完美解决客户的需求,我们期待与您的洽谈。
业务范畴:应用软件定制、UI定制、各类管理系统定制、仿真设计、三维开发、通信SDK定制、Logo设计等等
QQ:548725431
微信:yanche521
离线realfan

只看该作者 24楼 发表于: 2014-05-27
没考虑那么多,按实际需要写的,只是为了使用方便些。
离线zsz1

只看该作者 25楼 发表于: 2014-06-24
能加上 oracle的吗? 谢谢分享
离线realfan

只看该作者 26楼 发表于: 2014-06-24
回 zsz1 的帖子
zsz1:能加上 oracle的吗? 谢谢分享 (2014-06-24 14:06) 

没有oracle环境。
应该就是连接数据库的地方有点差异,其它地方应该是一样的。
离线圣域天子

只看该作者 27楼 发表于: 2014-06-25
回 realfan 的帖子
realfan:没有oracle环境。
应该就是连接数据库的地主有点差异,其它地方应该是一样的。 (2014-06-24 21:41) 

听到过很多人说Qt连不上Oracle了,不知具体原因是什么。
离线realfan

只看该作者 28楼 发表于: 2014-06-25
回 圣域天子 的帖子
圣域天子:听到过很多人说Qt连不上Oracle了,不知具体原因是什么。 (2014-06-25 15:16) 

没有条件试。
难道开源版的不给用Oracle连接了?
离线icebrooks

只看该作者 29楼 发表于: 2014-07-08
select后,结果集的内容要怎么读取了,请楼主给个说明例子
离线liuyuanan

只看该作者 30楼 发表于: 2014-07-22
感谢分享源码. 期待楼主分享更多好东西
离线qq93247519

只看该作者 31楼 发表于: 2014-07-24
也许会用到  先收藏了  十分感谢楼主无私奉献
离线行潇

只看该作者 32楼 发表于: 2015-01-30
你好,我在调用addFieldsValueToTbl函数的时候,出现QMYSQL3: Unable to bind value这个错误,请问你遇到过吗,怎么解决?
离线realfan

只看该作者 33楼 发表于: 2015-01-30
回 行潇 的帖子
行潇:你好,我在调用addFieldsValueToTbl函数的时候,出现QMYSQL3: Unable to bind value这个错误,请问你遇到过吗,怎么解决? (2015-01-30 17:28) 

没遇到过。具体是什么类型的字段呢?
离线行潇

只看该作者 34楼 发表于: 2015-02-02
我猜是bool CDBProcess::addFieldsValueToTbl(const QString strTbl, const char* szFldInfo, ...)
这个函数中的        pQry->bindValue(strPlaceholder, var);这个语句,我查看了QT的帮助文档,发现
“QMYSQL Stored Procedure Support

MySQL 5 introduces stored procedure support at the SQL level, but no API to control IN, OUT and INOUT parameters. Therefore, parameters have to be set and read using SQL commands instead of QSqlQuery::bindValue().” 这段话,
离线行潇

只看该作者 35楼 发表于: 2015-02-02
回 realfan 的帖子
realfan:没遇到过。具体是什么类型的字段呢? (2015-01-30 21:18) 

还有我用m_pDB->driver()->hasFeature(QSqlDriver::NamedPlaceholders)这个函数查看,MySQL并不支持这个特征!
离线realfan

只看该作者 36楼 发表于: 2015-02-02
回 行潇 的帖子
行潇:还有我用m_pDB->driver()->hasFeature(QSqlDriver::NamedPlaceholders)这个函数查看,MySQL并不支持这个特征! (2015-02-02 09:12) 

是吗?
我没有MySql的环境,也未试过。
想当然认为是支持的。
可能说明要改一下了
离线行潇

只看该作者 37楼 发表于: 2015-02-02
回 realfan 的帖子
realfan:是吗?
我没有MySql的环境,也未试过。
想当然认为是支持的。
可能说明要改一下了 (2015-02-02 09:17) 

原来这样,我以为是我操作不当呢,不过楼主写的很棒,希望可以看到你更多的作品,谢谢!
离线realfan

只看该作者 38楼 发表于: 2015-02-02
回 行潇 的帖子
行潇:原来这样,我以为是我操作不当呢,不过楼主写的很棒,希望可以看到你更多的作品,谢谢! (2015-02-02 10:17) 

谢谢提醒,已经在帖子中加了一条提示。
离线XChinux

只看该作者 39楼 发表于: 2015-02-28
@realfan  ,   请问我想将这个加入tianchi库,请问可以吧?
本帖提到的人: @realfan
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个