Mapper: Data Mapping Abstraction Component

Most Java applications must store data to a data store whether it's XML files or a relational database. Changes to the mapping technology should be transparent to the rest of the application allowing changes to be localized in the mapping layer.

Commons Mapper is a thin abstraction layer around a project's chosen data mapping technology. It allows the developer to vary the mapping technique behind this layer (often combining several technologies) so that the rest of the application doesn't change. Technologies such as these can be used to map Java objects to a data store:

The purpose of Mapper is similar to Commons Logging. It isn't a mapping technology itself, it merely exposes common functionality of other mapping APIs.

Commons Mapper is based on the Data Mapper pattern presented in "Patterns of Enterprise Application Architecture" by Martin Fowler.

Scope of the Package

Commons Mapper is not a data mapping implementation. It is meant to be an API allowing pluggable mapper objects of varying implementations.

Interaction With Other Packages

Commons Mapper relies on the standard Java 1.2 (or later) APIs.

Example Usage

Commons Mapper is based on the idea of groups of mappers and a MapperFactory. Mappers are responsible for persisting one kind of Object to a data store. MapperFactory is responsible for dynamically loading and initializing Mappers for the client code. Typically, a .properties file is used to map domain class names to mapper implementation class names and passed to a new MapperFactory instance.

All mappers must implement the Mapper interface. The majority of mapping work can be accomplished through the methods in this interface with specialized methods added to specific Mappers as needed.

    // 1. Setup MapperFactory (this is best done with a .properties file).
    // The keys in the file are fully qualified class names of objects to
    // persist.  The values are the fully qualified class names of the Mapper
    // objects.  
    
    // Note: The keys can actually be anything you want; however, by using
    // fully qualified class names, you can use the Object.class shortcut 
    // notation to lookup Mappers with MapperFactory.getMapper() as shown in
    // step 3.

    Map mappers = new HashMap();
    mappers.add("com.yourcorp.Person", "com.yourcorp.PersonMapper");
    MapperFactory factory = new MapperFactory(mappers);

	// 2. Add a factory listener that will initialize Mapper instances as 
	// they are created.  This allows you to initialize any number of Mapper
	// types without subclassing MapperFactory and using an ugly if/else
	// statement.

	MapperFactoryListener listener =
		new JdbcMapperFactoryListener(dataSource);
    factory.addMapperFactoryListener(listener);
    
    // 3. Persist object with a dynamically loaded Mapper implementation.
    // The factory will return a com.yourcorp.PersonMapper object
    // (which was defined in the Map) to do the persistence.

    Person p = new Person("Joe", "User");
    Mapper m = factory.getMapper(Person.class);
    m.create(p);