sql – Qt中的持久化类

前端之家收集整理的这篇文章主要介绍了sql – Qt中的持久化类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在将一个中等大小的CRUD应用程序从.Net移植到Qt,我正在寻找一种创建持久化类的模式.在.Net中,我通常使用基本方法(插入,更新,删除,选择)创建抽象持久化类,例如:
  1. public class DAOBase<T>
  2. {
  3. public T GetByPrimaryKey(object primaryKey) {...}
  4.  
  5. public void DeleteByPrimaryKey(object primaryKey) {...}
  6.  
  7. public List<T> GetByField(string fieldName,object value) {...}
  8.  
  9. public void Insert(T dto) {...}
  10.  
  11. public void Update(T dto) {...}
  12. }

然后,我将其子类化为特定的表/ DTO并添加了DB表布局的属性

  1. [DBTable("note","note_id",NpgsqlTypes.NpgsqlDbType.Integer)]
  2. [DbField("note_id",NpgsqlTypes.NpgsqlDbType.Integer,"NoteId")]
  3. [DbField("client_id","ClientId")]
  4. [DbField("title",NpgsqlTypes.NpgsqlDbType.Text,"Title","")]
  5. [DbField("body","Body","")]
  6. [DbField("date_added",NpgsqlTypes.NpgsqlDbType.Date,"DateAdded")]
  7. class NoteDAO : DAOBase<NoteDTO>
  8. {
  9. }

感谢.Net反射系统,我能够实现繁重的代码重用并轻松创建新的ORM.

在Qt中执行此类操作的最简单方法似乎是使用Qtsql模块中的模型类.不幸的是,在我的情况下,它们提供了太抽象的界面.我至少需要事务支持和控制QsqlTableModel不提供的单个提交.

你能给我一些关于用Qt解决这个问题的提示或者给我一些参考资料吗?

更新:

基于Harald的线索,我实现了一个与上面的.Net类非常相似的解决方案.现在我有两节课.

UniversalDAO继承QObject并使用元数据系统处理QObject DTO:

  1. class UniversalDAO : public QObject
  2. {
  3. Q_OBJECT
  4.  
  5. public:
  6. UniversalDAO(QsqlDatabase dataBase,QObject *parent = 0);
  7. virtual ~UniversalDAO();
  8.  
  9. void insert(const QObject &dto);
  10. void update(const QObject &dto);
  11. void remove(const QObject &dto);
  12. void getByPrimaryKey(QObject &dto,const QVariant &key);
  13. };

还有一个通用的SpecializedDAO,它将从UniversalDAO获得的数据转换为适当的类型:

  1. template<class DTO>
  2. class SpecializedDAO
  3. {
  4. public:
  5. SpecializedDAO(UniversalDAO *universalDao)
  6. virtual ~SpecializedDAO() {}
  7.  
  8. DTO defaultDto() const { return DTO; }
  9.  
  10. void insert(DTO dto) { dao->insert(dto); }
  11. void update(DTO dto) { dao->update(dto); }
  12. void remove(DTO dto) { dao->remove(dto); }
  13. DTO getByPrimaryKey(const QVariant &key);
  14. };

使用上面的内容,我将具体的DAO类声明如下:

  1. class ClientDAO : public QObject,public SpecializedDAO<ClientDTO>
  2. {
  3. Q_OBJECT
  4.  
  5. public:
  6. ClientDAO(UniversalDAO *dao,QObject *parent = 0) :
  7. QObject(parent),SpecializedDAO<ClientDTO>(dao)
  8. {}
  9. };

在ClientDAO中,我必须为UniversalDAO设置一些数据库信息.这就是我的实现变得丑陋的地方,因为我这样做:

  1. QMap<QString,QString> fieldMapper;
  2. fieldMapper["client_id"] = "clientId";
  3. fieldMapper["name"] = "firstName";
  4.  
  5. /* ...all column <-> field pairs in here... */
  6.  
  7. dao->setFieldMapper(fieldMapper);
  8. dao->setTable("client");
  9. dao->setPrimaryKey("client_id");

我在构造函数中执行此操作,因此对于浏览标题的人来说,第一眼看不到它.在.Net版本中,很容易发现和理解.

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

解决方法

据我所知,没有任何现成的东西直接在qt给这个设施.有一些可能的方法.

>将字段实现为Q_PROPERTY,然后通过Metaclass系统反映,并可用于实现通用DAO功能
>您仍然可以使用QsqlTableModel但使用事务封装写入,如果事务失败,则从DB刷新模型.可行性取决于您在模型中保存的数据的大小.

我们目前使用基于TableModel / QsqlRecord的方法进行读写,我们的系统中没有完成ORM映射.我一直在努力设计一种更通用的方法,但我们为实现目标而必须做的重构工作目前是昂贵的.

链接http://giorgiosironi.blogspot.com/2009/08/10-orm-patterns-components-of-object.html与Qt无关,但对实现模式有很好的概述

猜你在找的MsSQL相关文章