qxorm oracle,QxOrm 快速上手

QxOrm 几乎支持所有的主流数据库,比如 SQLite、MySQL、PostgreSQL、Oracle、MS SQL Server、MongoDB 等。为了快速了解它的用法,我们以 SQLite 为例,来介绍一些常见的数据库操作(例如:增删改查)。

先来创建一个名为 User 的项目,结构如下所示:

c4c2428e2075e7cdda8a2dfc0538fcb0.png

相比传统的 C++/Qt 入门级程序,这个工程似乎“复杂了很多”。的确是这样,但对于 QxOrm 来说,这其实算是最简单的示例了。

像 QxOrm.pri、export.h 以及 precompiled.h 这些文件,在以后的 QxOrm 项目中几乎都会用到,下面将会对他们进行详细的介绍!

1

项目文件

项目文件由 User.pro 表示,它包含了项目中所有的文件列表(头文件、源文件),以及所有依赖项(QxOrm.pri 文件包含了与 Qt 和 boost 库的所有依赖项):

# QxOrm 的通用配置,包含了 Qt 和 boost 库依赖

include($$PWD/../QxOrm/QxOrm.pri)

CONFIG += console

DEFINES += _BUILDING_USER

# 预编译头文件

!contains(DEFINES, _QX_NO_PRECOMPILED_HEADER) {

PRECOMPILED_HEADER = precompiled.h

}

# QxOrm 库相关配置

INCLUDEPATH += $$PWD/../QxOrm/include

LIBS += -L$$PWD/../QxOrm/lib

# 设置生成的目标名称、添加依赖库

CONFIG(debug, debug|release) {

TARGET = Userd

LIBS += -lQxOrmd

} else {

TARGET = User

LIBS += -lQxOrm

}

# 文件列表

HEADERS += \

precompiled.h \

export.h \

user.h

SOURCES += \

main.cpp \

user.cpp

这里有一个重要的常量 - _BUILDING_USER,通过它可以知道项目是否正在编译(参见 export.h 和 Windows 下的 DLL 机制 - 导入或导出函数、类...)。

2

export.h 文件

如果使用过 DLL,相信对此文件并不陌生,它可以管理类、函数 ... 的导出/导入。

QxOrm 使用了相同的机制来提供某些功能:因此对于使用 QxOrm 库的所有项目,export.h 文件是必需的:

#ifndef EXPORT_H

#define EXPORT_H

#ifdef _BUILDING_USER

#define USER_DLL_EXPORT  QX_DLL_EXPORT_HELPER

#else

#define USER_DLL_EXPORT  QX_DLL_IMPORT_HELPER

#endif

#ifdef _BUILDING_USER

#define QX_REGISTER_HPP_USER  QX_REGISTER_HPP_EXPORT_DLL

#define QX_REGISTER_CPP_USER  QX_REGISTER_CPP_EXPORT_DLL

#else

#define QX_REGISTER_HPP_USER  QX_REGISTER_HPP_IMPORT_DLL

#define QX_REGISTER_CPP_USER  QX_REGISTER_CPP_IMPORT_DLL

#endif

#endif // EXPORT_H

3

预编译头文件

预编译头文件的作用在于:提高编译速度。换句话说,使用它能够减少项目的编译时间。

QxOrm 使用元编程的概念来提供许多功能,元编程在编译时成本很高,因此使用 precompiled.h 文件可以更快地编译项目:

#ifndef PRECOMPILED_H

#define PRECOMPILED_H

#include 

#include "export.h"

#endif // PRECOMPILED_H

此外,还有一个优点:文件 QxOrm.h 包含了 Qt 和 boost 库的基本功能,因此,不需要再编写像 #include 这样的语句来使用 Qt 的 QString 类;同样地,也不需要编写像#include  这样的语句来使用 boost 库的智能指针。

4

定义 User 类

在 C++ 代码中,User 类对应的是数据库中的 User 表,而类的属性对应的是表中的一个字段(列)。因此,C++ 源代码中的一个 User 类实例对应 User 表中的一条记录(行),这种机制使得 C++ 源代码更易于开发和维护。

为 User 类定义三个属性,id、name 和 age:

#ifndef USER_H

#define USER_H

class USER_DLL_EXPORT User

{

public:

User() : id(0) { }

virtual ~User() { }

long id;

QString name;

int age;

};

QX_REGISTER_HPP_USER(User, qx::trait::no_base_class_defined, 1)

#endif // USER_H

QX_REGISTER_HPP_USER 宏是必须的,用于将 User 类注册到 QxOrm 的上下文中:

参数一:表示要注册的当前类 - User。

参数二:基类,如果没有基类,则使用 qx::trait::no_base_class_defined。

参数三:用于序列化的类版本。

在 user.cpp 文件中,需要实现 qx::register_class(),它是一个设置函数:

#include "precompiled.h"

#include "user.h"

#include 

QX_REGISTER_CPP_USER(User)

namespace qx {

template <> void register_class(QxClass & t){

// 注册 User::id <=> 数据库中的主键

t.id(&User::id, "id");

// 注册 User::name 属性,使用的 key 是 name,version 是 1。

t.data(&User::name, "name", 1);

// 注册 User::age 属性,使用的 key 是 age。

t.data(&User::age, "age");

}

}

和 QX_REGISTER_HPP_USER  相同,QX_REGISTER_CPP_USER 宏也是必需的,用于将 User 类注册到 QxOrm 的上下文中。

5

基本使用

现在,是时候一展身手了。通过 User 类,来了解 QxOrm 中的一些基本操作:

#include "precompiled.h"

#include "user.h"

#include 

int main(int argc, char *argv[]){

QCoreApplication a(argc, argv);

// 初始化参数,用于和数据库交互

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("");

// 在数据库中创建 User 表

QSqlError daoError = qx::dao::create_table();

// 创建 3 个用户

// 可以使用 std 和 Qt 智能指针:std::shared_ptr、QSharedPointer 等...

typedef  QSharedPointer UserPtr;

UserPtr u1;

u1.reset(new User());

u1->name = "Jack Ma";

u1->age = 30;

UserPtr u2;

u2.reset(new User());

u2->name = "Pony";

u2->age = 25;

UserPtr u3;

u3.reset(new User());

u3->name = "Waleon";

u3->age = 18;

// 将所有用户插入容器中

// 可以使用 std、boost、Qt 和 qx::QxCollection 中的许多容器

typedef QVector VectorUser;

VectorUser users;

users.push_back(u1);

users.push_back(u2);

users.push_back(u3);

// 将容器中的所有用户插入到数据库中

// p1、p2、p3 的 id 属性会自动更新

daoError = qx::dao::insert(users);

// 修改第二个用户的信息,并更新到数据库中

u2->name = "Pony modified";

u2->age = 38;

daoError = qx::dao::update(u2);

// 从数据库中删除第一个用户

daoError = qx::dao::delete_by_id(u1);

// 计算用户的数量

long userCount = qx::dao::count();

qDebug() <

// 将 id 为 3 的用户取出,并传给一个新变量

UserPtr userTmp;

userTmp.reset(new User());

userTmp->id = 3;

daoError = qx::dao::fetch_by_id(userTmp);

qDebug() <id <name <age;

#if _QX_SERIALIZE_XML

// 将容器中的用户导出到 XML 文件中(序列化)

qx::serialization::xml::to_file(users, "./export_users.xml");

// 将 XML 中的用户导入至新容器

VectorUser usersXmlTmp;

qx::serialization::xml::from_file(usersXmlTmp, "./export_users.xml");

#endif

#ifndef _QX_NO_JSON

// 将容器中的用户导出到 Json 文件中(序列化)

qx::serialization::json::to_file(users, "./export_users.json");

// 将 Json 文件中的用户导入至新容器

VectorUser usersJsonTmp;

qx::serialization::json::from_file(usersJsonTmp, "./export_users.json");

#endif

// 克隆一个用户

UserPtr uClone = qx::clone_to_qt_shared_ptr(*u1);

qDebug() <id <name <age;

// 按类名(factory)创建新用户

qx::any uAny = qx::create("User");

// 将用户插入到 qx::cache

qx::cache::set("users", users);

// 从 qx::cache 中删除所有元素

qx::cache::clear();

// 内存泄漏

User *user = new User();

return a.exec();

}

这里重点介绍一下 QxOrm_Impl.h,它的作用是检测内存泄露。如果使用 QxMemLeak 模块或 boost::serialization 引擎,应该在所有的 *.cpp 中包含它;否则,它便是可选的(非必须)。

6

程序跟踪

运行程序,除了会打印一系列的输出信息之外,还会生成相应的数据库文件和 JSON 文件。

QxOrm 不会隐藏 SQL 查询(默认情况下,所有的语句都会显示),所以在控制台中可以看到执行过程:

aa81b56110ea5bcc0e3e067585015a11.png

如果要查看数据库 Users.db 的信息,可以使用数据库可视化工具(例如:SQLite Database Browser):

772ce2df4f7ef70588745b0fe684fee3.png

可以看到,User 表中包含了两条记录。一开始我们添加了 3 个用户,但随后删除了 u1(id 为 1)。此外,u2 的 name 和 age 也被更新了。

JSON 文件是通过序列化生成的,打开 export_users.json,将会看到:

21070cec876c95da00934982026cef1a.png

7

最后的话

由于 QxOrm 可以自动对 Entity 对象与数据库中的 Table 进行属性与字段的映射,所以在实际项目中几乎不需要编写数据访问层的代码,这在很大程度上提高了我们的开发效率。

话虽如此,但 QxOrm 不能解决 SQL 和数据库的所有问题(没有一种工具是万能的),所以有时也需要使用 Qt 的 QtSql 引擎来编写自己的 SQL 查询或存储过程。

上面的示例可以说是最简单的入门级程序,希望它能帮助大家更快地学习 QxOrm。如果有什么问题,欢迎随时交流!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值