If you choose to make an RDBMS your persistence mechanism, you must begin by deciding how an object's state will be mapped to a set of rows in one or more tables in your RDB. The decisions that are made here will affect the system's performance.
We begin by mapping from C++ objects to database tables. This includes deciding how to represent an object's primitive data (mapping from C++ data types to database data types) and how to represent hierarchies, associations, etc. This is done once. Typically, a tool is defined that uses these definitions to map from a given object model to the corresponding DDL. In essence, this tool bridges the conceptual gulf between the relational database world (which thinks in terms of data definitions) and the object world (which thinks in terms of objects and their interactions).
We then define the methods that create the database image of the objects, update them and delete them. These methods need to be defined for every persistent class. In general, there are three ways of writing this code, as well as the other class-specific code that is required:
We then define the queries that are used to obtain these data. If the database has a C-level API and no object interface, we write the component that talks to the database API. The API will communicate with the class's member functions (e.g.
, save
) through a C structure or equivalent. We define these structures, again either by hand, from the header files or from the model.delete
These days, most of these features are provided by the application framework (e.g. MFC). The framework should provide an object which manages the connection to the database, typically via ODBC (Open Database Connectivity), as well as an iterator (or recordset), whose member variables correspond to the fields in the database.