为ormc+实现1到n映射+; 我正在编写一个项目,我需要在C++中实现一个精简版的ORM解决方案。我在为同样的目标实现1-n关系时感到震惊
例如,如果以下是类:为ormc+实现1到n映射+; 我正在编写一个项目,我需要在C++中实现一个精简版的ORM解决方案。我在为同样的目标实现1-n关系时感到震惊,c++,orm,mapping,C++,Orm,Mapping,例如,如果以下是类: class A { ... } class B { ... std::list<A> _a_list; ... } A类 { ... } B类 { ... 标准::列表_a_列表; ... } 我提供了加载/保存到数据库的加载/保存方法。 现在,如果我以B为例,并采用以下工作流: 从列表中删除1个条目 修改了列表中的1个条目 1个条目添加到_a_列表中 现在,我需要使用类似“b.save()”的东西来更新数据库。 那么,
class A
{
...
}
class B
{
...
std::list<A> _a_list;
...
}
A类
{
...
}
B类
{
...
标准::列表_a_列表;
...
}
我提供了加载/保存到数据库的加载/保存方法。
现在,如果我以B为例,并采用以下工作流:
- 从列表中删除1个条目
- 修改了列表中的1个条目
- 1个条目添加到_a_列表中
那么,保存更改的最佳方法是什么,即识别添加、删除和更新到_a_列表。一种策略是使用枚举来表示记录的“状态”。即
enum RecordState {
RECORD_UNMODIFIED,
RECORD_NEW,
RECORD_CHANGED,
RECORD_DELETED
};
您将给每个记录一个RecordState(默认为record _NEW/record _UNMODIFIED,视情况而定),当调用Save()时,它将对每个记录执行适当的操作,并将其状态重置为record _UNMODIFIED。删除将在处理时从列表中删除。我的第一个想法是将所有可能的db操作封装为命令对象(命令模式)。通过这种方式,您可以创建任意数量的命令,直到调用Save()方法更新数据库为止。在这里,您需要确保这些命令作为事务处理。快速实现如下所示: 标题:
#include <vector>
using namespace std;
class B;
class Cmd;
class B
{
private:
vector<Cmd*> m_commands;
public:
void AddCmd( Cmd* p_command );
void Save();
};
class Cmd
{
protected:
B* m_database;
public:
Cmd( B* p_database );
virtual void Execute() = 0;
virtual void Undo() = 0;
};
class InsertCmd : public Cmd
{
private:
int m_newEntry;
public:
InsertCmd( B* p_database, int p_newEntry );
void Execute() { cout << "insert " << m_newEntry << endl; }
void Undo() { /* undo of insert */ }
};
#include "DbClass.h"
void B::AddCmd( Cmd* p_command )
{
m_commands.push_back(p_command);
}
void B::Save()
{
for( unsigned int i=0; i<m_commands.size(); i++ )
m_commands[i]->Execute();
}
Cmd::Cmd( B* p_database ) : m_database(p_database)
{
m_database->AddCmd(this);
}
InsertCmd::InsertCmd( B* p_database, int p_newEntry )
: Cmd(p_database), m_newEntry(p_newEntry)
{
}
#include "DbClass.h"
int main()
{
B database;
InsertCmd insert( &database, 10 );
database.Save();
return 0;
}
记录状态确实是个好主意 我建议: (a) 应用程序将删除的对象保留在数组中,只有在调用类似ORM的代码进行保存(即插入、更新和删除)时,才会实际删除这些对象 或 (b) ORM上下文需要在内部维护所有对象的幕后列表,这些对象要么是从磁盘中选择的,要么是在RAM中为每个数据库事务创建的(如果不使用事务,则是连接)。当ORM被要求保存时,这个列表被迭代,并且插入、更新和删除都基于这个列表 在第二种情况下,您通常会发现一个额外的要求,即能够在系统的某些部分将对象与ORM分离/分离,以创建状态的持久快照或对象的修改版本(根据某些高级数据流模型或其他模型),而该对象不能立即存储,因此,需要一个额外的位或枚举状态来反映分离。您可能希望能够将对象与ORM事务重新关联/重新附加,但请注意,此处可能涉及完整性问题,如果需要处理,则必须进行处理,并且处理这些问题的方法通常是特定于应用程序的
请注意,在首次保存之前删除的新创建对象不应生成SQL DELETE,因此,使用未修改、新建、更改、删除的枚举在实践中通常是不够的,您还需要删除新对象,如果您同意我的分离理论,则需要删除新对象。有点晚,但在我看来,您需要的是。您当前的设计就像一个与UoW配合得很好的模型。我想分享一下我对如何实现“1对n”关系的看法。 侧“1”是主表,而侧“n”对应从(子)表。我想,我们想从双方的角度来处理这种关系。从slave的角度来看,该关系看起来像一个单一的对象属性,可能具有设置/更改/清除该属性指定的对象引用的能力。从master的角度来看,相同的关系将是类似于集合的属性,为我们提供了迭代/添加/删除该集合中的对象引用的方法。 由于对关系的一方所做的任何更改都必须立即从另一方获得,因此我们有两种选择:
DataObject
类表示映射类的实例,其中映射规则在元数据描述中给出。这样的对象总是在堆中分配,而不是c