Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Qt中的持久性类_Sql_Qt_Orm - Fatal编程技术网

Sql Qt中的持久性类

Sql Qt中的持久性类,sql,qt,orm,Sql,Qt,Orm,我正在将一个中型CRUD应用程序从.Net移植到Qt,我正在寻找一种创建持久性类的模式。在.Net中,我通常使用基本方法创建抽象持久性类insert、update、delete、select,例如: public class DAOBase<T> { public T GetByPrimaryKey(object primaryKey) {...} public void DeleteByPrimaryKey(object primaryKey) {...}

我正在将一个中型CRUD应用程序从.Net移植到Qt,我正在寻找一种创建持久性类的模式。在.Net中,我通常使用基本方法创建抽象持久性类insert、update、delete、select,例如:

public class DAOBase<T>
{
    public T GetByPrimaryKey(object primaryKey) {...}

    public void DeleteByPrimaryKey(object primaryKey) {...}

    public List<T> GetByField(string fieldName, object value) {...}

    public void Insert(T dto) {...}

    public void Update(T dto) {...}
}
以及将从UniversalDAO获得的数据转换为适当类型的通用SpecializedDAO:

template<class DTO>
class SpecializedDAO
{
public:
    SpecializedDAO(UniversalDAO *universalDao)
    virtual ~SpecializedDAO() {}

    DTO defaultDto() const { return DTO; }

    void insert(DTO dto) { dao->insert(dto); }
    void update(DTO dto) { dao->update(dto); }
    void remove(DTO dto) { dao->remove(dto); }
    DTO getByPrimaryKey(const QVariant &key);
};
使用上述内容,我声明具体的DAO类如下:

class ClientDAO : public QObject, public SpecializedDAO<ClientDTO>
{
    Q_OBJECT

public:
    ClientDAO(UniversalDAO *dao, QObject *parent = 0) :
        QObject(parent), SpecializedDAO<ClientDTO>(dao)
    {}
};
undefined reference to 
`SpecializedDAO<Address>::getByPrimaryKey(QVariant const&)'
在ClientDAO中,我必须为UniversalDAO设置一些数据库信息。这就是我的实现变得丑陋的原因,因为我这样做:

QMap<QString, QString> fieldMapper;
fieldMapper["client_id"] = "clientId";
fieldMapper["name"] = "firstName";

/* ...all column <-> field pairs in here... */

dao->setFieldMapper(fieldMapper);
dao->setTable("client");
dao->setPrimaryKey("client_id");
我是在构造器中完成的,所以浏览标题的人一眼就看不到。在.Net版本中,很容易发现和理解


你有什么想法可以让我做得更好吗?

据我所知,没有现成的东西可以直接在qt中提供给这个设施。有一些可能的方法

将字段实现为Q_属性,然后通过元类系统反映,并可用于实现通用DAO功能

您仍然可以使用QSqlTableModel,但可以用事务封装写操作,如果事务失败,请从数据库刷新模型。可行性取决于您在模型中保存的数据的大小

我们目前使用基于TableModel/QSqlRecord的方法进行读写,我们的系统中没有ORM映射。我一直在尝试设计一种更通用的方法,但目前我们必须进行的重构工作代价高昂


此链接不是Qt相关的,但对实现模式的一个很好的概述

TEGESOFT最近发布了一个新版本的库,它提供了C++在您的.NET中使用的运行时反身。我认为这将允许你实现你的应用程序,就像你在.NET中所做的一样。

< P>还有一个新的开源ORM C++库:QxOrm基于QtSql Qt模块与数据库通信,并通过boost::serialization将数据序列化为xml和二进制格式。该网站是法语,但快速样例代码和教程代码是英文翻译正在进行…

< P>如果你想要一个ORM,它只依赖于Qt并建立在Qt的元对象系统上,以提供实例化,你可以考虑尝试。在模型级别的基本创建/更新/删除操作之上,它提供了一个模仿django的queryset的queryset模板类,该类允许构建相当复杂的查找。QtScript集成也正在进行中

…还有一个新的Qt-ORM:最新的稳定版本-0.4.2a版本。 QST提供了生成简单SQL查询的机制:选择、插入、删除、取消日期和执行。版本0.4使用T-SQL;默认情况下,新版本0.5将使用PostgreSQL。你会发现,这个ORM基于原始的、不寻常的概念。例如,它与Qt面试系统集成,因此您可以轻松设置视图表示列宽、标题


有0.3和0.4版本的示例项目:TradeDB 0.3和TradeDB 0.4。TradeDB 0.4对于开始学习QST应该是有用的。

这似乎是一种很好的技术。然而,我在让我的原型编译n链接时遇到了一些问题

在您描述和调用DAO类以检索我的一个DB常驻对象的实例时,我已经实现了这些基础知识

以下是调用这些模型类的语句:

    _db = <create QSqlDatabase>;

    dao = new UniversalDAO (_db);

    AddressDAO * aDAO = new AddressDAO (dao);
    Address addr = aDAO->getByPrimaryKey(QVariant(1));
在UniversalDAO.cpp中:

void
UniversalDAO::getByPrimaryKey (QObject & dto, const QVariant & key)
{
    <retrieve properties from 'dto' n build up QSqlQuery>
    <execute QSqlQuery 'SELECT...' to retrieve record>
    <call dto.setProperty() on all fields>
}

当前一个悬而未决的问题是在我的DTO类中为属性类型使用用户定义的类型。我尝试使用std::string与QString,但无论我尝试了什么Q_DECLARE_METATYPEstd::string、qRegisterMetaType等,似乎都不起作用。。。。必须恢复到基于Qt的类型。bummer…

这看起来很有希望,但如果我能用纯Qt解决问题,我不想把boost作为依赖项。以您的提示和链接为起点,我已经发布了解决方案的实现。请告诉我你是怎么想的。
template<class Address>
Address SpecializedDAO<Address>::getByPrimaryKey(const QVariant &key)
{ }
undefined reference to 
`SpecializedDAO<Address>::getByPrimaryKey(QVariant const&)'
template<class DTO>
DTO  SpecializedDAO<DTO>::getByPrimaryKey(const QVariant &key)
        throw (FlowException)
{
    DTO obj;
    dao->getByPrimaryKey(static_cast<QObject &> (obj), key);
    return obj;
}
void
UniversalDAO::getByPrimaryKey (QObject & dto, const QVariant & key)
{
    <retrieve properties from 'dto' n build up QSqlQuery>
    <execute QSqlQuery 'SELECT...' to retrieve record>
    <call dto.setProperty() on all fields>
}