Presentation is loading. Please wait.

Presentation is loading. Please wait.

Data Access Patterns Problems with data access from OO programs: 1.The object-relational impedance mismatch 2.Decoupling domain logic from database technology.

Similar presentations


Presentation on theme: "Data Access Patterns Problems with data access from OO programs: 1.The object-relational impedance mismatch 2.Decoupling domain logic from database technology."— Presentation transcript:

1 Data Access Patterns Problems with data access from OO programs: 1.The object-relational impedance mismatch 2.Decoupling domain logic from database technology Bibliography: – Lecture notes based on material from: – Wolfgang Keller, Mapping Objects to Tables http://www.objectarchitects.de/ObjectArchitects/papers/Published/ZippedPaper s/mappings04 – Sun: Core J2EE Pattern Catalog http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.ht ml – For further reading if interested: Clifton Nock, Data Access Patterns: Database Interactions in Object Oriented Applications, Addison Wesley, 2003

2 Problems in Data Access (1) The object-relational impedance mismatch: conceptual and technical difficulties that are often encountered when a relational database management system is being used by a program written in an object-oriented programming language or style Object-oriented model: – Aggregation – Inheritance and polymorphism – Associations between classes Relational model: – Tables – Foreign key references to another table

3 Mapping Object Oriented to Relational Concepts General rules: – Class Table – Object Row – Attribute Column – Works well only for simple classes with scalar attributes only Problems: – Aggregations: one domain object contains other domain objects – Associations: objects have references to other objects (m:n) – Inheritance: How do you map an inheritance hierarchy of classes to database tables?

4 Solutions for Mapping Aggregation (1): Single Table Aggregation Solution: Put the aggregated object's attributes into the same table as the aggregating object’s.

5 Single Table Aggregation Example & Consequences Performance: +, only one table needs to be accessed for queries Flexibility: -, if the aggregated object type is aggregated in more than one object type, the design results in poor maintainability

6 Solutions for Mapping Aggregation (2): Foreign Key Aggregation Solution: Use a separate table for the aggregated type. Insert an Synthetic Object Identity into the table and use this object identity in the table of the aggregating object to make a foreign key link to the aggregated object.

7 Foreign Key Aggregation Example & Consequences Performance: -, needs a join operation or at least two database accesses Maintenance: +, Factoring out objects into tables of their own makes them easier to maintain and hence makes the mapping more flexible. Consistency of the database: !, Aggregated objects are not automatically deleted on deletion of the aggregating objects.

8 Solution for Mapping Associations: Association Table Solution: Create a separate table containing the Object Identifiers (or Foreign Keys) of the two object types participating in the association. Map the rest of the two object types to tables using any other suitable mapping patterns presented in this paper.

9 Association Table Example

10 Solutions for Mapping Inheritance (1): One Class – One Table Solution: Map the attributes of each class to a separate table. Insert a Synthetic OID into each table to link derived classes rows with their parent table's corresponding rows.

11 One Class – One Table Example & Consequences Performance: -, reading a FreelanceEmployee instance in our example costs 3 (=depth of inheritance tree) database read operations

12 Solutions for Mapping Inheritance (2): One Inheritance Path – One Table Solution: Map the attributes of each concrete class to a separate table. To a classes’ table add the attributes of all classes the class inherits from.

13 One Inheritance Path – One Table Example & Consequences Performance: +, needs one database operation to read or write an object. Space consumption: +, optimal space consumption. Maintenance cost: +/-: inserting a new subclass means updating all polymorphic search queries. The structure of the tables remains untouched. Adding or deleting attributes of a superclass results in changes to the tables of all derived classes.

14 Problems in Data Access (2) Access to data varies depending on the source of the data. type of storage (relational databases, object-oriented databases, flat files, etc) particular vendor implementation for a type. When business components need to access a data source, they can use the appropriate API to achieve connectivity and manipulate the data source. Problem: coupling between the components and the data source implementation: appears when including the connectivity and data access code provided by different API’s within the business components (domain objects) Such code dependencies in components make it difficult to migrate the application from one type of data source to another Components need to be transparent to the actual persistent store or data source implementation to provide easy migration to different vendor products, different storage types, and different data source types.

15 The Data Access Object Pattern Intent: Abstract and Encapsulate all access to the data source Sun Developer Network - Core J2EE Patterns http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

16 DAO – Participants and responsibilities BusinessObject: represents the data client. It is the object that requires access to the data source to obtain and store data. DataAccessObject: the primary object of this pattern. It abstracts the underlying data access implementation for the BusinessObject to enable transparent access to the data source. The BusinessObject also delegates data load and store operations to the DataAccessObject. DataSource: represents a data source implementation. A data source could be a database such as an RDBMS, OODBMS, XML repository, flat file system, etc. Transfer Object: used as a data carrier. The DataAccessObject may use a Transfer Object to return data to the client. The DataAccessObject may also receive the data from the client in a Transfer Object to update the data in the data source.

17

18 Where to get DAO’s from ? Strategies to get DAO’s: –Automatic DAO Code Generation Strategy –Factory for Data Access Objects Strategy

19 Automatic DAO Code Generation Strategy Since each BusinessObject corresponds to a specific DAO, it is possible to establish relationships between the BusinessObject, DAO, and underlying implementations (such as the tables in an RDBMS). Once the relationships are established, it is possible to write a simple application-specific code-generation utility that generates the code for all DAOs required by the application. The metadata to generate the DAO: – can come from a developer-defined descriptor file. – or, alternatively, the code generator can automatically introspect the database and provide the necessary DAOs to access the database. If the requirements for DAOs are sufficiently complex, consider using third-party tools that provide object-to-relational mapping for RDBMS databases. – Examples: Java Persistence API (JPA): Hibernate

20 Factory for Data Access Objects Strategy The DAO pattern can be made highly flexible by adopting the Abstract Factory [GoF] and the Factory Method [GoF] patterns Use Factory Method: When the underlying storage is not subject to change from one implementation to another, use the Factory Method pattern to produce a number of DAOs needed by the application. Use Abstract Factory: When the underlying storage is subject to change from one implementation to another, this strategy may be implemented using the Abstract Factory pattern. In this case, this strategy provides an abstract DAO factory object (Abstract Factory) that can construct various types of concrete DAO factories, each factory supporting a different type of persistent storage implementation. Once you obtain the concrete DAO factory for a specific implementation, you use it to produce DAOs supported and implemented in that implementation.

21 DAO with Factory Method

22 DAO with Abstract Factory

23

24 Consequences Enables Transparency Enables Easier Migration. Reduces Code Complexity in Business Objects: Adds Extra Layer Needs Class Hierarchy Design

25 Example

26 Example- Using Factory Method

27 Example- Using Abstract Factory

28 Abstract class DAO Factory // Abstract class DAO Factory public abstract class DAOFactory { // List of DAO types supported by the factory public static final int CLOUDSCAPE = 1; public static final int ORACLE = 2; public static final int SYBASE = 3;... // There will be a method for each DAO that can be created. //The concrete factories will have to implement these methods. public abstract CustomerDAO getCustomerDAO(); public abstract AccountDAO getAccountDAO(); public abstract OrderDAO getOrderDAO();... public static DAOFactory getDAOFactory( int whichFactory) { switch (whichFactory) { case CLOUDSCAPE: return new CloudscapeDAOFactory(); case ORACLE : return new OracleDAOFactory();... default : return null; }

29 Cloudscape concrete DAO Factory implementation import java.sql.*; public class CloudscapeDAOFactory extends DAOFactory { public static final String DRIVER= "COM.cloudscape.core.RmiJdbcDriver"; public static final String DBURL= "jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB"; // method to create Cloudscape connections public static Connection createConnection() { // Use DRIVER and DBURL to create a connection // Recommend connection pool implementation/usage } public CustomerDAO getCustomerDAO() { // CloudscapeCustomerDAO implements CustomerDAO return new CloudscapeCustomerDAO(); } public AccountDAO getAccountDAO() { // CloudscapeAccountDAO implements AccountDAO return new CloudscapeAccountDAO(); } public OrderDAO getOrderDAO() { // CloudscapeOrderDAO implements OrderDAO return new CloudscapeOrderDAO(); }... }

30 Interface that all CustomerDAOs must support // Interface that all CustomerDAOs must support public interface CustomerDAO { public int insertCustomer(...); public boolean deleteCustomer(...); public Customer findCustomer(...); public boolean updateCustomer(...); public RowSet selectCustomersRS(...); public Collection selectCustomersTO(...);... }

31 CloudscapeCustomerDAO implementation // CloudscapeCustomerDAO implementation of the CustomerDAO interface. // This class can contain all Cloudscape specific code and SQL statements. import java.sql.*; public class CloudscapeCustomerDAO implements CustomerDAO { public CloudscapeCustomerDAO() { // initialization } // The following methods can use CloudscapeDAOFactory.createConnection() // to get a connection as required public int insertCustomer(...) { // Implement insert customer here. // Return newly created customer number or a -1 on error } public boolean deleteCustomer(...) { // Implement delete customer here // Return true on success, false on failure } public Customer findCustomer(...) { // Implement find a customer here using supplied argument values as search criteria // Return a Transfer Object if found, return null on error or if not found }

32 Customer Transfer Object public class Customer implements java.io.Serializable { // member variables int CustomerNumber; String name; String streetAddress; String city;... // getter and setter methods...... }

33 Client Code // Create a DAO CustomerDAO custDAO = cloudscapeFactory.getCustomerDAO(); // create a new customer int newCustNo = custDAO.insertCustomer(...); // Find a customer object. Get the Transfer Object. Customer cust = custDAO.findCustomer(...); // modify the values in the Transfer Object. cust.setAddress(...); cust.setEmail(...); // update the customer object using the DAO custDAO.updateCustomer(cust); // delete a customer object custDAO.deleteCustomer(...); // select all customers in the same city Customer criteria=new Customer(); criteria.setCity("New York"); Collection customersList = custDAO.selectCustomersTO(criteria); // returns customersList - collection of Customer // Transfer Objects. iterate through this collection to // get values....

34 Related Pattern: Data Mapper [Martin Fowler] The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. http://martinfowler.com/eaaCatalog/dataMapper.html

35 Related Pattern: Table Data Gateway [Martin Fowler] A Table Data Gateway holds all the SQL for accessing a single table or view: selects, inserts, updates, and deletes. Other code calls its methods for all interaction with the database.

36 Simpler Pattern: Active Record/Active DomainObject An object that wraps a row in a database table, encapsulates the database access, and adds domain logic on that data. Characteristics: DomainObjects are dependent on the persistence mechanism Use only if the DomainModel is simple enough and persistence mechanism does not change

37 Simpler Pattern: Row Data Gateway Row Data Gateway gives you objects that look exactly like the record in your record structure but can be accessed with the regular mechanisms of your programming language. All details of data source access are hidden behind this interface.


Download ppt "Data Access Patterns Problems with data access from OO programs: 1.The object-relational impedance mismatch 2.Decoupling domain logic from database technology."

Similar presentations


Ads by Google