[This text is only available in english so far.]
Efficient Java-Database Application Development
Hiding SQL by using the Invoca Java-Database Objectrelational Mapping:
The Invoca OR-Mapping technology is a fully automated toolkit which
transforms database metadata into java classes with the complete functionality
needed to develop elegant database applications.
Instead of writing code like this:
Class.forName(<jdbcDriver>);
java.sql.Connection con =
DriverManager.getConnection(<jdbcURL>,
<dbUID>, <dbPWD>);
Statement stmt = con.createStatemen();
stmt.executeQuery("INSERT INTO ITEM"
+" (ITEMNUMBER, DESCRIPTION, PRICE)"
+" VALUES (1234, 'Chair, red', 55.00)");
...
stmt.executeUpdate("UPDATE ITEM"
+" SET PRICE=PRICE+1"
+" WHERE ITEMNUMBER=1234")
we simply need to write the following piece of code:
ITEM item = new ITEM();
item.colITEMNUMBER = new BigDecimal(1234);
item.colDESCRIPTION = "Chair, red";
item.colPRICE = new BigDecimal("55.00");
item.insert();
...
item.colPRICE = item.colPRICE.add(
new BigDecimal(1));
item.update();
Integrated Features:
- Automated Generation of all java source and class files for all [optionally selected] Tables.
This generation step can be integrated programmatically into the buildprocess for
the project.
- Integration of Userdefined Code: Each Java Source File contains a region of 'protected code' which is used to place logical code
or other userdefined functionality. This area is untouched during the generation process above.
- Reference-Support: The Framework supports referential integrity, which means for example the ability to retrieve one
single ADDRESS-Instance (one row of the table ADDRESS) which is referenced by an ORDER with the
following method (=many-to-one relationship):
ADDRESS address = order.toRefADDRESS();
In a similar way it is possible to retreive all ITEMS referenced by one ORDER
(=one-to-many relationship):
ITEM[] items = order.toRefAllITEM(int maxRows,
boolean ad);
where the parameters maxRows and ad (additional denied) limit
the result to avoid the reading of rows the application never really uses.
- Caching Mechanisms: The semantically correct implementation of the
equals and hashCode -Methods
provide an easy support for various userdefined caching-mechanisms.
- Support for recursively defined data structur: Recursive Data Structures usually define
a tree, while each element of the tree is stored in one row of the same table and the table
contains a foreign key that points to the primary key of the same table. In this case the
foreign key coulmn[s] contain[s] the value[s] of the primary key column[s] of his parent-element.
Our persistence framework provides a mechanism to automatically read the recursively defined data
into a tree structure.
- Automatically generated Keys even with several keyColumns.
The following code shows how it works:
Let's suppose that the ORDER-Table contains the following
columns: ORDERNUMBER, ADDRESSNUMBER and ORDERDATE and the
code should insert a new order for the client whose address
is saved in the row with ADDRESSNUMBER=555:
// reads the specified row automatically:
ADDRESS address = new ADDRESS(
new BigDecimal("555"));
// create a new order-Object (in java only):
ORDER order = new ORDER();
// apply the values defined by referential
// integrity to the order-Object:
order.setRefCols(address);
// and finally insert the order
// into the database:
order.insertAsNext();
In this exaple the line 'order.setRefCols(address);' is actually doing the same
as 'order.colADDRESSNUMBER = address.colADDRESSNUMBER' since this column
is used by the database for the referential integrity.
Like other data manipulation, the method 'insertAsNext() runs as 'atomic operation'
what means that the key generation runs as one transaction sequence. The default implementation
will generate the subsequent ordernumber [max(ordernumber)+1] as the next key. This behaviour can be
changed by overriding the method that defines the default behaviour.
- Transaction-based manipulation of Data: An update-operation for example takes place as
'atomic operation'. This means that before an update is done, the specified row is
read again from the database and compared to the old values cached within each Persistent
instance (like
order in our prvious example). If the values have been changed by
another user [or another application] the framework avoids the update operation (that
would make the previous uptdate to a 'lost update'). Instead an Exception is thrown that
indicates that the values have been changed.
- Database-Java Mapping: The relationship between Database Elements and their mapped
counterparts within the java environment
is shown in the following table:
Database Objects | Java Mapping |
Table (eg. 'ITEM') |
Java Class (src: 'ITEM.java') |
Column of a Table (eg. PRICE of table ITEM) |
Field of Class (ITEM.colPRICE ) |
Foreign Key (Referential Integrity Rule) |
Innerclass within the main class |
Execution of an Insert-Statement |
Call of the method 'insert()' |
Update-Statement |
Method 'update()' |
Delete-Statement |
Method 'delete()' |
Selection of all rows of the table ITEM referenced by one row of the table ORDER. |
ORDER order =
new ORDER(new BigDecimal("1000"));
ITEM[] items =
order.toRefAllITEM(); |
Using this framework brings several advantages:
- Development of code is much simpler, more elegant, clearer and easyer to
maintnance.
- RuntimeExceptions caused by the use of wrong data types
are avoided. (Example: Inserting
values by an SQL-Statement causes a RuntimeException
if for example a String ('1') is set instead of a Number (1).
In some cases the use of prepared statements avoid this problem, too.).
Using our Persistence Framework prevents the developer from doing
mistakes of that kind even earlier:
Normally the IDE supports type-checking. Thus a wrong expression like
item.colPRICE = "55.00";
instead of
item.colPRICE = new BigDecimal("55.00");
will cause the IDE to show the user that the two types
BigDecimal and String are incompatible.
- The visibility of Databasetables as java classes
as well as columns as java-fields and referential integrity rules as
inner classes (and String constants)
within the preferred IDE (Integrated development environment)
avoids mistakes during develpment.
- A change of a table- or columnname for example will never keep the developer
guessing about the question if the project still contains code that needs a change,
too or a change within the code that was done was wrong.
The replacement of these names within JavaCode [especially in a large project]
is both difficult and a waste of time because it can't be done by a
simple 'find & replace' on the project.
Re-running the automatic code generation, more exactly the subsequent
compilation - will show the developer exactly which part
of code need a change. Or even better: if the used IDE supports refactoring
(like IntelliJ for example), the change of a table- or columnname is
a matter of two minuts.
copyright (c) Invoca Systems, Sägeweg 15, CH-4304 Giebenach
|