** 此操作数据库框架为类mybatis,如果之前使用过此类框架,则会比较熟悉一些,所有的sql操作都采用宏函数的进行操作,方便简单。 此框架目前为测试版本,非稳定版本。版本查看:在Qdbc.h中的Qversion宏,你可以打印此宏,如果看到版本中有c,为测试版本。为s,则为稳定版本 此框架命名为Qdbc,如果有重名,则立刻修改。**
将Qdbc文件夹拷贝到新创建的工程目录中
建立一个含qt的工程并且包含于SQL模块
添加"Qdbc.h"头文件导入其中即可快速开苏
导入laneip表(网络检测表),数据库一定要utf-8格式,测试的数据表如下
CREATE TABLE Laneip (
id int(11) NOT NULL AUTO_INCREMENT ,
ip varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
port varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
entryno varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
etype int(255) NULL DEFAULT NULL ,
Status int(255) NULL DEFAULT 1 ,
description varchar(600) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
updatetime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=7
ROW_FORMAT=COMPACT;
表结构解释:
字段名 | 描述 |
---|---|
id | 默认自增长 |
ip | 网站的ip |
port | 网站的端口 |
url | 网站的url |
entryno | 网站的地点编号(‘0’:北京,'1':上海,'2':深圳,'3':江苏) |
etype | 网站种类(0:‘ 企业网站 ’,1:‘ 行业网站 ’,2:‘ B2B电子商务网站 ’) |
description | 网络状态描述 (‘网络异常,连接超时’,‘网络正常’) |
updatetime | 更新事件,如果不填,则为当前时间 |
#include <QtCore/QCoreApplication>
#include "dbc.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString ip;
Qselect("SELECT ip from laneip WHERE id = 2") > ip;
return a.exec();
}
目前占位符分两种#{}和${}。#{}和${}与orm的类的属性要完全匹配,如何不匹配,会出现异常。#{}表示一个预处理占位符号,${} 表示简单的拼接sql
void updatetest()
{
QString sql = "UPDATE laneip SET updatetime='${updatetime}' WHERE id=${id}";
int count;
Qupdate(sql) < QDateTime::currentDateTime() < 2 > count ;
qDebug() << "update1:" << count;
}
对于Qselect,可根据需求返回,查询不到或者执行报错,指针类型为NULL,值类型为-1。
对于Qupdate,Qinsert,Qdelete,只返回int类型,执行成功,返回影响的行数。执行报错,返回-1 。
宏格式
所有宏格式都在Qdbc中进行查看,采取语义化的标签,尽量方便使用。此为查询语句格式:
Qselect 表示查询宏:对于查询 Qselect("select * from xxx") < arg1 < arg2 > result; 可以有多个输入,但只能一个输出。<表示输入,相当于函数参数,>表示输出,相当于函数返回值。<不可以指定为list类型,但返回值可以,一般用于查询多条语句。
其他语句格式:
Qdelete 表示删除宏 Qinsert 插入宏 Qdelete删除宏,此上三种宏只能有一个输出或不输出。此输出类型一定为int类型。
Qtransactional事务宏
默认放在函数的第一行,这样才能照顾到所有的sql操作,一旦某个sql操作出现了错误,则会回滚操作,否则提交,列子如下:
void transactionaltest()
{
Qtransactional();
Laneip lane;
lane.ip = "192.168.1.103";
lane.id = 2;
QString sql = "UPDATE laneip SET ip=#{ip} WHERE id=#{id}";
int count;
Qupdate("UPDATE laneip SET1 ip=#{ip} WHERE id=#{id}") < &lane > count;
lane.ip = "192.168.1.104";
lane.id = 2;
Qupdate(sql) < &lane > count;
qDebug() << "update:" << count;
}
Qswitch(const1) const1 为常量,此常量支持字符串或者整形。
Qcase(const1,value1) const1 为常量,此常量支持字符串或者整形。value1为匹配到的const1值
Qforeach(begin,separator,end,collection)
Qforeach 宏为循环语句,相当于for语句,此宏需单独使用
begin 参数为字符串,此为collection的开始点
separator 参数为字符串,此为collection以什么分割
end 参数为字符串,此为collection的结束点
collection 此为QString,QList,QStringList类型,QList可以用宏IntList代替
Qclear
Qclear为释放动态申请内存的指针变量,可以手动进行释放,如果不手动释放,申请的内存也会自动释放
QconfigPath(path,name)
此宏需要在执行sql语句之前进行配置,否则配置无效。
QBye()
此宏用于对于在多线程情况下,线程需要不断的销毁于创建,需要在线程结束的时候放置 QBye()
QDBC_Id
此宏用于在多线程下定位哪个线程打印的数据,每次增加一个线程,QDBC_Id就会增加1, 如:qDebug() << QDBC_Id << Object_utils::toString(lane);
此方法为测试Qif功能
void iftest()
{
Laneip* lane = NULL;
QString ip = "192.168.1.104";
QString sql = "SELECT * FROM laneip WHERE id = "
Qif(ip == "192.168.1.104", "2")
Qelse("0");
Qselect(sql) > lane;
if (lane == NULL) {
qDebug() << "error";
return;
}
qDebug() << Object_utils::toString(lane);
}
**此方法为测试Qswitch功能,此返回的是**
void switchtest()
{
Laneip* lane = NULL;
QString ip = "192.168.1.104";
QString sql = "SELECT * FROM laneip WHERE id = "
Qswitch(ip)
Qcase("192.168.1.100","1")
Qcase("192.168.1.104","2");
Qselect(sql) > lane;
if (lane == NULL) {
qDebug() << "error";
return;
}
qDebug() << Object_utils::toString(lane);
}
此方法为测试Qforeach功能,此返回是list类型
void foreachtest()
{
qDebug() << "QHello::selectAl start";
QList<Laneip*> lanelist;
IntList ls;
ls << 2 << 3;
QString sql = "SELECT * FROM laneip where id in" Qforeach("(",",",")",ls);
Qselect(sql) > lanelist;
qDebug() << QDBC_Id << Object_utils::toString(lanelist);
}
Qresults 宏使用
此宏需要配合@result_Id,@result,@one,@many
#define result_Id(column,...) 此为定义id的属性,column定义为数据库列名,如果填充属性,则为自定义属性,否则为数据库列名跟属性名字相同
#define result(column,...) 此为定义类的属性,column定义为数据库列名,如果填充属性,则为自定义属性,否则为数据库列名跟属性名字相同
#define one(classname,...) 此为定义关联的类,classname为类名,可以跟属性形成多级嵌套,关联为对象或链表(只为Qlist)时使用此宏
class Laneipch : public QObject
{
Q_OBJECT
public:
Q_ATTR(int, id)
Q_ATTR(QString, url)
};
class Laneip :public QObject
{
Q_OBJECT
public:
Q_ATTR(int, id)
Q_ATTR(QString, ip)
Q_ATTR(int, port)
Q_ATTR(QString, url)
Q_ATTR(QString, entryno)
Q_ATTR(int, etype)
Q_ATTR(int, Status)
Q_ATTR(QString, description)
Q_ATTR(QDateTime, updatetime)
Q_ASSOCIATION_OBJECT(Laneipch)
};
class Place : public QObject
{
Q_OBJECT
public:
Q_ATTR(int, id)
Q_ATTR(QString, name)
Q_ATTR(QString, area)
Q_ASSOCIATION_OBJECT(Laneipch)
};
void unionselect()
{
QList<Place*> pl ;
QString str = "SELECT pl.id as pid,pl.`name`, pl.area,l.id,l.ip,l.url,l.entryno,ch.id as chid,ch.url as urls \
from laneip L, place pl, laneipchild ch WHERE l.etype = pl.id and pl.id = ch.id ORDER BY pid asc";
Qselect(str) < Qresults(
@result_Id(pid, id),
@result(name),
@result(area),
@one(Laneip, {
@result_Id(id),
@result(ip),
@result(url),
@result(entryno),
}),
@one(Laneipch, {
@result_Id(chid,id),
@result(urls,url),
})
) > pl;
Qclear();
}
class Laneip :public QObject
{
Q_OBJECT
public:
Q_ATTR(int,id)
Q_ATTR(QString, ip)
Q_ATTR(int, port)
Q_ATTR(QString,url)
Q_ATTR(int,entryno)
Q_ATTR(int,etype)
Q_ATTR(int, Status)
Q_ATTR(QString, description)
Q_ATTR(QDateTime,updatetime)
};
对于orm定义的类,使用Q_ATTR来包裹定义的成员变量。此宏默认会在其成员中加入get或set方法,并且大小写敏感,禁止使用static变量,并且不要试图用laneip(QObject *parent): QObject(parent)来定义。
别名属性:
如果不想说明数据库的字段名作为属性,则可以使用别名来定义属性。此Q_ATTR_ALIAS(Laneip,lane_url,url)
例如:Q_ATTR_ALIAS(Laneip,lane_url,url) 属性为lane_url,指定的表字段为url
属性访问:
读取属性: Laneip ip; int id = ip.id;或者int id = ip.getid();
写属性: Laneip ip; ip.id = 11;或者ip.setid(12);
属性类型规定:如果想要使用自定义类型,需要继承Object_qdbc,继承之后就可以与标签进行绑定,属性暂时只能规定: 字符串类型 QString 时间类型 QDateTime 值类型 int,bool 更多类型后续增加 。而对于自定义的变量需要定义成指针:
Laneip *lane = NULL;
QString sql = "SELECT * FROM laneip WHERE id = #{lid}";
Qselect(sql) < 3 > lane;
注意:orm采用的办自动化内存管理,会在适当的时机释放掉此内存,千万不要收到delete,如果想要delete此指针,请使用此宏函数Qclear()。此指针不会保存很长时间,如果想长期保存,需要自己定义变量来保存。
3 . 输入与输出
假设orm定义的类为T,对于输入(<) 而言,只能为T,对于输出而言,可以为T,或者 Qlist<T*> 类型,*T。
我们以Laneip的定义类来举例,详见如下表格。而对于指针类型,直接用NULL进行判断,而对于直接定义的类型,需要用 Object_utils::isNULL 进行判断。需要规定的是如果对象输出的对象为NULL,那么qdbc会默认new一个对象,否则视为已分配对象,不会重复分配。
输入(<) | 输出(>) |
---|---|
Laneip lane 或者 lane* lane = new Lane() | Laneip lane 或者 Laneip* lane = new Laneip()或者Laneip* lane=NULL或者QList<Laneip*> lane |
对于 Laneip lane = NULL而言,Qclear()会清楚此内存。但对于 Laneip lane = new Laneip()不会清理内存,请手动释放**
Object_utils 此类将有三个静态成员函数分别为:
static QString toString(T* src)
static QString toString(QList<T*>& value)
static void copy(T* src,T* dec)
static void clear(T& data)
static void clear(T* & data)
static bool isNULL(T& data)
static bool isClear(T& data)
static bool compare(T& data)
此内容大致为:"[ id:3 ip:192.168.1.100 port:100 url:https://github.com/linuxguangbo/ entryno:111 etype:1 Status:1 description:正常 updatetime:2020-09-08T17:33:55 ]"
Laneip* lane = NULL;
QString sql = "SELECT * FROM laneip where id = 2";
Qselect(sql) > lane;
qDebug() << Object_utils::toString(lane);
此内容大致为:"[ id:1 ip:127.0.0.1 port:5009 url:www.sohu.com entryno:101 etype:0 Status:2 description:网络异常,连接超时 updatetime:2020-04-30T16:54:29 && id:2 ip:192.168.1.104 port:5010 url:www.baidu.com entryno:102 etype:0 Status:1 description:网络异 常,连接超时! updatetime:2020-09-16T11:23:23 && id:3 ip:192.168.1.100 port:100 url:https://github.com/linuxguangbo/ entryno:111 etype:1 Status:1 description:正常 updatetime:2020-09-08T17:33:55 && id:5 ip:192.168.1.112 port:100 url:www.google.com entryno:111 etype:1 Status:1 description:正常 updatetime:2020-04-30T17:24:19 && id:6 ip:192.168.1.112 port:1144 url:www.google.com entryno:2 etype:2 Status:1 description:网络正常 updatetime:2020-09-08T17:24:47 && ]"
QList<Laneip*> lane;
QString sql = "SELECT * FROM laneip";
Qselect(sql) > lane;
qDebug() << Object_utils::toString(lane);
Laneip *lane = NULL;
QString sql = "SELECT * FROM laneip WHERE id = #{lid}";
Qselect(sql) < 3 > lane;
if (lane == NULL) {
qDebug() << "error";
return;
}
Laneip pp;
Object_utils<Laneip>::copy(&pp, lane);
4. 对于static void clear(T& data)静态成员函数而言,为清除引用orm类型对象。
5. 对于static void clear(T* & data)静态成员函数而言,为清除指针类型orm的对象。
6. 对于static bool isNULL(T& data) 静态成员函数而言,判断引用的orm类型是否为空,与静态成员函数isClear的返回值正好相反
7. 对于static bool isClear(T& data) 静态成员函数而言,判断引用的orm类型是否为被清除,与静态成员函数isNULL的返回值正好相反
8. 对于static bool compare(T& data) 静态成员函数而言,判断引用的orm类属性是否相同,相同返回true,不同为false
此为“20.09”的配置文件,如果或许增加内容,则会在配置文件中单独说明,配置文件的说明如:
[MYSQL] #暂时只要支持MYSQL
host=127.0.0.1 #数据库地址
port=3306 #数据库端口
dbname=test1 #数据库名
dbuser=root #用户名
dbpwd= #密码
isPool=true #释放开启线程,有true和false两张可选,如果是false,则[pool]不管用
timeout=2 #连接数据库的延迟
[TEMPLATE]
Loglevel=1 #日志水平,0代表全输出,1代表不输出
automemory=ture #如果为true,则有Qdbc来管理动态分配的内存,如果false则手动管理内存,Qclear宏将无效。
version=x.x.xc #版本既可以在配置文件看,也可以在Qdbc.h中查看,c为测试版本,s为稳定版
[pool]
initialPoolSize=4 #线程池的个数,暂时只支持默认的线程池,如需扩展,等待后续开发
写在最后:
希望大家提供大量的测试案列,此版暂定为测试版本,谢谢大家支持。如有bug,请在Issues中提问,或者联系邮箱1104559085@qq.com 。
Qdbc源码地址: https://github.com/linuxguangbo/QtOrm
Qdbc测试地址: https://github.com/linuxguangbo/Qt-Orm-test
说明: 测试库(Qt-Orm-test )放置测试代码,源码库(QtOrm )不放置测试代码
如果想修修改代码,或用于其他用途,请带有Qdbc.h中的注释。另遵守Apache License 2.0协议。版本请看配置文件
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型