Developing Database Applications with an O-R Mapping Framework Part 1

原创 2004年09月25日 21:31:00

Developing Database Applications with an O-R Mapping Framework Part 1

Download this article in Word format

Aaron Lau
September 2004

Applied to:
Microsoft .NET Framework 1.1
Microsoft SQL Server 2000


Summary: this is the part one of a two-part article which introduces how to develop database applications with an O-R (Object-Relational) mapping framework. The first part introduces an O-R mapping framework called DAP (Data Access Process) Framework; and the second part introduces an O-R mapping tool called SuperType which is used to generate from database schemas files of business types and configurations that will be used as the mete-data by the DAP Framework. At the time this article was written, the latest version of the DAP Framework and the SuperType is 2.0.

Content

Introduction

Design of the DAP Framework 2.0

Developing with the DAP Framework 2.0

Deployment and Operations

Conclusion

Introduction

Multi-Layered architecture has for a long time been proved to be an effective way to build reliable, maintainable and flexible enterprise applications. Originally, we had tree layers in the applications we built, they are Presentation (UI) layer, BL (Business Logic) layer and Data layer. As we proceeded, we found that another two layers are needed. One is User Interface Process layer between UI and BL layers, and the three together work as the MVC pattern which is a very good approach that can effectively separate UI and BL layers; another is Data Access layer that exists between BL and Data layers, and that Data Access layer is what the DAP Framework is all about.

The DAP Framework is an O-R mapping framework for the .NET enterprise development. It can assist you with developing flexible and extensible Multi-Layered Windows and Web applications which involve relational databases development. It can be used with SuperType, an O-R mapping tool, together to build intricate enterprise applications in a record time. As an O-R mapping framework, the DAP Framework has the following features, and all of them will be described in detail throughout the rest of this article.

Materialization and dematerialization of a single object

Materialization and dematerialization of a collection of objects

Paging is enabled

Object state management

Cache is enabled

Distributed transaction

Multi-User access and locking strategies

Who Should Read This Article

This guide is targeted at software architects who has already been familiar with architecture design and can use this framework as an alternative way to realize the O-R mapping, or developers who is interested Data Access layer design and can get a first view of what the O-R mapping is primarily about.

In order to fully benefit from this guide, potential readers should have a good understanding of the object-oriented technology and relational databases, such as SQL-Server, basic knowledge of OOD (object-oriented design) and Multi-Layered development methodology. The specific technologies mentioned in this article are C#, the .NET Framework, and XML.

Why O-R mapping?

Because of the prevalence and maturity of the relational databases, they are widely used in the database applications. A number of problems, however, arose due to the mismatch between the record-oriented and the object-oriented representations of data. And that’s the main reason why O-R mapping was introduced as a solution.

What Is an O-R mapping anyway?

Before you go any further, you need to get familiar with the following key ideas, and in the sections to come, each of them is to be described in detail. How they can be achieved and how we should employ them in the real-world enterprise applications will also be introduced.

Mapping: There must be some mapping between a class and its persistence store (for example, a table in a database), and between object attributes and the fields (columns) in a record. That is, there must be a schema mapping between the two schemas.

Materialization and dematerialization: Materialization is the act of transforming a non-object representation of data (for example, a record) from a persistence store into an object. Dematerialization is the opposite activity (also known as passivation).

Caches: Persistence services cache materialized objects for performance.

Transaction state of object: It is useful to know the state of an object in terms of its relationship to the current transaction. For example, it is useful to know whether an object has been modified (is dirty) so that it is possible to determine if it need to be saved back to its persistent store.

Transaction operations: Commit and rollback operations.

Lazy materialization: Not all objects are materialized at once; a particular instance is only materialized on-demand, when needed.

Now, you may be able to figure out what an O-R mapping is.
O-R mapping is a mechanism that can map an object to a record in a relational database table and map that object’s attributes to the fields of that record, and unique values are used to relate that object to that record.

Design of the DAP Framework 2.0

To make the most of the DAP Framework, you need to understand the design of it. The DAP Framework was built with C# and designed to be an extensible and reusable package that can be freely deployed in any project developed with the programming languages that conform to Common Language Specification (CLS). The DAP Framework works in Multi-Layered architecture as an O-R mapping framework through which records in database table can be easily mapped to objects, which also provide functionalities of object caching, object states management, distributed transaction, and etc.

How Does an O-R Mapping Work in the DAP Framework?

In spite of knowing what an O-R mapping is, some of you, especially those who are new in this area, may still be puzzled by how it works. What’s the secret behind an O-R mapping framework? To begin, let’s make a comparison between the following two diagrams in figure 1.

O-R%20Comparison.gif
Figure 1. Comparison between a RDB table and a class

On the left side is a UML class diagram. Instances of the Project class are objects we work with in Business Logic layer. There are 4 fields that represent the attributes of the BO (Business Object) Project in the real world. On the right side, it is a RDB table diagram. It also has 4 fields which are used to save the attributes of Project objects, e.g. id, name, number and cost. Instances of this table schema are records that hold many projects, so we can see records in RDB table as the persistent format of BOs. Let’s proceed to see what the C# code of Project class looks like.


In this Project class, there are 4 fields and 4 properties each of which corresponds to one field, so we can now map these 4 properties to those 4 fields in that RDB table in figure 2.1.

Ordinarily, there are three ways to implement an O-R mapping framework.

One way is to write some database access methods, such as Select, Save, etc. in Project class itself. This approach is convenient, for Project object has the necessary information for itself to be saved to or retrieved from database. The logical extension of this approach is that each business class has it own methods to access to database. But this leads to problems in cohesion, coupling, and duplication. For example, the Project class must now contains logic related to database handling. This class is no longer focused on just the pure application logic of “being a project”, for it now has other kinds of responsibilities, which lowers its cohesion. The class must be coupled to the database service component, such as ADO.NET, rather than just being coupled to other objects in the domain layer of software objects, which raises its coupling. And it is likely that similar database logic would be duplicated in many persistent classes.

Another way is that we can use another class, such as ProjectORMapper, as the mapper between Project objects and RDB records. In this way, Project class works as an
Information Expert which means an individual has necessary information to fulfill a task. Database handling was removed to a separate class, called O-R mapper class such as ProjectORMapper, where Project objects are selected from and updated to the database. Thus some OOD principles, such as High Cohesion, Low Coupling, are conserved. But the issue of code duplication remains unresolved. Even though we move database handling code into another class, there are still possibilities that duplicated database logic would exist through out many classes, since every business class has its own O-R mapper and each O-R mapper has it own code to access a database.

So we come to the third way. We can use only one O-R mapper and an XML file recording the mete-data of different classes, then this mapper can read the mete-data to map different kinds of objects to records in RDB. In this way, those three OOD issues, cohesion, coupling, and code duplication are resolved. An O-R mapping framework is responsible of mapping different objects to RDB records. The mete-data file is essential to the framework, for it provides the knowledge of how a specific object can be mapped to a RDB record. Actually, with an O-R mapping framework, we don’t have to care about SQL statements and ADO.NET, because all these things are handled by the framework. SQL statements are generated from the mete-data automatically. This third way is what the DAP Framework 2.0 use to implementan O-R mapping framework.

Architecture Overview

Figure 2. illustrates the overall architecture of the DAP Framework.

Architecture.gif
Figure 2. The DAP Framework 2.0 architecture

There are two parts in that figure. Panes in olivedrab represent the components in the DAP Framework. They are the essential components that work together to realize the mapping between objects and RDB records. What are in turquoise color indicate a configuration file and code that will access this framework. The configuration file is extremely important to the DAP Framework, because it contains the necessary mete-data that the DAP framework will use to map objects to RDB records; and code in BL layer will use this framework to select objects from or update objects to Data layer.

Persistence Facade

Primarily because the DAP Framework is an independent layer in Multi-Layered system architecture, it needs to provide a facade, a common pattern to provide a unified interface to a subsystem, that upper layers can use consistently to access the Data layer underneath.

Figure 3 is the UML diagram of the PersistenceFacade class which works as the facade of the DAP Framework. Its primary responsibilities are retrieving objects from and updating objects to the Data layer. This class is a
Singleton class, which means there is only one instance of this class exists throughout the application domain. You might be confused by the methods in the class diagram, for there are definitely no methods called Insert and Update, how objects can be inserted or updated to the database. Actually there are indeed some methods called Insert and Update, your can not seeing them is just because they are marked as internal. You can not invoke them outside the framework assembly. Every class who wants their instances to be mapped to RDB records must inherits from the PersistentObject class which provides some methods, such as Save or Delete, that will internally invoke the corresponding methods in this PersistenceFacade class. This is the internal logic of the framework, you don't have to care about it while you are using it.

PersistenceFacade.gif
Figure 3. UML diagram of the PersistenceFacade class

Notice that when you use Select method to retrieve object from the data layer, only one object will be returned, even if there are many records in the database are true of the passed conditions, and that one will be the first in the group. By contrast, when you use SelectCollection method, a collection will be retrieved, even though only one record in the database is true of the conditions passed, and it will be the only one element in the returned collection.

O-R Mapper

This component is the exact place where mapping between objects and records is realized. With the helps from other two components, Sql Factory and SqlParameter Factory, it knows how objects can be retrieved from databases and how those objects can be subsequently updated into databases. Reflection is used in this component to dematerialize objects to databases. An application block from Microsoft, called Data Access Block or SqlHelper, is used in this component. It wraps all ADO.NET database commands.

Sql Factory

This component works as the factory that's used to generate SQL statements. For the performance reason, SQL statements generated from this factory will be cached, so no need to generate a new SQL statement if it has already been requested. This component internally calls other factories for getting the mete-data from the configuration file.

SqlParameter Factory

This components is used to create SqlParameter objects which will be passed as parameters to ADO.NET commands. This component will internally call other factories for getting the mete-data from the configuration file.

Config

This component is used to read the mete-data from the configuration file. And at the very beginning, the format of the configuration will be validated against a predefined schema validation file. This is to make sure the format of the configuration is correct, not incomplete. If the validation fails, a meaningful exception will be thrown to inform developers what the problem is. Thus, less codes are needed to prevent the system built on the framework from being cracked down.

Configuration File

There is a heavy use of configuration file in the DAP Framework. The configuration file contains the mete-data that will be used dynamically at run time. Following is a sample configuration file.


<cachePolicies> that contains one or more child tags, each of which represents a cache policy that will be used to cache objects retrieved from databases. Each <cachePolicy> tag has three attributes. name is used to uniquely represent a cache policy, and a type can be related to a cache policy through this attribute. cacheExpirationMode will be used with cacheExpirationInterval together to indicate how long objects should be cached. There are following examples:


Cached objects with this cache policy will expire at 23:59:59 every day.

Cached objects with this cache policy will expire in 20 minutes.

Cached objects with this cache policy will never expire.

NOTE that if Absolute is used as the cache expiration mode, a time-format value, e.g. 23:59:59, should be assigned to the cache expiration interval attribute. But if Sliding is used as the cache expiration mode, an integer value should be assigned to the cache expiration interval attribute. No need to assign the cache expiration interval attribute if None is used as the cache expiration mode.

<databases> that contains one or more child tags, each of which represents a relational database that will be used. Each <database> tag has two attributes. name is used to uniquely represent a database, and a type can be related to a database through this attribute. conString is used to save the connection string of the database.

<types> that contains one or more child tags, each of which represents a business type or business class. Each <type> tag has four attributes and one child tag. name is used to indicate the name of the type, it is actually the class name. database is used to relate this type to a database specified in the <database> tag. table is used to indicate which table in the specified database is mapped to this type. cachePolicy is used to relate this type to a cache policy specified in the <cachePolicy> tag. This <type> tag has a child tag <properties> which also contains many child tags, each of which represents a property of this type. Each <property> tag can have at most five attributes. name is used to indicate the property name. field is used to indicate the name of the class field that this property will internally access. dbField is used to indicate the name of the field in the specified database table, and this database field is mapped to the class field just mentioned. type is used to indicate the property type, and it is also the type of the class field. This type will be converted to its counterpart type in the database at run time. The last attribute is isPrimary. If the database field just mentioned is the primary key in its table, this attribute will be set to true, otherwise, false.

NOTE that the sequence of the properties MUST be the same as that of the parameters in a constructor of the type.

That is all about the configuration file. Actually, you don't have to code this file manually, SuperType, an O-R mapping tool, can be used to generate this file from database automatically.

PersistenObject

In the DAP Framework, each business class who wants its instances to be mapped to RDB records must inherit from the PersistentObject class which provides many implementations that derived class can use. Figure 4 is the UML diagram of the PersistentObject class.

PersistentObject.gif
Figure 4. UML diagram of the PersistentObject class

States Management

The DAP Framework adopts the State pattern and each persistent object has its own state. There are in all five states:

New State which means a persistent object is new, not retrieved from the database.

OldClean State which means a persistent object was retrieved from the database, but without any operation to it.

OldDirty State which means a persistent object was retrieved from the database and has been modified.

OldDelete State which means a persistent object was retrieved from the database and will be deleted.

Deleted State which means a persistent object has already been deleted from the database.

Figure 5 shows the state chart for a persistent object. From the state chart, you may know that the response to an operation depends on the state of the persistent object. If a persistent object is selected from a database, its state is OldClean, and after it’s saved, its state transforms to OldDirty, then it’s committed, at this time, it’s updated to the database, and its state goes back to OldClean. If this persistent object is totally new, nothing will happen if it’s saved, and its state remains the same, then it's committed, at this time, it is inserted into the database, and its state is changed to OldClean.

StateChart.gif
Figure 5. State chart of a persistent object

In the DAP Framework, a persistent object created explicitly by its constructor has the default state New; and a persistent object retrieved from the database has the default state OldClean.

Overall

The DAP Framework provides developers the ability to clearly separate Data layer and Business Logic layer. Developers have a reasonable and convenient way to retrieve objects from and update objects to the Data layer through the facade of the framework. The framework can work with SuperType, an O-R mapping tool, to develop intricate enterprise application in a record time.

Developing with the DAP Framework 2.0

Feature List of the DAP Framework 2.0

The DAP Framework 2.0 has the following major features.

Materialization and dematerialization of a single object

Materialization and dematerialization of a collection of objects

Paging is enabled

Object state management

Cache is enabled

Distributed transaction

Multi-User access and locking strategies

A Sample Class and a Sample Configuration File

In order to demonstrate the features of the DAP Framework, we need to at first have a sample class and a sample configuration file.

Following is a class Author, and the database table this class mapping to is a sample table called authors in the public database called pubs in the SQL-Server 2000.


Following is a configuration file which has already been introduced.


NOTE that if the application you are building is a Windows application, this configuration file should be placed into the folder where the EXE file is; if you are building an ASP.NET Web application, this configuration file should be placed into the root folder of the Web application, and its extension should changed to config to prevent it from being access through client browsers. Also, the name of this configuration file should be configured in the application configuration file, app.config or web.config, as the following way:


Materialization and Dematerialization of a Single Object

The following code snippet first materializes an Author instance based on the property ID and its value passed to the database, then the first name of this author is changed to “Aaron”, and at last, this author is dematerialized to the database.


NOTE that if there are more than one records in the database are true of the passed condition, only the first one will be converted into an object and returned.

Materialization and Dematerialization of a Collection of Objects

The following code is used to materialize a collection of Author instances. All authors whose first name contains the letter “a” will be returned. Subsequently their phone numbers are changed, and then they are dematerialized to the database.


NOTE that if there is no record in the database is true of the passed condition, the returned ArrayList will contain no author, but the list itself has already been instantiated.

The folowing code demonstrates how to retrieve those authors whose first name contains the letter "a", and also they must live in the state CA.


The folowing code demonstrates how to retrieve those authors whose first name or last name contains letter "a".


Paging Is Enabled

Paging is enabled in the DAP Framework 2.0. The following code demonstrate how to separately retrieve the first ten authors and the second ten authors.


Object State Management

In the following code, there are two authors, author1 and author2. One is constructed explicitly using the constructor, and the other is retrieved from the database. When both methods, Save and Commit, are invoked on these two object, the first one, author1, is inserted to the database, the second one, author2 however, is updated into the database. How could that happened? I mean how the framework is able to know which object should be inserted into the database and which object should be updated to the database. That's because these two Author objects have their states respectively. The Author object instantiated using the constructor has the default state New, and the Author object retrieved from the database has the default state OldClean, so the framework knows how to separately handle these two Author objects.


The following code shows that an Author object is retrieved from the database, and it is subsequently committed without any operation on that object. In this case, that object is not updated to the database, actually, no database access happens. Because the framework knows that the object's state is OldClean, no operation happened on it. For more information about the state management, please review the figure 5 State chart of a persistent object.


Cache Is Enabled

Objects retrieved from the database can be cached by the framework automatically. If some kind of objects are requested frequently, they can be cached to promote system performance. In order to cache objects of a specified type, you should configured that type in the configuration file. Take the Author type for example. Looking at the Author tag in the sample configuration file, you can see that an attribute called cachePolicy has the value Absolute, the name of a cache policy, and that cache policy, configured in the <cachePolicy> tag, tells that cached objects with this cache policy will expire at 23:59:59 every day.

Looking at the following code snippet, if objects of Author type are configured to be cached, that equal boolean value will finally be true, whichh means the object author1 has a reference equality with one Author object in the collection that is retrieved at the second time with the same query parameter.


The same result can be illustrated by the following code, which means that if an author is requested several times, the same cached author will always be returned no matter which query parameter is used.


Distributed Transaction

If transaction were not supported by an O-R mapping framework, developers using it would finally come to a place where something is a mission impossible. Fortunately, distributed transaction is realized in the DAP Framework 2.0 in a reasonable and seemingless way.

Suppose that we had another type called Book. The following code shows how an Author object and a Book object are inserted into the database in a transaction.


NOTE that the sequence that objects are added into the transaction is the sequence that those objects are going to be committed into databases, so objects MUST be added into the transaction in a reasonable sequence to prevent exceptions from being thrown.

Multi-User Access and Locking Strategies

If the DAP Framework 2.0 is being used in an application that is running on a server, there might be the cases when many users will access this framework simultaneously. This concern was considered the first time this framework was designed. For example, there can be only one transaction being executed at a certain time while the framework is running to prevent databases from being locked; if objects of a specified type are configured to be cached, selecting those objects will be synchronized to prevent duplicated objects from being instantiated.

Pet Shop Built on the DAP Framework 2.0

The .NET Pet Shop was originally built by Microsoft as a sample application for .NET developers, and therefore many developers are so familiar with it, some of them even looked into the code of it. This is the main reason why it's been chosen as the sample application built on the DAP Framework. Actually only two days were used to rebuild this application, partially because that the UI and database remain changed, and partially because it is so straightforward to build database applications on the DAP Framework. In this newly created Pet Shop, new Data Access layer, Business Logic layer and controller were used, and almost all features the framework has have been used in it. I personally think that the new Business Logic layer is more reasonable than that of the original one, for it presents clearer associations among different classes. Figure 6 shows the architecture of this new Pet Shop.

PetShopArchitecture.gif
Figure 6. Pet Shop architecture

UI and Data layers remain unchanged. In UI layer, there exist many ASP.NET web forms and some user and custom controls. And Data layer is the SQL-Server 2000 database.

Controller is a class with only static methods which are used to communicate between UI layer and Business Logic layer. Users log in the system through this controller; account, product and order information are saved and retrieved through this controller; session and cache state are maintained through this controller.

Business Logic layer mainly involves business objects and associations among them. It is the place where objects work together to get their job done.

Data Access layer is where the DAP Framework is. It’s used to retrieve objects from or update objects to the Data layer underneath.

Deployment and Operations

Software Requirements

This framework package has been applied in several real-world projects, and it has been fully tested in the following software environment, so you need to make sure that your system meets the following minimum software requirements:

Microsoft Windows 2000 / XP / 2003.

Microsoft .NET Framework version 1.1.

Microsoft SQL-Server 2000.

Microsoft Application Data Block 2.0.

Database Restriction

Database tables should not have fields that are auto-incremental, all fields must be inserted explicitly.

Conclusion

A major advantage of adopting an O-R mapping framework is that it can minimize the complexity of systems and thus help developers build real OO applications. Developers don’t have to care about how to write SQL statements, they can even have no knowledge of what ADO.NET is, they primarily work on how objects can work together to get something done.

1.The Information Expert is a pattern which likes many things in object technology has a real-world analogy. We commonly give responsibility to individuals who have the information necessary to fulfill a task. For example, in a business, who should be responsible for creating a profit-and-loss statement? The person who has access to all the information necessary to create it ─ perhaps the chief financial officer. And just as software objects collaborate because the information is spread around, so it is with people. The company's chief financial officer may ask accountants to generate reports on credits and debits.

2.Practically, there are three principles with OOD. They are High Cohesion, Low Coupling and Protected Variations. More information about these principles can be found from Applying UML and Patterns, an excellent book by Craig Larman.

3.Singleton is one of the GOF patterns, more information can be found from Design Patterns Elements of Reusable Object-Oriented Software.

4.State is one of the GOF patterns, more information can be found from Design Patterns Elements of Reusable Object-Oriented Software.

采用O/R Mapping带来的好处

采用O/R Mapping带来的好处:1.在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像操作对象就可以了, O/R Mapping工具会自动地将对象的操作转换为SQL语句操作。...
  • jackern
  • jackern
  • 2006年04月22日 22:02
  • 718

Codeforces Round #357 (Div. 2) B Economy Game(水题)

思路:水题,注意c为0这种情况即可 #include using namespace std; int main() { int n; int flag = 0; scanf("%d...
  • qq_21057881
  • qq_21057881
  • 2016年07月08日 11:20
  • 229

Web Applications on Azure.pdf 英文原版 免费下载

下载地址: Web Applications on Azure.pdf
  • jiongyi1
  • jiongyi1
  • 2018年01月04日 20:52
  • 35

对O/R Mapping 框架的一点想法

     目前的O/R Mapping框架有很多,如 Hibernate,ibatis,JDO等等。它们无一例外都有一个特点,就是用静态数据类管理数据。例如:一个Order 表,必须为其创建一个Ord...
  • henryqqq
  • henryqqq
  • 2007年09月29日 17:36
  • 524

Simultaneous Localization and Mapping (SLAM)讲义1

Simultaneous Localization and Mapping (SLAM)讲义1简介:Slam问题的核心是将一个移动机器人放置在一个未知环境中,机器人通过自身传感器逐步建立环境的地图同时...
  • akunainiannian
  • akunainiannian
  • 2015年04月28日 22:24
  • 8052

CFGym - 101086J. Smooth Developer - dfs+字符串处理

1.题目描述: J. Smooth Developer time limit per test 8 seconds memory limit per test 256 megabytes ...
  • dragon60066
  • dragon60066
  • 2017年05月08日 19:34
  • 219

深入理解O/R Mapping

什么是O/R Mapping? 广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换。 狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据...
  • nszkadrgg
  • nszkadrgg
  • 2013年01月06日 09:54
  • 834

计算机专业免费电子书下载列表List of freely available programming books

List of freely available programming books      在StackOverflow论坛上,有人要打算收集个免费...
  • yanglr2010
  • yanglr2010
  • 2013年05月30日 12:58
  • 1967

国外经典计算机以及相关领域电子书,下载地址

Meta-Lists 25 Free Computer Science Ebooks Book Training - On Video Cheat Sheets (Free) Code...
  • tainyiliusha
  • tainyiliusha
  • 2013年08月27日 22:03
  • 2538

Simple Mapping of WndProc to your Specific Class' WndProc - Part 1

Simple Mapping of WndProc to your Specific Class' WndProc - Part 1 By AdamMartin, 11 Jun 2010 ...
  • aasmfox
  • aasmfox
  • 2012年11月28日 13:15
  • 335
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Developing Database Applications with an O-R Mapping Framework Part 1
举报原因:
原因补充:

(最多只允许输入30个字)