QxOrm入门实战
博客例程 – BlogDemo项目
外键统一使用QSharedPointer智能指针
1 创建表格
-
博客:一个博客由一个作者编写,可以有多个评论,并可以放置在多个分类中。
Blog.h
#ifndef BLOG_H #define BLOG_H #include "Author.h" #include "Category.h" #include "Comment.h" class BLOG_DLL_EXPORT Blog { public: Blog() : m_id(0) {} virtual ~Blog() {} public: long m_id; //主键 QString m_title; //标题 QString m_text; //内容 QDateTime m_createdAt; //创建时间 AuthorPtr m_authorPtr; //作者 CommentPtrVect m_commentPtrVect; //评论列表 CategoryPtrColl m_categoryPtrColl; //标签列表 }; typedef QSharedPointer<Blog> BlogPtr; /************************************************************ * QX_REGISTER_HPP_APP 宏是必须的,用于将 Blog 类注册到 QxOrm 的上下文中 * 参数一:表示要注册的当前类 - Blog * 参数二:基类,如果没有基类,则使用 qx::trait::no_base_class_defined * 参数三:用于序列化的类版本 * ***********************************************************/ QX_REGISTER_HPP_BLOG(Blog, qx::trait::no_base_class_defined, 0) #endif // BLOG_H
Blog.cpp
#include "Blog.h" #include <QxOrm_Impl.h> #include "precompiled.h" /************************************************************ * QX_REGISTER_CPP_BLOG 宏是必须的,用于将 Blog 类注册到 QxOrm 的上下文中 * ***********************************************************/ QX_REGISTER_CPP_BLOG(Blog) namespace qx { /************************************************************** * qx::register_class() 是一个设置函数 * 用于将 User 类对应的属性 注册到 QxOrm 的上下文中 * ***********************************************************/ template <> void register_class(QxClass<Blog>& t) { //设置数据库表名 t.setName("t_blog"); //设置表的主键 t.id(&Blog::m_id, "id"); //添加字段 t.data(&Blog::m_title, "title"); t.data(&Blog::m_text, "text"); t.data(&Blog::m_createdAt, "created_at"); //创建一个n-1的关联关系,并添加字段 author_id ,此字段作表Author的外键 t.relationManyToOne(&Blog::m_authorPtr, "author_id"); //创建一个1-n的关联关系,关系名为 list_comment,(表Comment 的字段 blog_id 作为此表的外键) t.relationOneToMany(&Blog::m_commentPtrVect, "list_comment", "blog_id"); //创建一个n-n的关联关系,关系名为 list_blog,取用时是blog_id->category_id的映射 //创建一个新表 category_blog(如果不存在),并添加字段category_id和blog_id t.relationManyToMany(&Blog::m_categoryPtrColl, "list_category", "category_blog", "blog_id", "category_id"); } } // namespace qx
-
作者:一个作者可以编写多个博客。
Author.h
#ifndef AUTHOR_H #define AUTHOR_H class Blog; typedef QSharedPointer<Blog> BlogPtr; typedef QVector<BlogPtr> BlogPtrVect; class BLOG_DLL_EXPORT Author { public: enum Sex { Male, Female, Unknown }; public: Author() : m_id(0), m_sex(Unknown) {} ~Author() {} int age() const; public: long m_id; //主键 Sex m_sex; //性别 QString m_name; //姓名 QDate m_birthdate; //出生日期 BlogPtrVect m_blogPtrVect; //博客列表 }; typedef QSharedPointer<Author> AuthorPtr; QX_REGISTER_HPP_BLOG(Author, qx::trait::no_base_class_defined, 0) #endif // AUTHOR_H
Author.cpp
#include "Author.h" #include <QxOrm_Impl.h> #include "Blog.h" #include "precompiled.h" QX_REGISTER_CPP_BLOG(Author) namespace qx { template <> void register_class(QxClass<Author> &t) { t.setName("d_author"); t.id(&Author::m_id, "id"); t.data(&Author::m_sex, "sex"); t.data(&Author::m_name, "name"); t.data(&Author::m_birthdate, "birthdate"); //创建一个1-n的关联关系,关系名为 list_blog,(表Blog 的字段 author_id 作为此表的外键) t.relationOneToMany(&Author::m_blogPtrVect, "list_blog", "author_id"); //注册一个没有参数的方法 t.fct_0<int>(&Author::age, "age"); } } // namespace qx int Author::age() const { if (!m_birthdate.isValid()) { return -1; } return (QDate::currentDate().year() - m_birthdate.year()); }
-
评论:一个评论属于一个博客。
Comment.h
#ifndef COMMENT_H #define COMMENT_H class Blog; class BLOG_DLL_EXPORT Comment { public: typedef QSharedPointer<Blog> BlogPtr; public: Comment() : m_id(0) {} virtual ~Comment() {} public: long m_id; QString m_text; BlogPtr m_blogPtr; QDateTime m_createdAt; }; typedef QSharedPointer<Comment> CommentPtr; typedef QVector<CommentPtr> CommentPtrVect; QX_REGISTER_HPP_BLOG(Comment, qx::trait::no_base_class_defined, 0) #endif // COMMENT_H
Comment.cpp
#include "Comment.h" #include <QxOrm_Impl.h> #include "Blog.h" #include "precompiled.h" QX_REGISTER_CPP_BLOG(Comment) namespace qx { template <> void register_class(QxClass<Comment>& t) { t.setName("d_comment"); t.id(&Comment::m_id, "id"); t.data(&Comment::m_text, "text"); t.data(&Comment::m_createdAt, "created_at"); //创建一个n-1的关联关系,并添加字段 blog_id ,此字段作表Comment的外键 t.relationManyToOne(&Comment::m_blogPtr, "blog_id"); } } // namespace qx
-
分类:一个分类包含多个博客。
Category.h
#ifndef CATEGORY_H #define CATEGORY_H class Blog; class BLOG_DLL_EXPORT Category { public: typedef QSharedPointer<Blog> BlogPtr; typedef qx::QxCollection<long, BlogPtr> BlogPtrColl; public: Category() : m_id(0) {} virtual ~Category() {} public: long m_id; //主键 QString m_name; //名字 QString m_desc; //描述 BlogPtrColl m_blogPtrColl; //博客列表 }; typedef QSharedPointer<Category> CategoryPtr; typedef qx::QxCollection<long, CategoryPtr> CategoryPtrColl; QX_REGISTER_HPP_BLOG(Category, qx::trait::no_base_class_defined, 0) #endif // CATEGORY_H
Category.cpp
#include "Category.h" #include <QxOrm_Impl.h> #include "Blog.h" QX_REGISTER_CPP_BLOG(Category) namespace qx { template <> void register_class(QxClass<Category>& t) { t.setName("t_category"); t.id(&Category::m_id, "id"); t.data(&Category::m_name, "name"); t.data(&Category::m_desc, "description"); //创建一个n-n的关联关系,关系名为 list_blog,取用时是category_id->blog_id的映射 //创建一个新表 category_blog(如果不存在),并添加字段category_id和blog_id t.relationManyToMany(&Category::m_blogPtrColl, "list_blog", "category_blog", "category_id", "blog_id"); } } // namespace qx
2 数据库初始化
-
连接到数据库,默认连接一个
qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE"); qx::QxSqlDatabase::getSingleton()->setDatabaseName("./blogDemo.db"); qx::QxSqlDatabase::getSingleton()->setHostName("localhost"); qx::QxSqlDatabase::getSingleton()->setUserName("root"); qx::QxSqlDatabase::getSingleton()->setPassword(""); //设置 SQL 查询中的占位符风格为 ph_style_2_point_name。这是一种特定的占位符风格,用于在 SQL 查询中指定参数。 qx::QxSqlDatabase::getSingleton()->setSqlPlaceHolderStyle(qx::QxSqlDatabase::ph_style_2_point_name); //开启 SQL 查询的追踪功能。这意味着在执行 SQL 查询时将输出相关的跟踪信息,如查询语句、参数值等。 qx::QxSqlDatabase::getSingleton()->setTraceSqlQuery(true); //获取到db QSqlDatabase db = qx::QxSqlDatabase::getSingleton()->getDatabase();
-
多个数据库连接,每一个操作后面都有一个参数可以指定数据库
// 数据库一,该方式为创建默认数据库 qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE"); qx::QxSqlDatabase::getSingleton()->setDatabaseName("./Users.db"); qx::QxSqlDatabase::getSingleton()->setHostName("localhost"); qx::QxSqlDatabase::getSingleton()->setUserName("root"); qx::QxSqlDatabase::getSingleton()->setPassword("12345678"); // 数据库二 QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE"); //定义全局的,此处只是举例 db2.setDatabaseName("./Users2.db"); // 数据库三 QSqlDatabase db3 = QSqlDatabase::addDatabase("QSQLITE"); //定义全局的,此处只是举例 db3.setDatabaseName("./Users3.db"); //创建表 qx::dao::create_table<Author>(); //数据库一创建表(默认) qx::dao::create_table<Author>(&db2); //数据库二创建表 qx::dao::create_table<Author>(&db3); //数据库三创建表 //删除表 QSqlError daoError = qx::dao::delete_all<Author>();(默认) daoError = qx::dao::delete_all<Author>(&db2); daoError = qx::dao::delete_all<Author>(&db3); daoError = qx::dao::delete_all<Author>(&db4);
-
创建表
QSqlError daoError = qx::dao::create_table<Author>(); daoError = qx::dao::create_table<Comment>(); daoError = qx::dao::create_table<Blog>(); daoError = qx::dao::create_table<Category>();
3 插入数据
-
创建3个作者
AuthorPtr author1(new Author()); AuthorPtr author2(new Author()); AuthorPtr author3(new Author()); author1->m_id = 1; author1->m_name = "sjl"; author1->m_sex = Author::Male; author1->m_birthdate = QDate(2000, 01, 01); author1->m_id = 2; author2->m_name = "jls"; author2->m_sex = Author::Male; author2->m_birthdate = QDate(2010, 01, 01); author1->m_id = 3; author3->m_name = "ljs"; author3->m_sex = Author::Female; author3->m_birthdate = QDate(2009, 01, 01); QVector<AuthorPtr> authorVect; authorVect << author1 << author2 << author3; daoError = qx::dao::insert(authorVect); //一次性插入3条数据 qDebug() << qx::dao::count<Author>(); //获取当前表数据条数:SELECT COUNT(*) FROM d_author
-
创建1个博客
BlogPtr blogptr1(new Blog()); BlogPtr blogptr2(new Blog()); blogptr1->m_title = QObject::tr("m_titlem_titlem_titlem_title"); blogptr1->m_text = QObject::tr("m_textm_textm_tm_textm_textm_textm_text"); blogptr1->m_createdAt = QDateTime::currentDateTime(); blogptr1->m_authorPtr = author1; blogptr2->m_title = QObject::tr("1m_titlem_titlem_titlem_title"); blogptr2->m_text = QObject::tr("2m_textm_textm_tm_textm_textm_textm_text"); blogptr2->m_createdAt = QDateTime::currentDateTime(); blogptr2->m_authorPtr = author2; qx::dao::insert(blogptr1); qx::dao::insert(blogptr2);
-
同时创建1个博客,带1个作者,带2条评论
BlogPtr blogptr1(new Blog()); blogptr1->m_title = QObject::tr("m_titlem_titlem_titlem_title"); blogptr1->m_text = QObject::tr("m_textm_textm_tm_textm_textm_textm_text"); blogptr1->m_createdAt = QDateTime::currentDateTime(); blogptr1->m_authorPtr = author1; //作者 AuthorPtr author4(new Author()); author4->m_id = 1; author4->m_name = "sjlsjl"; author4->m_sex = Author::Male; author4->m_birthdate = QDate(2001, 02, 01); //评论 CommentPtr commPtr1(new Comment()); CommentPtr commPtr2(new Comment()); commPtr1->m_text = QObject::tr("Comment111111111111"); commPtr1->m_createdAt = QDateTime::currentDateTime(); commPtr1->m_blogPtr = blogptr1; commPtr2->m_text = QObject::tr("Comment2222222222222"); commPtr2->m_createdAt = QDateTime::currentDateTime(); commPtr2->m_blogPtr = blogptr1; //博客 BlogPtr blogptr2(new Blog()); blogptr2->m_title = QObject::tr("1m_titlem_titlem_titlem_title"); blogptr2->m_text = QObject::tr("2m_textm_textm_tm_textm_textm_textm_text"); blogptr2->m_createdAt = QDateTime::currentDateTime(); blogptr2->m_authorPtr = author4; blogptr2->m_commentPtrVect << commPtr1 << commPtr2; //插入带关系的实体 qx::dao::insert_with_all_relation(blogptr2); //下面两种插入方法和上面是同一个效果,只要with_all表全部关系 //关系如何书写请看下面单独小节 qx::dao::insert_with_relation("*", blogptr1); QStringList relation;relation << "*"; qx::dao::insert_with_relation(relation, blogptr1);
4 删除数据
-
删除表中全部数据
qx::dao::delete_all<Author>();
-
根据PO中的id删除数据
AuthorPtr authorTmp(new Author()); authorTmp->m_id = 4; qx::dao::delete_by_id(authorTmp);
-
根据其他条件删除数据
qx::QxSqlQuery queryTmp("WHERE d_author.sex = :sex"); queryTmp.bind(":sex", Author::Female); qx::dao::delete_by_query<Author>(queryTmp);
5 修改数据
-
依据PO中的id更新数据
AuthorPtr authorTmp(new Author()); authorTmp->m_id = 4; authorTmp->m_name = "Jon"; qx::dao::update(authorTmp);
-
如何存在id相同的数据就修改数据,否则插入一条新数据
AuthorPtr authorTmp2(new Author()); authorTmp2->m_id = 1; authorTmp2->m_name = "txtxtx"; authorTmp2->m_sex = Author::Female; authorTmp2->m_birthdate = QDate::currentDate(); qx::dao::save(authorTmp2);
-
带关系的分组插入
BlogPtr blog_1(new Blog()); blog_1->m_title = "blog"; blog_1->m_text = "blog1111"; blog_1->m_authorPtr = author1; blog_1->m_createdAt = QDateTime::currentDateTime(); //使用 'save()' 方法插入数据到数据库 daoError = qx::dao::save(blog_1); //使用 'save()' 方法更新数据库数据 blog_1->m_text = "txtxttxtxttxtxtxtx"; daoError = qx::dao::save(blog_1); //插入2个分组 blog_1->m_categoryPtrColl.insert(category1->m_id, category1); blog_1->m_categoryPtrColl.insert(category3->m_id, category3); daoError = qx::dao::save_with_relation("list_category", blog_1); //获取博客,并附带获取作者、评论、分组 BlogPtr blogTmp(new Blog()); blogTmp->m_id = blog_1->m_id; daoError = qx::dao::fetch_by_id_with_all_relation(blogTmp); qDebug() << "m_commentPtrVect" << blogTmp->m_authorPtr->m_name; qDebug() << "m_commentPtrVect" << blogTmp->m_commentPtrVect.size(); qDebug() << "m_commentPtrVect" << blogTmp->m_categoryPtrColl.size();
6 查询数据
-
查出全部数据
BlogPtrVect blogPtrVect; daoError = qx::dao::fetch_all(blogPtrVect);
-
sql语句查询
qx::QxSqlQuery query("WHERE d_author.sex = :sex"); query.bind(":sex", Author::Female); QVector<AuthorPtr> authorVect2; daoError = qx::dao::fetch_by_query(query, authorVect2);
-
组合查询(下面仅作例子参考,部分字段可能不存在)
qx_query query; query.where("sex") .isEqualTo(User::Female) .and_("age") .isLessThan(38) .orderAsc("id") .limit(5, 5);
qx_query query; query.where("sex").isEqualTo(author::female) .and_("age").isGreaterThan(38) .or_("last_name").isNotEqualTo("Dupont") .or_("first_name").like("Alfred") .and_OpenParenthesis("id").isLessThanOrEqualTo(999) .and_("birth_date").isBetween(date1, date2) .closeParenthesis() .or_("id").in(50, 999, 11, 23, 78945) .and_("is_deleted").isNotNull() .orderAsc("last_name", "first_name", "sex") .limit(50, 150); QList<User> list_of_female; qx::dao::fetch_by_query(query, list_of_female); for (int i = 0; i < list_of_female.count(); i++) ;//your code
-
自定义字段查询+连表查询
BlogPtrVect blogPtrVect; QStringList relationList; relationList << "{ title, text }" //当前表只查询title和text字段 << "author_id { name, birthdate }" //author表查询name和birthdate字段 << "list_comment { text, created_at }"; //comment表查询text和created_at字段 daoError = qx::dao::fetch_all_with_relation(relationList, blogPtrVect); qDebug() << blogPtrVect[0]->m_title << blogPtrVect[0]->m_text << blogPtrVect[0]->m_createdAt.isNull(); qDebug() << blogPtrVect[0]->m_authorPtr->m_name << blogPtrVect[0]->m_authorPtr->m_birthdate << blogPtrVect[0]->m_authorPtr->m_sex; qDebug() << blogPtrVect[0]->m_commentPtrVect.size(); for (int i = 0; i < blogPtrVect[0]->m_commentPtrVect.size(); i++) { qDebug() << blogPtrVect[0]->m_commentPtrVect[i]->m_text; }
-
连表查询查出全部数据
BlogPtrVect blogPtrVect; daoError = qx::dao::fetch_all_with_all_relation(blogPtrVect);
7 事务
-
事务
//打开数据库的事务 QSqlDatabase db = qx::QxSqlDatabase::getDatabase(); bool bCommit = db.transaction(); daoError = qx::dao::insert(category1, (&db)); daoError = qx::dao::insert(category2, (&db)); daoError = qx::dao::insert(category3, (&db)); qDebug() << "category1->m_id = " << category1->m_id; qDebug() << "category2->m_id = " << category2->m_id; qDebug() << "category3->m_id = " << category3->m_id; //事务提交或者回滚 if (bCommit) { db.commit(); } else { db.rollback(); }
8 软触发器
-
基础Po类:为子类提供统一的字段与回调
APo.h
#ifndef _QX_APO_H_ #define _QX_APO_H_ class BIO_DLL_EXPORT APo : public qx::IxPersistable { QX_REGISTER_FRIEND_CLASS(APo) public: APo() : m_id(0) {} virtual ~APo() {} //声明定义回调函数 void onBeforeInsert(qx::dao::detail::IxDao_Helper* dao); void onBeforeUpdate(qx::dao::detail::IxDao_Helper* dao); public: long m_id; QDateTime m_updatedAt; QDateTime m_createdAt; }; //注册一个抽象类 QX_REGISTER_ABSTRACT_CLASS(APo) QX_REGISTER_HPP_BIO(APo, qx::trait::no_base_class_defined, 0) /************************************************************ * QxDao_Trigger<APo> 是一个特化的模板结构体 * 主要用于处理持久化操作(如插入、更新、删除、获取)的前后触发器。 * ***********************************************************/ namespace qx { namespace dao { namespace detail { template <> struct QxDao_Trigger<APo> { static inline void onBeforeInsert(APo* t,qx::dao::detail::IxDao_Helper* dao) { if (t) {t->onBeforeInsert(dao);} } static inline void onBeforeUpdate(APo* t,qx::dao::detail::IxDao_Helper* dao) { if (t) {t->onBeforeUpdate(dao);} } static inline void onBeforeDelete(APo* t,qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } static inline void onBeforeFetch(APo* t, qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } static inline void onAfterInsert(APo* t, qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } static inline void onAfterUpdate(APo* t, qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } static inline void onAfterDelete(APo* t, qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } static inline void onAfterFetch(APo* t, qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(t);Q_UNUSED(dao); } }; } // namespace detail } // namespace dao } // namespace qx #endif // APO_H
APo.cpp
#include "APo.h" QX_REGISTER_CPP_BIO(APo) namespace qx { template <> void register_class(QxClass<APo>& t) { IxDataMember* pData = NULL; pData = t.id(&APo::m_id, "id"); pData = t.data(&APo::m_updatedAt, "updated_at"); pData = t.data(&APo::m_createdAt, "created_at"); } } // namespace qx /* 回调函数的实现 这里实现的功能是 1.插入之前将字段m_updatedAt和m_createdAt设置为当前时间 2.更新之前将字段m_updatedAt设置为当前时间 */ void APo::onBeforeInsert(qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(dao); m_updatedAt = QDateTime::currentDateTime(); m_createdAt = QDateTime::currentDateTime(); } void APo::onBeforeUpdate(qx::dao::detail::IxDao_Helper* dao) { Q_UNUSED(dao); m_updatedAt = QDateTime::currentDateTime(); }
-
子类复用:子类继承复用父类的功能和成员变量
SettingsPo.h
#ifndef SETTINGSPO_H #define SETTINGSPO_H #include "../Base/APo.h" class BIO_DLL_EXPORT SettingsPo : public APo { //用于将某个C++类声明为可以持久化的对象 QX_PERSISTABLE_HPP(SettingsPo) public: SettingsPo() : APo() {} SettingsPo(QString parent, QString key, QString value, QString desc) : APo(), m_parent(parent), m_key(key), m_value(value), m_desc(desc) {} public: QString m_parent; //父节点 QString m_key; //键 QString m_value; //值 QString m_desc; //描述 }; //注意这个地方第二个字段要指定基类APo QX_REGISTER_HPP_BIO(SettingsPo, APo, 0) #endif // SETTINGSPO_H
SettingPo.cpp
#include "SettingsPo.h" #include <QxOrm_Impl.h> //用于将某个C++类声明为可以持久化的对象 QX_PERSISTABLE_CPP(SettingsPo) QX_REGISTER_CPP_BIO(SettingsPo) namespace qx { template <> void register_class(QxClass<SettingsPo> &t) { t.setName("d_settings"); t.data(&SettingsPo::m_parent, "parent"); t.data(&SettingsPo::m_key, "key"); t.data(&SettingsPo::m_value, "value"); t.data(&SettingsPo::m_desc, "desc"); } } // namespace qx
补充
工程目录配置
TEMPLATE = app
# _BUILDING_BLOG,通过它可以知道项目是否正在编译
DEFINES += _BUILDING_BLOG
# C++11特性的支持
QMAKE_CXXFLAGS += -std=c++11
# 预编译头文件
!contains(DEFINES, _QX_NO_PRECOMPILED_HEADER) {
PRECOMPILED_HEADER = precompiled.h
}
macx:CONFIG-=app_bundle
# QxOrm 库相关配置
include(/home/sjl/code/QxOrm_1.4.9/QxOrm/QxOrm.pri)
INCLUDEPATH += /home/sjl/code/QxOrm_1.4.9/QxOrm/include/
LIBS += -L"/home/sjl/code/QxOrm_1.4.9/QxOrm/lib"
# 设置生成的目标名称、添加依赖库
CONFIG(debug, debug|release) {
TARGET = BlogDemod
LIBS += -l"QxOrmd"
} else {
TARGET = BlogDemo
LIBS += -l"QxOrm"
}
export.h
#ifndef EXPORT_H
#define EXPORT_H
/****************************************
* @file Export
* @brief 管理类、函数 ... 的导出/导入。
* @author sjl
* @date 2023/06/25
****************************************/
#ifdef _BUILDING_BLOG
#define BLOG_DLL_EXPORT QX_DLL_EXPORT_HELPER
#else // _BUILDING_BLOG
#define BLOG_DLL_EXPORT QX_DLL_IMPORT_HELPER
#endif // _BUILDING_BLOG
#ifdef _BUILDING_BLOG
#define QX_REGISTER_HPP_BLOG QX_REGISTER_HPP_EXPORT_DLL
#define QX_REGISTER_CPP_BLOG QX_REGISTER_CPP_EXPORT_DLL
#else // _BUILDING_BLOG
#define QX_REGISTER_HPP_BLOG QX_REGISTER_HPP_IMPORT_DLL
#define QX_REGISTER_CPP_BLOG QX_REGISTER_CPP_IMPORT_DLL
#endif // _BUILDING_BLOG
#endif // EXPORT_H
precompiled.h
#ifndef PRECOMPILED_H
#define PRECOMPILED_H
/****************************************
* @file Precompiled
* @brief 预编译头文件,用于提高编译速度
* @author sjl
* @date 2023/06/25
****************************************/
#include <QxOrm.h>
#include "export.h"
#endif // PRECOMPLIED_H