JDBF

Object-Relational Mapping system

SourceForge.net Logo

Why this tool?

Overview

Requirements

Getting Started

Contributing

Acknowledgements

Why this tool?

JDBF has been implemented on one idea described by Scott Ambler in his white paper The Design of a Robust Persistence Layer for Relational Databases . JDBF is a robust persistence layer that maps objects to persistence mechanisms(relational databases) in such a manner that simple changes to the relational schema do not affect your object-oriented code. The advantage of this approach is that your application programmers do not need to know a thing about the schema of the relational database, infact, they dont even need to know that their objects are being stored in a relational database. This approach allows your organization to develop large-scale, mission critical applications. The disadvantage is that there is a performance impact to your applications, a minor one if you build the layer well, but there is still an impact. Some advantages of JDBF are small footprint, low-level access, ease of programming with criteria objects, and built-in support of XML. It does not have some enterprise features such as locking, and modification detection. Because of this, it is smaller than some systems. If you are more interested in enterprise features, I recommend Castor. When you need to generate a list which includes information from hundreds of records, you don't want to create objects. JDBF allows low-level access while still allowing use of the mapping system. The criteria objects are very easy to use. Please see the examples. Soon, JDBF should support the relations between tables, should generate XML directly from a result set using the mapping. It also should include a parser for restoring or creating objects from an XML stream, it should support updates to the DBMS directly from XML, skipping objects.


layer

Overview

JDBF is an JDBC-based object-relational mapping that allows Java developers to quickly implement database access in their applications. It generates SQL for retreiving, saving, and deleting objects. With JDBF, objects which represent data from a relational database may be easily saved and retrieved. JDBF provides a mapping of objects to a JDBC relational database. With this approach, minor changes to the relational schema do not affect the object-oriented code. That object-oriented code is not hardwired to the schema of the relational database is one of the advantages of this approach. Another advantage is that the application will have significantly less code becaue much of the SQL code which would be statically embedded in the application is generated. Another benefit is that you do not need to code for a particular database vendor's syntax. The disadvantage is that there is a performance impact to the applications, a minor one if the persistence layer is built well, but there is still an impact. For a complete discussion of the advantages of using an object-relational mapping system, please read the aforementioned white paper by Scott Ambler.
The features of JDBF are:

Requirements

JDK 1.3 or higher is required.

Getting Started

Before using JDBF, you should configure it. The steps that you should do are following:

  1. Configuring the connections against databases
  2. Configuring the repository to map the object to database
  1. Configuring connections.

    JDBF use a xml file to configure the connection to database. It support the connections to various database versions and/or vendors. In addition to the generic interface, there are database specific ones for Interbase, MySQL, Oracle, PostgreSQL, SQL Server, and Sybase. JDBf should work on any database which has a JDBC driver. To configure a connection to database you need to have some important informations about database as name of database,vendor,driver JDBC,server,user and password. In start-up phase JDBF'll create all connections that are configured. Database configuration is described as shown below.

    <?xml version="1.0"?>
    
    <databases>
       <database>
    	  <name>jdbf_test</name>
    	  <vendor>Mysql</vendor>	
    	  <dbDriver>org.gjt.mm.mysql.Driver</dbDriver>
    	  <dbServer>jdbc:mysql://localhost/jdbf_test</dbServer>
      	  <dbLogin>dummy</dbLogin>
    	  <dbPassword>jdbf</dbPassword> 	
       </database>
       .
       .
       .
    </databases>
            

    Very important in this file is the vendor as you'll see later.

  2. Configuring repository

    After that you have configured the connections, you should configure the repository. This is the core of layer because repository maps the the Java object to the specific table of database.

    Consider a database that has of one table for product. Product can be described for JDBF as shown below.

       
    Java
    Attribute Name
    Database
    Column Name

    Type
    id id integer
    name name varchar
    groupId group_id integer
    price price numeric

    Code snipped from the Product class is shown below.

    	private String	name;
    	private int	groupId;
    	private double	price;
    	
    	
            public Product(){}
    
    	public Product(String repositoryName){
    	    super(repositoryName);
    	}
    
    	
    	private String	name;
    	private int	groupId;
    	private double	price;
    	private int	id;
    
    	public String getName() { return name; }
    
    	public int getGroupId() { return groupId; }
    
    	public double getPrice() { return price; }
    
    	public int getId() { return id; }
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setGroupId(int groupId) {
    		this.groupId = groupId;
    	}
    
    	public void setPrice(double price) {
    		this.price = price;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    		

    Assume that product has the following database definition:

    create table prod (
         id        int not null,
         name      varchar(200) not null,
         price     numeric(18,2) not null,
         group_id  int not null
         );
    
    

    With JDBF, XML is used for the external representation of maps for classes such as Product. XML for the mapping of Product is below.

    <repository>
    
      <repositoryView name="product" table-name="Product" object-name="Product" database-name="jdbf_test">
    	<item property-name="OID" primary-key="yes" data-type="int" column-name="id" />
    	<item property-name="name" primary-key="no" data-type="string" column-name="name" />
    	<item property-name="price" primary-key="no" data-type="int" column-name="price" />          
    	<item property-name="groupId" primary-key="no" data-type="int" column-name="group_id" />          	
      </repositoryView>
    	.      
    	.
    </repository>
    
            

    XML mapping is very quickly, every repositoryView represents the mapping between Java objcet with relative table. You need to have some additional informations as name of repositoryView, name of table which links Java object to table, name of Java object and name of database (all these informations are case-sensitive).

    Now, you should map the properties of your Java class with the relative columns of the table. This is do with <item/> tag where you define the property name of your class, define if it is a primary key, define its data-type (this information is a short name, see section Data Types) and its relative column name on the table. Note that when the item is a primary key its property-name attribute is OID, because your Java class inherits it from org.jdbf.engine.basic.ObjectMapped class. Don't worry, you are reaching your goal. :-)

  3. Data Types

    JDBF maps SQL data types as shown below.

    short name java types type
    int java.lang.Integer integer
    long java.lang.Long bigint
    binary byte[] binary
    varbinary byte[] varbinary
    longbinary byte[] longvarbinary
    boolean java.lang.Boolean bit
    date java.sql.Date date
    time java.sql.Time time
    timestamp java.sql.Timestamp timestamp
    decimal java.math.BigDecimal decimal
    numeric java.math.BigDecimal numeric
    double java.lang.Double double
    float java.lang.Double float
    real java.lang.Float real
    smallint java.lang.Short smallint
    tinyint java.lang.Byte tinyint
    char java.lang.Char char
    string java.lang.String varchar
    longstring java.lang.String longvarchar

    You can define,for the same item descriptor, two different data type because Jdbf converts its value.

    Currently, there's no support for storing character or binary streams.

  4. Key Generation

    JDBF features automatic generation of keys. A list of key generators that are supported by JDBF is shown follows:

     4.1 Max key enerator
     4.2 HighLow key generator
     4.3 Identity key generator
     4.4 Sequence key generator

    4.1 Max key generator

    The basic idea is that when you insert a new row into the table that you take the MAX() of that column, add one to it, and then use that as the value for your key (SELECT MAX(key) + 1).To configure a Max key generator you should add this line in repository file.

    <repository>
    
      <repositoryView . . .>
    	.      
    	.
    	<key-generator type="max"/>
      </repositoryView>
    	
    </repository>
            

    4.2 HighLow key generator

    The basic idea is that instead of using a large integer for the OID, requiring you to go to a single source (and therefore a bottleneck) to obtain the OID, you reorganize your OID into two logical components: A HIGH value that you obtain from a single source and a LOW value that the application assigns itself. The value HIGH is obtained from a single row table in the database (or from a built in key value function for some databases) when the application first needs to create an OID. Because HIGH is obtained from a single source it is guaranteed to be unique. At this point the value for LOW is set at zero and is incremented every time an OID is needed for that user’s session.To configure a HighLow key generator you should add this line in repository file.

    <key-generator type="highlow" table="keyGenerators" tableColumn="tablename" keyColumn="keyName" nextColumn="nextLow"/>

    To use HighLow key generator you must create a table that contains the table name,the key name and the next value of low.

    4.3 Identity key generator

    The basic idea is that when you insert a new row into the table the value of your key is auto-incremented.To configure a Identity key generator you should add this line in repository file.

    <repository>
    
      <repositoryView . . .>
    	.      
    	.
    	<key-generator type="identity"/>
      </repositoryView>
    	
    </repository>
    	  

    4.4 Sequence key generator

    The basic idea is that when you insert a new row into the table the value of your key is auto-incremented by a sequence.To configure a Sequence key generator you should add this line in repository file.

    <repository>
    
      <repositoryView . . .>
    	.      
    	.
    	<key-generator type="sequence"/>
      </repositoryView>
    	
    </repository>
    	  

    A table database-key generators ,that explains for every database which key generators are supported follows.

    database vendor Max HighLow Identity Sequence
    Oracle X X   X
    Postgres X X    
    Interbase X X    
    Informix X X    
    MySQL X X X  
    SQL Server X X X  
    Sybase X X X  
    Others   X    


  5. Initializing

    To intialize JDBF, the samples use the code below.

    //Initialize layer
    LayerManager layer = LayerManager.getInstance("repository.xml");
    //Configure database connections.
    DatabaseImpl database = layer.getDatabase("/conf/database.xml");
    .. .. //Use JDBF 
    
  6. Manipulating objects

    JDBF helps Java programmers to holds the objects. It generates SQL for retreiving, saving, and deleting objects.


    6 1 Insert

    To insert a new object, the samples use the code below.

    	//Create the object Product link it to repository called product.
    	Product prod = new Product("product");
    	prod.setName("AS40 Canon");
    	prod.setPrice(239.00);
    	prod.setGroupId(1);
    	//Insert the product.
    	database.insert(prod);	
    	
    6 2 Select

    To select a new object, the samples use the code below.

    	SelectCriteria selectCriteria = new SelectCriteria("Product");
    	//Select the product specifing the column and its value of search.
    	selectCriteria.addSelectEqualTo("name","AS40 Canon");
    	//Order by id in oder ascending.
    	selectCriteria.addOrderBy("id",true);			
    	//Select specifing the name of repository.
    	QueryResults results = database.select("product",selectCriteria);
    	while(results.next()){				
    	    System.out.println(results.getObject());
    	}
    	

    If you need to select all the record in a table, you can do as shown below.

    	.
    	.
    	.
    	QueryResults results = database.select("product",null);
    	while(results.next()){				
    	    System.out.println(results.getObject());
    	}
    	
    6 3 Update

    To update a object, the samples use the code below.

    	String[] propertiesNameToUpdate = {"name"};
    	Object[] values = {"PowerShot AS40"};
    	//Update product.
    	database.update(prod,properties);
    	

    In addition, you can update more records together in table. If you need to do this see the example below.

    	String[] propertiesNameToUpdate = {"name"};
    	Object[] values = {"PowerShot AS40"};
    	UpdateCriteria criteria = new UpdateCriteria("product");
    	criteria.addSelectEqualTo("name","AS40 Canon");
    	database.updateForCriteria("product",properties,values,criteria);        
    	
    6 4 Delete

    To delete a object, the samples use the code below.

    	//Delete product.
    	database.delete(prod);
    	

    In addition, you can delete more records together in table. If you need to do this see the example below.

    	DeleteCriteria deleteCriteria = new DeleteCriteria(obj.getClassName());
    	deleteCriteria.addSelectEqualTo("name","AS40 Canon");
    	database.deleteForCriteria(deleteCriteria);
    	


  7. Marshalling and Unmarshalling of objects

    You can process a Java Bean so that you can perform an marshall and unmarshal operations.


    7 1 Marshalling

    Marshall is the operation that creates a xml rapresentation from Java object. This rapresentation is composed from state (properties's values) of Java object.

    	//Retrieves all rows from product repositoryView
    	QueryResults results = database.select(repositoryViewName,null);
    	Product prod = (Product)results.first();
    	//Marshalles object
    	String xml = prod.marshall();	
    	
    XML rapresentation is composed as shown below:
    <object>
      <class-name>Product</class-name>
      <repository-name>product</repository-name>
      <attributes>
         <attribute>
            <name>OID</name>
            <value>1</value>
            <type>java.lang.Object</type>
         </attribute>
         <attribute>
            <name>name</name>
            <value>AS70 Canon</value>
            <type>java.lang.String</type>
         </attribute>
         <attribute>
            <name>groupId</name>
            <value>0</value>
            <type>int</type>
         </attribute>
         <attribute>
            <name>price</name>
            <value>300</value>
            <type>int</type>
         </attribute>
      </attributes>
    </object>
            

    7 2 Marshalling

    Unmarshall is the operation that creates a Java object from a xml.

    	prod = (Product)Product.unmarshall(xml);
    	

Contributing

JDBF should support more datatypes, more database specific syntax, and should have better error checking. Bug fixes are certainly welcome. For enhancements or implementing items in the Todo list, I encourage you to contact me first. I will respond to items posted in the Open Discussion at SourceForge.

Acknowledgements

This project uses sources authored by Assaf Arkin of ExOffice Technologies, Inc. Assaf Arkin's original code is in Castor JDO, an excellent object-relational mapping system. I also used the class and method names for key generation from Oleg Nitz's work in Castor JDO. Obviously, I like Castor JDO. The reasons for developing JDBF are enumerated above. Xalan Apache is used for XML mapping and parser of configuration database. I wish to thank Scott Ambler who has me a idea to implement JDBf with his white paper persistenceLayer