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