C++ ORM框架 QT版本

mac2025-09-19  30

用C++写的ORM框架,由于一些原因,只写了一个DEMO,一些数据结构和数据库也直接用了QT封装好的

用到的QT库: 1. QList 2. QHash 3. QString 4. QDebug 5. QSqlDatabase 6. QSqlQuery 7. QVariant 8. QUuid

QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open) { const QConnectionDict *dict = dbDict(); Q_ASSERT(dict); dict->lock.lockForRead(); QSqlDatabase db = dict->value(name); dict->lock.unlock(); if (!db.isValid()) return db; if (db.driver()->thread() != QThread::currentThread()) { qWarning("QSqlDatabasePrivate::database: requested database does not belong to the calling thread."); return QSqlDatabase(); } if (open && !db.isOpen()) { if (!db.open()) qWarning() << "QSqlDatabasePrivate::database: unable to open database:" << db.lastError().text(); } return db; }

QT的数据库是单线程版本的,加了线程控制,看了源码,各种宏,也没细看,就没办法做多线程了

接下来是表数据定义,用了宏,语法超简单

#ifndef YSQLDEFINEMODELS_H #define YSQLDEFINEMODELS_H #include <YSqlModel> YSQLMODELCREATECLASS(User,//这里是类名 YSQLString(uid)//定义一个string属性 YSQLString(pwd) YSQLInt(count)//定义一个int属性 ) YSQLMODELCREATECLASS(Work, YSQLString(wid) YSQLString(pwd) YSQLString(type) ) #endif // YSQLDEFINEMODELS_H #include "YSqlDefineModels.h" YSQLMODELCREATEINSTANCE(User,user,//这里是类名,表名 //声明一下属性,YSQLFieldPrimaryKey用于把字段声明为主键 //除了YSQLFieldPrimaryKey,还有YSQLFieldUnique,YSQLFieldNotNull分别为unique和not null,很方便 //还有YSQLFieldForeignKey的功能写了,但是每个数据库的声明不一样,所以暂时还没写适配 YSQLStringField(uid) YSQLFieldPrimaryKey(uid) YSQLStringField(pwd) YSQLIntField(count) ) YSQLMODELCREATEINSTANCE(Work,work, YSQLStringField(wid) YSQLFieldPrimaryKey(wid) YSQLStringField(pwd) YSQLStringField(type) )

数据类型大概设想了有这些,不过还没写,刚开始想用ysqlstringfield这种形式,但是不好用,就算了

//#define YSqlChar(x) ysqlcharfield x = ysqlstringfield(#x); #define YSqlString(x) ysqlstringfield x = ysqlstringfield(#x); //#define YSqlText(x) ysqltextfield(x) //#define YSqlLongText(x) ysqltextfield(x) //#define YSqlDate(x) ysqldatefield(x) //#define YSqlTime(x) ysqltimefield(x) //#define YSqlDateTime(x) ysqldatetimefield(x) //#define YSqlBool(x) ysqlboolfield(x) #define YSqlInt(x) ysqlintfield(x) //#define YSqlBigInt(x) ysqlbigintfield(x) //#define YSqlDouble(x) ysqldoublefield(x) //#define YSqlFloat(x) ysqlfloatfield(x)

受C++语法限制和自身的能力限制,必须要在.h文件和.cpp文件都要写定义

接下来是一些用法,为了不污染命名,名字都取得很长 -_-

首先是建表

User user;//建表需要先实例化一个对象 user.CREATE_TABLE();//这两个函数功能一样 user.YSqlCreateTable();

实例化一个对象,《select》

/*我希望能写成 User user(uid="001") 但是C++不支持指定参数名传值,只能折中了, 这是采用了可变参数,所以可以任意传 */ User user(YSQLMETA,YSqlMeta(uid)=QString("001")); User user(YSQLMETA,YSqlMeta(uid)=QString("001"),YSqlMeta(pwd)=QString("100")); User user(YSQLMETA,YSqlMeta(uid)=QString("001"),YSqlMeta(pwd)=QString("100"),YSqlMeta(count)=10); //这里不能直接写“001”,必须用QString包一下,因为我是根据传入变量的类型来保存数据的,大概和QVarint有点像, //可惜功力不太够,写的不是太好,也是写了才想起来QT有个QVarint,不过以后要彻底做成一个框架,我也不能用QT的类了呀 isNull()//判断是否查询到了并实例化了一个对象,如果没有查询到, User user(YSQLMETA,YSqlMeta(uid)=QString("001")); //就等于 User user;

Insert

User user; user.uid = "001"; user.pwd = "100"; user.count = 10; user.save();

Update

User user(YSQLMETA,YSqlMeta(uid)=QString("001")); user.uid = "001"; user.pwd = "100"; user.count = 10; //修改了值之后是立即更新的,但user必须是查询到并实例化的

Delete

//这两句话效果一样 user.remove(); user.delete_();

get_or_create

User user; user.get_or_create(YSqlMeta(uid)=QString("001"),YSqlMeta(pwd)=QString("100"),YSqlMeta(count)=10); //只有在数据不合格的情况下会返回false //这个也是可变参数

insert_many

User user; user.insert_many({{"001","100","10"},{"002","200","20"},{"003","300","30"}}); //总觉得这样写很方便,也很直观,有数据没插进去,就返回false

还有很多函数有了想法,但是还没写,不过框架搭的差不多,那些方法写起来就很简单了

百度网盘链接

链接: YSqlTest测试工程压缩文件 提取码: r8aj

这个是初版,还没有优化和重新设计

最新回复(0)