• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

QtOrm: qt orm,灵感来源Mybatis框架。[qT orm, inspired by mybatis framework] ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

QtOrm

开源软件地址:

https://gitee.com/QdbcShen/QtOrm

开源软件介绍:

Qdbc 使用手册

** 此操作数据库框架为类mybatis,如果之前使用过此类框架,则会比较熟悉一些,所有的sql操作都采用宏函数的进行操作,方便简单。此框架目前为测试版本,非稳定版本。版本查看:在Qdbc.h中的Qversion宏,你可以打印此宏,如果看到版本中有c,为测试版本。为s,则为稳定版本此框架命名为Qdbc,如果有重名,则立刻修改。**

Contents

1,快速开始

  1. 将Qdbc文件夹拷贝到新创建的工程目录中

  2. 建立一个含qt的工程并且包含于SQL模块

  3. 添加"Qdbc.h"头文件导入其中即可快速开苏

  4. 导入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=InnoDBDEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ciAUTO_INCREMENT=7ROW_FORMAT=COMPACT;

    表结构解释:

    字段名描述
    id默认自增长
    ip网站的ip
    port网站的端口
    url网站的url
    entryno网站的地点编号(‘0’:北京,'1':上海,'2':深圳,'3':江苏)
    etype网站种类(0:‘ 企业网站 ’,1:‘ 行业网站 ’,2:‘ B2B电子商务网站 ’)
    description网络状态描述 (‘网络异常,连接超时’,‘网络正常’)
    updatetime更新事件,如果不填,则为当前时间
    1. 插入一些数据,能查询到对应的ip
		#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();		}

2,占位符与宏格式

​ 目前占位符分两种#{}和${}。#{}和${}与orm的类的属性要完全匹配,如何不匹配,会出现异常。#{}表示一个预处理占位符号,${} 表示简单的拼接sql

  1. 标签查找规则:优先找#{}在找${},对于${}注意字符串类型需要加单引号
void updatetest(){	QString sql = "UPDATE laneip SET updatetime='${updatetime}' WHERE id=${id}";	int count;	Qupdate(sql) < QDateTime::currentDateTime() < 2 > count ;	qDebug() << "update1:" << count;}	
  1. 查找出错如果查找出错,则int类型为-1,指针类型为NULL,QString为NULL,需看此返回值是否有查询结果冲突。
  • 对于Qselect,可根据需求返回,查询不到或者执行报错,指针类型为NULL,值类型为-1。

  • 对于Qupdate,Qinsert,Qdelete,只返回int类型,执行成功,返回影响的行数。执行报错,返回-1 。

  1. 宏格式

    所有宏格式都在Qdbc中进行查看,采取语义化的标签,尽量方便使用。此为查询语句格式:

    • Qselect 表示查询宏:对于查询 Qselect("select * from xxx") < arg1 < arg2 > result; 可以有多个输入,但只能一个输出。<表示输入,相当于函数参数,>表示输出,相当于函数返回值。<不可以指定为list类型,但返回值可以,一般用于查询多条语句。

    • 其他语句格式:

      ​ Qdelete 表示删除宏 Qinsert 插入宏 Qdelete删除宏,此上三种宏只能有一个输出或不输出。此输出类型一定为int类型。

  2. 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;}
  1. Qif 宏为逻辑判断,相当于if-else
  • Qif(condition,va)condition 为逻辑判断条件,支持&&,||,!
    va 为此condition条件成立时候,执行va。但va一定为字符串输出
    • Qelif(condition,va)condition 为逻辑判断条件,支持&&,||,!
      va 为此condition条件成立时候,执行va。但va一定为字符串输出,另外一定先执行Qif-Qelse(va)va 为所有的condition条件不成立时候,执行va。但va一定为字符串输出,另外一定先执行Qif或Qelif
  1. Qswitch 宏为选择判断,相当于switch-case,此宏需要跟Qcase连用
    • Qswitch(const1)const1 为常量,此常量支持字符串或者整形。

    • Qcase(const1,value1)const1 为常量,此常量支持字符串或者整形。value1为匹配到的const1值

  • Qdefault(value1)const1 为常量,此常量支持字符串或者整形。value1为匹配不到的const1值
  1. Qforeach(begin,separator,end,collection)

    Qforeach 宏为循环语句,相当于for语句,此宏需单独使用

    • begin 参数为字符串,此为collection的开始点

    • separator 参数为字符串,此为collection以什么分割

    • end 参数为字符串,此为collection的结束点

    • collection 此为QString,QList,QStringList类型,QList可以用宏IntList代替

  2. Qclear

    ​ Qclear为释放动态申请内存的指针变量,可以手动进行释放,如果不手动释放,申请的内存也会自动释放

  3. QconfigPath(path,name)

    ​ 此宏需要在执行sql语句之前进行配置,否则配置无效。

    • path:可以指定相对路径,也可以指定觉得路径,此路径可以是相对路径也可以是绝对路径。对于路径,请用反斜杠进行路径编码。如C:/11/22 。如何填空字符串,则于可执行文件路径相同。
    • name: 指定的配置文件名,如果name为空字符串,则写指定为默认的配置文件名:qjbctemplate.ini。否则以指定的配置文件名来指定。
  4. QBye()

此宏用于对于在多线程情况下,线程需要不断的销毁于创建,需要在线程结束的时候放置 QBye()

  1. 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);		}
  1. Qresults 宏使用

    1. 此宏需要配合@result_Id,@result,@one,@many

    2. #define result_Id(column,...) 此为定义id的属性,column定义为数据库列名,如果填充属性,则为自定义属性,否则为数据库列名跟属性名字相同

    3. #define result(column,...) 此为定义类的属性,column定义为数据库列名,如果填充属性,则为自定义属性,否则为数据库列名跟属性名字相同

    4. #define one(classname,...) 此为定义关联的类,classname为类名,可以跟属性形成多级嵌套,关联为对象或链表(只为Qlist)时使用此宏

      class Laneipch : public QObject{	Q_OBJECTpublic:		Q_ATTR(int, id)		Q_ATTR(QString, url)};class Laneip :public QObject{	Q_OBJECTpublic:		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_OBJECTpublic:	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();}

3,orm 类定义

  1. 假设定义的类型为Laneip,想将类映射到数据库,那就要将类定义成如下格式:
  2. 从20.10版本以后需要加上头文件 #include "QdbcConfig.h"
		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)来定义。

  1. 属性说明
  • Q_ATTR(T,member) 用此宏属性为member,类型为T。定义的属性与数据库表字段一一对应,大小写敏感。
  • 此定义的类一定要继承于QObject,并且写上Q_OBJECT宏,不需要写构造函数。
  • Q_ASSOCIATION_OBJECT(T2) 此宏用于关联一个对象,T2为一个对象类型,不可为指针
  • Q_ASSOCIATION_LIST(T) 此宏用于关联一个链表,T2为一个链表中的对象类型,不可为指针
  • ATTR_ALIAS(T,alias,member) 如果不想与数据库对应名字,则需要别名来定义。alias为别名属性, member为数据库表字段,T表示类型

​ 别名属性:

如果不想说明数据库的字段名作为属性,则可以使用别名来定义属性。此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()不会清理内存,请手动释放**

4,工具类: Object_utils

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)    
  1. 对于static QString toString(T* src) )静态成员函数而言,返回的是定义orm类字符串格式化的内容,以"["开头,“]”结尾,中间为类成员咱开。

​ 此内容大致为:"[ 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);
  1. 对于static QString toString(T* src) )静态成员函数而言,返回的是定义orm的QList类字符串格式化的内容,以"["开头,“]”结尾,中间为类成员咱开,如果有多个类成员,则以&分割。

​ 此内容大致为:"[ 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);
  1. 对于static void copy(T* src,T* dec) 成员而言,为复制定义为orm类的工具。因为继承于Qobject的类禁止拷贝复制,则可以用 copy函数来实现:
				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

5,配置文件:qjbctemplate.ini

​ 此为“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	#线程池的个数,暂时只支持默认的线程池,如需扩展,等待后续开发

6,版本说明

  • 20.09版本:此为qdbc的第一个版本,增加了工具类Object_utils,可以通过配置文件看到版本号。
  • 20.10版本:优化了程序的性能,解决了一部分内存泄漏问题,对于Readme的修订。增加了了Object_utils::compare的功能。提供了对于关联查询的支持。支持关联查询,增加了QdbcConfig的头文件,与之前的Qdbc头文件进行分离

写在最后:

​ 希望大家提供大量的测试案列,此版暂定为测试版本,谢谢大家支持。如有bug,请在Issues中提问,或者联系邮箱[email protected]

​ Qdbc源码地址: https://github.com/linuxguangbo/QtOrm

​ Qdbc测试地址: https://github.com/linuxguangbo/Qt-Orm-test

​ 说明: 测试库(Qt-Orm-test )放置测试代码,源码库(QtOrm )不放置测试代码

​ 如果想修修改代码,或用于其他用途,请带有Qdbc.h中的注释。另遵守Apache License 2.0协议。版本请看配置文件​


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap