[ Team LiB ] |
B.3 Database Patterns
GoalTo hide the process of selecting an appropriate persistence layer or set DAO objects from the business tier, and to allow configuration of DAO features at runtime in a centralized manner (Figure B-3). Figure B-3. DAO factory with two DAO typesParticipants
InteractionsThe client, a business tier or presentation tier object, calls a method on a DAO factory object, requesting a DAO object. The DAO factory is responsible for determining how to create the DAO object. This may involve implementation-specific DAO factories responsible for creating the DAO objects.
GoalSeparate code for accessing data from a persistence mechanism from code used for processing data (Figure B-4). Figure B-4. Data access objectParticipants
InteractionsA business object or presentation tier object obtains an instance of a data access object (DAO), which it uses to save and retrieve data objects. The DAO is responsible for all interactions with the persistence mechanism (database, raw files, etc.) used to store the application data. A data object independent from the persistence layer (see the Data Transfer Object pattern) is used to exchange data between the business objects and the DAO.
GoalTo prevent writing data to the database unnecessarily. Participants
InteractionsA DAO is used to create a data object. When the data object is updated, it records the fact. When the DAO is used to update the database with the changed values, it can use this information to avoid writing to the database when the underlying data hasn't changed. NotesThe obvious benefit of this pattern is to eliminate the performance overhead of doing the write operation in the first place. There's also a hidden benefit when running against databases that perform auditing: the database is spared the overhead of storing huge quantities of unnecessary change tracking. Since in an active database the volume of audit trail information can far exceed the actual volume of data, the performance and storage benefits of this pattern can be huge.
GoalTo avoid delays created by excessive and unnecessary database access (Figure B-5). Figure B-5. Lazy load sequenceParticipants
InteractionsThe client calls methods on a business object, requesting specific data. The business object calls a DAO method to retrieve only the data required for the current method. If the client needs additional data, the business object performs an additional request to the DAO. NotesImplementing the Lazy Load pattern intelligently requires a bit of analysis of your application. If your application can retrieve several kinds of data with a single database query, it will generally be more efficient to do that then to retrieve each piece separately. If multiple queries would be required anyway, and different use cases require different data, the Lazy Load pattern can improve performance by limiting queries to only those strictly necessary.
GoalLeverage stored procedures in the database by providing a transparent Java interface (Figure B-6). Figure B-6. A PAO objectParticipants
InteractionsA business or presentation tier object (the client) creates an instance of a PAO and optionally sets properties. The client calls the PAO's execute( ) method. The PAO then accesses the database and invokes a stored procedure using the properties passed in by the client. The PAO may perform transformations of the parameters set by the client to match the expectations of the stored procedure. After the stored procedure completes, the client may read additional properties on the PAO to retrieve the results of the stored procedure. NotesA PAO can also be implemented using a method-return syntax, in which all input parameters are passed into a single, possibly static, method call on the PAO object. In this case, return values are provided to the client via a DTO object. Also see the GoF Command pattern.
GoalEfficiently generate a block of unique numerical identifiers, supporting distributed applications and eliminating risk of duplicate identifiers. Participants
InteractionsThe application maintains an object responsible for handing out identifiers. The object maintains a block of identifiers and hands them out one at a time. When the current block is exhausted, the object accesses the database and reads a new unique value from a database sequence. The new value is used as a seed to generate a new block of sequences. NotesSince the database maintains the seed values used to generate each sequence block, there is no problem with duplicate identifiers, even if the application is running across multiple JVMs. The worst that will happen in this case is that identifiers may not be contiguous and may be assigned out of order.
GoalTo easily persist Java objects to the database. Participants
InteractionsThe client passes a data object to a DAO. The DAO uses Java object serialization to translate the object into a set of bytes, which are stored directly in the database. When the client needs to retrieve the object, the DAO reads the bytes back from the database and reconstitutes the object. NotesUsing serialization has two major drawbacks: the data cannot be queried directly in the database, and the data must be converted if the structure of the underlying objects changes. Using objects that can write themselves to XML alleviates both these concerns.
GoalEfficiently assign primary keys to new entities, using the database's key management techniques without performing multiple queries. Participants
InteractionsThe client passes the data object to a DAO object to be used in the creation of a new entity in the database. The DAO passes this information to a stored procedure, which generates a new primary key and inserts the data into the target table, or inserts the data into the target table and allows the database to assign a primary key, which the stored procedure can then retrieve. The DAO then passes the new key back to the application.
GoalProvide a simple mapping between a class hierarchy and a set of database tables. Participants
Interactions
GoalTo automatically store an object in a database in a way that is human-readable and easily extensible. Participants
InteractionsThe tuple table DAO takes a data object and converts its properties to name=value pairs. It then writes those pairs into multiple rows of a database table. Each row of the table contains the object's primary key, a field name, and a value. When the client needs to retrieve the data from the table, the DAO reads the name=value pairs and uses them to reconstitute an instance of the object. NotesThe tuple table approach makes it easy to add new fields to the database, since you only need to extend the data object. |
[ Team LiB ] |