QxOrm的使用-数据操作
上一篇我们讲了QxOrm的基本的数据映射操作,这里面再补充一点东西
● 数据类型映射
Qt/C++类型 | 数据库类型 |
bool | SMALLINT |
qx_bool | SMALLINT |
short | SMALLINT |
int | INTEGER |
long | INTEGER |
long long | INTEGER |
float | FLOAT |
double | FLOAT |
long double | FLOAT |
unsigned short | SMALLINT |
unsigned int | INTEGER |
unsigned long | INTEGER |
unsigned long long | INTEGER |
std::string | TEXT |
std::wstring | TEXT |
QString | TEXT |
QVariant | TEXT |
QUuid | TEXT |
QDate | DATE |
QTime | TIME |
QDateTime | TIMESTAMP |
QByteArray | BLOB |
qx::QxDateNeutral | TEXT |
qx::QxTimeNeutral | TEXT |
qx::QxDateTimeNeutral | TEXT |
● 注册瞬态数据成员
我们以person为例子
person.h
#ifndef QXORMDEMO_PERSON_H #define QXORMDEMO_PERSON_H #include "precompiled.h" #include "export.h" #include <QDateTime> class person { public: long id; QString firstName; QString lastName; QDateTime birthDate; int age; }; QX_REGISTER_HPP_APP(person, qx::trait::no_base_class_defined, 0) #endif //QXORMDEMO_PERSON_H
person.cpp
#include "person.h" QX_REGISTER_CPP_APP(person) namespace qx { template <> void register_class(QxClass<person> & t) { t.setName("t_person"); t.id(& person::id, "id"); t.data(& person::firstName, "first_name"); t.data(& person::lastName, "last_name"); t.data(& person::birthDate, "birth_date"); // 注册瞬态数据成员,一下两种二选一: // t.data(& person::age, "age", 0, true, false); IxDataMember * pDataMember = t.data(& person::age, "age"); pDataMember->setDao(false); } }
使用该方法可以看到数据库内没有生成age字段,但是类内是有该字段的。
瞬态数据成员是为了方便序列化或者自检等。
● 数据库的连接
在main函数内看到的以下代码:
qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE"); qx::QxSqlDatabase::getSingleton()->setDatabaseName("./demo.db"); qx::QxSqlDatabase::getSingleton()->setHostName("localhost"); qx::QxSqlDatabase::getSingleton()->setUserName("root"); qx::QxSqlDatabase::getSingleton()->setPassword("");
该段代码是使用QxSqlDatabase内的单例类来连接数据库的,该方式是跨线程的。其他方式暂且不介绍,如果有需要则到官网查看。
使用QxOrm对数据库进行增删改查
接下来我们使用person类来做基本的增删改查操作,QxOrm提供了多种函数,这里只介绍最基本的,如果你想深入学习,可以到源码中去查看QxOrm的文档
新增数据
main.cpp
#include <QApplication> #include "precompiled.h" #include "person.h" #include "author.h" #include "author2.h" #include "turbo_log.h" void databaseInit() { qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE"); qx::QxSqlDatabase::getSingleton()->setDatabaseName("./demo.db"); qx::QxSqlDatabase::getSingleton()->setHostName("localhost"); qx::QxSqlDatabase::getSingleton()->setUserName("root"); qx::QxSqlDatabase::getSingleton()->setPassword(""); } void createTable() { QSqlError daoError = qx::dao::create_table<person>(); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("Table person:" + daoError.text().toStdString()); } daoError = qx::dao::create_table<author>(); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("Table author:" + daoError.text().toStdString()); } daoError = qx::dao::create_table<author2>(); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("Table author2:" + daoError.text().toStdString()); } } void insertData() { person p; p.firstName = "张三"; p.lastName = "张三2"; p.birthDate = QDateTime::fromString("1996-04-25", "yyyy-MM-dd"); p.age = 23; QSqlError daoError = qx::dao::insert(p); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("insert person:" + daoError.text().toStdString()); } person p2; p2.firstName = "李四"; p2.lastName = "李四2"; p2.birthDate = QDateTime::fromString("1996-04-25", "yyyy-MM-dd"); p2.age = 23; daoError = qx::dao::save(p2); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("save person:" + daoError.text().toStdString()); } } int main(int argc, char **argv) { QApplication app(argc, argv); databaseInit(); insertData(); return app.exec(); }
我们在main函数中执行插入, qx::dao::save 和 qx::dao::insert都可以进行插入,区别在于如果save的数据的id是存在的则修改数据。
如果你想测试对应的数据,则给person设置id之后执行save和insert就可以看出区别。
person p; p.id = 1; p.firstName = "王二麻"; p.lastName = "王二麻2"; p.birthDate = QDateTime::fromString("1996-04-25", "yyyy-MM-dd"); p.age = 23; QSqlError daoError = qx::dao::save(p); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("insert person:" + daoError.text().toStdString()); }
删除数据
QxOrm提供了如下函数删除数据
qx::dao::delete_by_query qx::dao::delete_by_id qx::dao::delete_all qx::dao::destory_by_query qx::dao::destory_by_id qx::dao::destory_all
如果没有定义软删除的话 destory和delete都是把数据删除了。
void deleteData() { person p; qx_query query; query.where("id").isEqualTo(2); QSqlError daoError = qx::dao::delete_by_query<person>(query); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("delete persons:" + daoError.text().toStdString()); } qx_query query2; query2.where("id").isEqualTo(1); daoError = qx::dao::destroy_by_query<person>(query2); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("delete persons:" + daoError.text().toStdString()); } }
如果定义了软删除行为的话。
person.h
#ifndef QXORMDEMO_PERSON_H #define QXORMDEMO_PERSON_H #include "precompiled.h" #include "export.h" #include <QDateTime> class person { public: long id; QString firstName; QString lastName; QDateTime birthDate; QDateTime deleteData; int age; }; QX_REGISTER_HPP_APP(person, qx::trait::no_base_class_defined, 0) #endif //QXORMDEMO_PERSON_H
person.cpp
#include "person.h" QX_REGISTER_CPP_APP(person) namespace qx { template <> void register_class(QxClass<person> & t) { t.setName("t_person"); t.id(& person::id, "id"); t.data(& person::firstName, "first_name"); t.data(& person::lastName, "last_name"); t.data(& person::birthDate, "birth_date"); // t.data(& person::age, "age", 0, true, false); IxDataMember * pDataMember = t.data(& person::age, "age"); pDataMember->setDao(false); t.setSoftDelete(qx::QxSoftDelete("deleteData")); } }
使用delete 数据不会被实际删除。
main.cpp
void deleteData() { QSqlError daoError = qx::dao::delete_all<person>(); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("delete persons:" + daoError.text().toStdString()); } }
使用destory 数据会被实际删除。
void deleteData() { QSqlError daoError = qx::dao::destroy_all<person>(); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("delete persons:" + daoError.text().toStdString()); } }
最后by_id的用法和查找的那个by_id是一致的,我这里不再贴代码了。
修改数据
使用qx::dao::update 更新数据库数据,注意:未赋值的字段将被更新为默认值或者空,此操作需要将字段赋值全
person p; p.id = 3; p.firstName = "王五"; p.lastName = "王五2"; p.birthDate = QDateTime::fromString("1996-04-25", "yyyy-MM-dd"); p.age = 23; QSqlError daoError = qx::dao::update(p); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("insert update:" + daoError.text().toStdString()); }
QxOrm提供了一种脏模式更新数据库qx::dao::update_optimized但是不建议使用。
查询数据
上面修改的时候,如果你的数据不全则更新的字段也会出问题,最好的方式是线查询出来再更新某个字段。
我们可以使用qx::dao::fetch_all查询全部数据。
void selectData() { QList<person> persons; QSqlError daoError = qx::dao::fetch_all(persons); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("select persons:" + daoError.text().toStdString()); } TurboLog::instance().getConsoleLogger()->info("persons: {}", persons.size()); }
可以打印出总数据数量为4;
同样的我们可以使用qx::dao::fetch_by_id 精确查询某条数据。
void selectData() { person p; p.id = 3; QSqlError daoError = qx::dao::fetch_by_id(p); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("select persons:" + daoError.text().toStdString()); } TurboLog::instance().getConsoleLogger()->info("persons: {}", p.firstName.toStdString()); }
可以打印出总数据数量为p.firstName为王五;
同样的我们可以使用qx::dao::fetch_by_query 按照自己想要的条件搜索
mvoid selectData() { person p; qx_query query; query.where("id").isEqualTo(2); QSqlError daoError = qx::dao::fetch_by_query(query, p); if (daoError.type() != QSqlError::NoError) { TurboLog::instance().getConsoleLogger()->error("select persons:" + daoError.text().toStdString()); } TurboLog::instance().getConsoleLogger()->info("persons: {}", p.firstName.toStdString()); }
可以打印出总数据数量为p.firstName为张三;