上一篇我们讲了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
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内的单例类来连接数据库的,该方式是跨线程的。其他方式暂且不介绍,如果有需要则到官网查看。
接下来我们使用person类来做基本的增删改查操作,QxOrm提供了多种函数,这里只介绍最基本的,如果你想深入学习,可以到源码中去查看QxOrm的文档
main.cpp
#include
#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
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 按照自己想要的条件搜索
void 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为张三;