QT C++数据库ORM 使用QxOrm框架并使用泛型编程 (二)

上一篇 windows下静态使用QxOrm框架并使用泛型编程 (一)

这篇开始讲实际编程并且抽象化,让代码书写更少。

为了模块划分我在Demo文件夹下新增了一个SQLModule文件夹,在此文件夹下又新增QxHandler,QxMapped,QxObject三个文件夹,QxObject是用来存储数据对象类的一个文件夹,QxMapped是存储键值映射的文件夹,QxHandler是操作数据库的实际句柄类文件夹。


QxObject类

User.h

#ifndef USER_H

#define USER_H

#include "common.h"

#include <QxOrm.h>

#include <QJsonObject>

class User

{

    QX_REGISTER_FRIEND_CLASS(User)        //用于将类注册到QxOrm的宏定义

public:

    User();

    long getId();

    QString getName();

    int    getAge();

public:

    QJsonObject toJsonObject();

    bool analyzeJson(QByteArray &json);

    void analyzeJson(QJsonObject &json);

private:

    long    m_lId;

    QString m_sName;

    int    m_nAge;

};

//QX_REGISTER_PRIMARY_KEY(User, int)  //主键不是整数类型的时候使用

QX_REGISTER_HPP_IMPORT_DLL(User, qx::trait::no_base_class_defined, DATABASE_VERSION)   //用于将类注册到QxOrm的宏定义  第一个参数为类名 第二个为默认值 第三个为数据库版本

#endif // USER_H

User.cpp

#include "User.h"

QX_REGISTER_CPP_IMPORT_DLL(User)  //用于将类注册到QxOrm的宏定义

namespace qx  //用于将类注册到QxOrm的方法 

{

    template <> void register_class(QxClass<User> & t)

    {

        qx::IxDataMember * pData = NULL; Q_UNUSED(pData);

        qx::IxSqlRelation * pRelation = NULL; Q_UNUSED(pRelation);

        qx::IxFunction * pFct = NULL; Q_UNUSED(pFct);

        qx::IxValidator * pValidator = NULL; Q_UNUSED(pValidator);

        // Register

        pData =t.id(& User::m_lId, "id",DATABASE_VERSION);

        pData =t.data(& User::m_nAge, "name",DATABASE_VERSION);

        pData =t.data(& User::m_nAge, "age",DATABASE_VERSION);

        qx::QxValidatorX<User> * pAllValidator = t.getAllValidator(); Q_UNUSED(pAllValidator);

    }

}

User::User()

    :m_lId(0)

    ,m_sName("")

    ,m_nAge(0)

{

}

long User::getId()

{

    return m_lId;

}

QString User::getName()

{

    return m_sName;

}

int User::getAge()

{

    return m_nAge;

}

QJsonObject User::toJsonObject()

{

    QJsonObject subObject;

    subObject.insert("Name",m_sName);

    subObject.insert("Age",m_nAge);

    return subObject;

}

bool User::analyzeJson(QByteArray &json)

{

    bool success=false;

    QJsonParseError error;

    QJsonDocument document=QJsonDocument::fromJson(json,&error);

    if (!document.isNull() && (error.error == QJsonParseError::NoError))

    {

        QJsonObject rootObject =document.object();

        this->analyzeJson(rootObject);

        success=true;

    }

    else

    {

        success=false;

        qDebug()<<error.error;

        qDebug("LockoutFun analyze falied");

    }

    return success;

}

void User::analyzeJson(QJsonObject &json)

{

    QJsonObject rootObject = json.value("User").toObject();

    m_sName=rootObject.value(QString("Name")).toString();

    m_nAge=rootObject.value(QString("Age")).toInt();

}


QxMapped

IMapped 映射抽象类

#ifndef IMAPPED_H

#define IMAPPED_H

/**

* @author tianmin

* @brief The IMapped class 抽象出来的映射类

* @date 2019-07-22

*/

#include <QStringList>

#include <QString>

#include <QMap>

class IMapped

{

public:

    //字符map初始化

    virtual void initMapped() = 0;

    //获取QString列表

    virtual QStringList getListMapped(int en) =0;

    //获取QString 字段

    virtual QString getMapped(int en)  = 0;

    virtual ~IMapped(){}

};

#endif // IMAPPED_H

UserMapped 实际使用的类  

UserMapped .h

#ifndef USERMAPPED_H

#define USERMAPPED_H

#include "IMapped.h"

namespace USER {

enum USER_MAPPED

{

    EN_ID          = 0x00000001,

    EN_NAME        = 0x00000002,

    EN_AGE          = 0x00000004,

    EN_ALL          = 0xFFFFFFFF

};

}

class UserMapped:public IMapped

{

public:

    UserMapped();

    virtual ~UserMapped();

public:

    virtual void initMapped();

    virtual QStringList getListMapped(int en);

    virtual QString getMapped(int en);

private:

    QMap<int,QString> m_map;

};

#endif // USERMAPPED_H

UserMapped.cpp

#include "UserMapped.h"

UserMapped::UserMapped()

{

}

UserMapped::~UserMapped()

{

}

void UserMapped::initMapped()

{

    m_map.clear();

    m_map.insert(USER::EN_ID, "id");

    m_map.insert(USER::EN_NAME ,"name");

    m_map.insert(USER::EN_AGE ,"age");

}

QStringList UserMapped::getListMapped(int en)

{

    QStringList temp;

    QString str;

    QMap<int,QString>::iterator i;

    for (i = m_map.begin(); i != m_map.end(); ++i)

    {

        if(en&(i.key()))

        {

          str=i.value();

          temp.append(str);

          str.clear();

        }

    }

    return temp;

}

QString UserMapped::getMapped(int en)

{

    QString str;

    QMap<int,QString>::iterator i;

    for (i = m_map.begin(); i != m_map.end(); ++i)

    {

        if(en==i.key())

        {

          str =i.value();

          return str;

        }

    }

    return QString();

}


QxHandler

IHandler 抽象化的类模板  

这里只抽象了部分方法 还有save 和事务以及关系的方法未抽象完成

#ifndef IHANDLER_H

#define IHANDLER_H

#include <QxOrm.h>

#include <QMutexLocker>

#include <QMutex>

#include <QtSql/QSqlDatabase>

#include <QtSql/QSqlError>

/**

* @brief The ISqlInterface class 数据库操作的抽象方法类  并且模板化减少代码的繁杂

*/

class ISqlInterface

{

public:

    ISqlInterface(){}

    virtual ~ISqlInterface(){}

    //数据库连接初始化

protected:

    virtual void initSqlconnect()=0;

    //建表

    virtual bool createTable()=0;

    //断开连接

    virtual void disconnect()=0;

};

template<class T,class T2,class T3>

class IHandler

{

public:

    IHandler(){}

    virtual ~IHandler(){}

    virtual bool createTable(QSqlDatabase &m_SqlDatabase)

    {

        QSqlError error= qx::dao::create_table<T3>(&m_SqlDatabase);

        return !error.isValid();

    }

    virtual bool insert(T &t,QMutex &m_Mutex,QSqlDatabase &m_SqlDatabase)

    {

        QMutexLocker locker(&m_Mutex);

        if(!m_SqlDatabase.isOpen())

            return false;

        if(qx::dao::exist(t,&m_SqlDatabase).getValue()!=false)

            return false;

        QSqlError error= qx::dao::insert(t,&m_SqlDatabase);

        return !error.isValid();

    }

    virtual bool deleteObject(T &t,QMutex &m_Mutex,QSqlDatabase &m_SqlDatabase,bool isDestroy)

    {

        QMutexLocker locker(&m_Mutex);

        if(!m_SqlDatabase.isOpen())

            return false;

        QSqlError error;

        if(qx::dao::exist(t,&m_SqlDatabase).getValue()==false)

            return false;

        if(isDestroy==false)

        {

            error= qx::dao::delete_by_id(t,&m_SqlDatabase);

        }

        else

        {

            error= qx::dao::destroy_by_id(t,&m_SqlDatabase);

        }

        return !error.isValid();

    }

    virtual bool update(T &t,QMutex &m_Mutex,QSqlDatabase &m_SqlDatabase,QStringList &list)

    {

        QMutexLocker locker(&m_Mutex);

        if(!m_SqlDatabase.isOpen())

            return false;

        if(qx::dao::exist(t,&m_SqlDatabase).getValue()==false)

            return false;

        QSqlError error= qx::dao::update(t,&m_SqlDatabase,list);

        return !error.isValid();

    }

    virtual bool select(T &t,QMutex &m_Mutex,QSqlDatabase &m_SqlDatabase,QStringList &list)

    {

        QMutexLocker locker(&m_Mutex);

        if(!m_SqlDatabase.isOpen())

            return false;

        QSqlError error;

        if(qx::dao::exist(t,&m_SqlDatabase).getValue()==false)

            return false;

        error= qx::dao::fetch_by_id(t,&m_SqlDatabase,list);

        return !error.isValid();

    }

    virtual bool selectByQuery(T2 &t,QMutex &m_Mutex,QSqlDatabase &m_SqlDatabase,qx::QxSqlQuery &query,QStringList &list)

    {

        QMutexLocker locker(&m_Mutex);

        if(!m_SqlDatabase.isOpen())

            return false;

        QSqlError error=qx::dao::fetch_by_query(query,t,&m_SqlDatabase,list);

        return !error.isValid();

    }

};

#endif // IHANDLER_H

UserHandler 实际操作句柄类

UserHandler.h

#ifndef USERHANDLER_H

#define USERHANDLER_H

#include <QxOrm.h>

#include <QString>

#include <QMutexLocker>

#include <QMutex>

#include <QtSql/QSqlDatabase>

#include <QtSql/QSqlError>

#include "IHandler.h"

#include "SQLModule/QxMapped/UserMapped.h"

#include "SQLModule/QxObject/User.h"

namespace USER

{

const QString DATABASE_TYPE="QSQLITE";

const QString CONNECT_NAME="USER_CONNECTED";

const QString DATABASENAME="C:/Users/we/Desktop/workTools/demo/qxorm.db";

const QString HOSTNAME="localhost";

const QString USERNAME="root";

const QString PASSWORD="";

}

using namespace USER;

class User;                                                //OBJECT 类

typedef QSharedPointer<User> Shared_User;                  //User类智能指针

typedef QList<Shared_User> List_User;                      //User类数组

typedef qx::QxCollection<int,Shared_User> Collection_User;  //User容器

class UserHandler:public IHandler<Shared_User,Collection_User,User> ,public ISqlInterface

{

public:

    UserHandler();

    virtual ~UserHandler();

    /**

    * @brief insert            插入数据至数据库

    * @param t                插入的单条数据 不需要指定ID值 自增

    * @return                  0失败 1成功

    */

    bool insert(Shared_User &t);

    /**

    * @brief deleteObject      从数据库中删除指定数据

    * @param t                删除的单条数据 需要指定ID值

    * @param isDestroy        是否软删除

    * @return                  0失败 1成功

    */

    bool deleteObject(Shared_User &t,bool isDestroy=false);

    /**

    * @brief update            根据ID值更新数据

    * @param t                数据

    * @param en                更新字段的映射值

    * @return                  0失败 1成功

    */

    bool update(Shared_User &t,int en=EN_ALL);

    /**

    * @brief select            根据ID值查询数据

    * @param t                数据

    * @param en                映射值

    * @return                  0失败 1成功

    */

    bool select(Shared_User &t,int en=EN_ALL);

    /**

    * @brief selectByQuery    根据搜寻条件查找

    * @param t                数据集合

    * @param query            搜寻语句

    * @param en                数据库列映射值

    * @return                  0失败 1成功

    */

    bool selectByQuery(Collection_User &t,qx::QxSqlQuery &query,int en=EN_ALL);

protected:

    virtual void initSqlconnect();

    virtual bool createTable();

    virtual void disconnect();

private:

    UserMapped m_Mapped;

    QMutex m_Mutex;

    QSqlDatabase m_SqlDatabase;

};

#endif // USERHANDLER_H

UserHandler.cpp

#include "UserHandler.h"

UserHandler::UserHandler()

{

    initSqlconnect();

    createTable();

}

UserHandler::~UserHandler()

{

    disconnect();

}

void UserHandler::initSqlconnect()

{

    QMutexLocker locker(&m_Mutex);

    if(QSqlDatabase::contains(CONNECT_NAME))

        m_SqlDatabase = QSqlDatabase::database(CONNECT_NAME);

    else

        m_SqlDatabase= QSqlDatabase::addDatabase(DATABASE_TYPE,CONNECT_NAME);

    m_SqlDatabase.setDatabaseName(DATABASENAME);

    m_SqlDatabase.setHostName(HOSTNAME);

    m_SqlDatabase.setUserName(USERNAME);

    m_SqlDatabase.setPassword(PASSWORD);

    m_SqlDatabase.open();

}

bool UserHandler::createTable()

{

    return IHandler<Shared_User,Collection_User,User>::createTable(m_SqlDatabase);

}

void UserHandler::disconnect()

{

    QMutexLocker locker(&m_Mutex);

    if(m_SqlDatabase.isOpen())

        m_SqlDatabase.close();

    QSqlDatabase::removeDatabase(CONNECT_NAME);

}

bool UserHandler::insert(Shared_User &t)

{

    return IHandler<Shared_User,Collection_User,User>::insert(t,m_Mutex,m_SqlDatabase);

}

bool UserHandler::deleteObject(Shared_User &t,bool isDestroy)

{

    return IHandler<Shared_User,Collection_User,User>::deleteObject(t,m_Mutex,m_SqlDatabase,isDestroy);

}

bool UserHandler::update(Shared_User &t, int en)

{

    QStringList list= m_Mapped.getListMapped(en);

    return IHandler<Shared_User,Collection_User,User>::update(t,m_Mutex,m_SqlDatabase,list);

}

bool UserHandler::select(Shared_User &t, int en)

{

    QStringList list= m_Mapped.getListMapped(en);

    return IHandler<Shared_User,Collection_User,User>::select(t,m_Mutex,m_SqlDatabase,list);

}

bool UserHandler::selectByQuery(Collection_User &t,qx::QxSqlQuery &query,int en)

{

    QStringList list= m_Mapped.getListMapped(en);

    return IHandler<Shared_User,Collection_User,User>::selectByQuery(t,m_Mutex,m_SqlDatabase,query,list);

}



下一篇讲如何整合所有表,并且升级数据库的方法。

下一篇windows下静态使用QxOrm框架并使用泛型编程 (三)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265