之前介绍了纯使用QxOrm的增删改查,接下来介绍使用QxOrm来执行sql语句。这部分也是有必要的。
QxOrm一共提供了1个类2个方法来执行sql语句
qx::QxSqlQuery // 类 qx_query ;
qx::dao::execute_query() // 方法 ;
qx::dao::call_query() // 方法.
有两种方式使用qx::QxSqlQuery
void selectData()
{
qx::QxSqlQuery query("WHERE t_person.first_name = :first_name");
query.bind(":first_name", "王五");
QList<person> persons;
QSqlError daoError = qx::dao::fetch_by_query(query, persons);
TurboLog::instance().getConsoleLogger()->error("select table:{}", persons.size());
}
这个里面是使用sql查询sql表,省去了select * from的那个部分,实际生成的sql不会有* 都是按字段生成的。
void selectData()
{
qx::QxSqlQuery query("WHERE t_person.first_name = :first_name");
query.bind(":first_name", "王五");
QList<person> persons;
QSqlError daoError = qx::dao::fetch_by_query(query, persons);
TurboLog::instance().getConsoleLogger()->error("select table:{}", persons.size());
qx_query query1;
query1.where("first_name").isEqualTo("王五");
QList<person> persons1;
daoError = qx::dao::fetch_by_query(query1, persons1);
TurboLog::instance().getConsoleLogger()->error("select table:{}", persons1.size());
}
这个是在上面的基础上使用了C++的方式查询,两次结果一致。
当然这种方式还支持其他的过滤条件,代码如下:
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);
你可以更换成自己的表字段去尝试不同的查找条件,我这里就不一一列举。
第一种方式除了:以外,QxOrm 库还提供 3 种样式来编写 SQL 参数。
下面的方法是所有的QxOrm可以执行qx::QxSqlQuery的方法。
// with functions into namespace qx::dao
qx::dao::count<T>()
qx::dao::fetch_by_query<T>()
qx::dao::update_by_query<T>()
qx::dao::delete_by_query<T>()
qx::dao::destroy_by_query<T>()
qx::dao::fetch_by_query_with_relation<T>()
qx::dao::fetch_by_query_with_all_relation<T>()
qx::dao::update_by_query_with_relation<T>()
qx::dao::update_by_query_with_all_relation<T>()
qx::dao::update_optimized_by_query<T>()
// with qx::QxSession class
qx::QxSession::count<T>()
qx::QxSession::fetchByQuery<T>()
qx::QxSession::update<T>()
qx::QxSession::deleteByQuery<T>()
qx::QxSession::destroyByQuery<T>()
// with qx::QxRepository<T> class
qx::QxRepository<T>::count()
qx::QxRepository<T>::fetchByQuery()
qx::QxRepository<T>::update()
qx::QxRepository<T>::deleteByQuery()
qx::QxRepository<T>::destroyByQuery()
上面是使用不完全的sql,如何执行自己写的sql语句呢?
接下来的两种方式是执行自己的sql语句或者是存储过程。
void selectData()
{
QList<person> persons;
qx_query testStoredProcBis("SELECT * FROM t_person");
QSqlError daoError = qx::dao::execute_query(testStoredProcBis, persons);
TurboLog::instance().getConsoleLogger()->error("select table:{}", persons.size());
qx::dump(persons);
qx::serialization::json::to_file(persons, "persons.json");
}
qx::serialization::json::to_file(persons, “persons.json”); 序列化到json文件函数。dump内执行的就是这个函数。
可以看到对应的表的json输出。
sqlite不支持存储过程,因此这个需要换用mysql进行测试。
创建存储过程
delimiter $$
create procedure bb(in aa varchar(20),out cid varchar(20))
begin
select t_person.id into cid
from t_person
where t_person.first_name=aa;
end $$
delimiter ;
执行一下代码即可,不过这个地方的boundValue函数我是没咋看懂,欢迎懂的小伙伴告诉我一下这个怎么用。
void selectData()
{
QList<person> persons;
qx_query query("CALL bb(:param1, :param2)");
query.bind(":param1", "王五");
query.bind(":param2", 5024, QSql::InOut);
QSqlError daoError = qx::dao::call_query(query);
QVariant vNewValue = query.boundValue(":param2");
TurboLog::instance().getConsoleLogger()->error("call_query update: {}", vNewValue.toInt());
}
main.cpp
#include <QApplication>
#include <QSqlDatabase>
#include <QMessageBox>
#include "precompiled.h"
#include "person.h"
#include "author.h"
#include "author2.h"
#include "turbo_log.h"
void databaseInit()
{
qx::QxSqlDatabase::getSingleton()->setDriverName("QMYSQL");
qx::QxSqlDatabase::getSingleton()->setHostName("192.168.0.84");
qx::QxSqlDatabase::getSingleton()->setPort(3306);
qx::QxSqlDatabase::getSingleton()->setDatabaseName("qttest");
qx::QxSqlDatabase::getSingleton()->setUserName("root");
qx::QxSqlDatabase::getSingleton()->setPassword("123");
}
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);
daoError = qx::dao::insert(p);
daoError = qx::dao::insert(p);
daoError = qx::dao::insert(p);
daoError = qx::dao::insert(p);
if (daoError.type() != QSqlError::NoError)
{
TurboLog::instance().getConsoleLogger()->error("insert update:" + daoError.text().toStdString());
}
}
void selectData()
{
QList<person> persons;
qx_query query("CALL bb(:param1, :param2)");
query.bind(":param1", "王五");
query.bind(":param2", "@aa", QSql::Out);
QSqlError daoError = qx::dao::call_query(query);
QVariant vNewValue = query.boundValue(1);
TurboLog::instance().getConsoleLogger()->error("call_query update: {}", vNewValue.toString().toStdString());
}
void deleteData()
{
QSqlError daoError = qx::dao::destroy_all<person>();
if (daoError.type() != QSqlError::NoError)
{
TurboLog::instance().getConsoleLogger()->error("delete persons:" + daoError.text().toStdString());
}
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
databaseInit();
// insertData();
selectData();
// deleteData();
return app.exec();
}
连接的地方需要修改成mysql的,当然有可能你的qt不支持mysql的连接,这个时候就需要编译mysql的驱动来连接mysql。最新版的mysql驱动编译完成之后还要加上openssl的动态库,否则会一直显示driver not load,只要将
libcrypto-1_1-x64.dll
libssl-1_1-x64.dll
拷贝到工程目录下即可
这边的使用sql语句就介绍到这里,有不明白的小伙伴欢迎提问。