Object-Relational Mapping

Because of foreign-key constraints in the database schema, the order of operations corresponding to the changes in the domain model is important. For example, a new row must be inserted into the database before another new row is inserted or an existing row is updated to refer to the new row. Similarly, a column in an existing row referring to a row to be deleted must be set to null before the row is deleted.

Automatic ordering of operations in the database based on database constraints is a significant usabil-ity feature of ORM technologies compared with other technologies in which the programmer must perform the operations in the correct order.

Queries. One of the primary benefits of ORM is that queries are expressed in terms of the domain object model and not the relational schema. This becomes important if the domain model or queries are complex.

One of the challenges in designing the query language for ORM is to make it rich enough to allow most application queries to be implemented in the query language, but restricted to allow all object domain queries to be mapped directly to SQL.

For example, to find all instances of Employee where the weekly salary is greater than some parameter, the SQL query is:

 

SELECT * FROM EMPLOYEE WHERE WEEKLY_SALARY > ?

The corresponding query using the domain object model would be:

SELECT FROM Full TimeEmployee WHERE weeklySalary > :salary

 

The provider generates the SQL from the domain model and the mapping. The “:” is a parameter marker that allows the application to bind parameters to the query by name.

In SQL, all the tables involved in the query are declared in the FROM clause and the joining conditions are expressly included in the WHERE clause. To find instances of Employee whose weekly salary is greater than some parameter and who work in a Department with some name, the SQL is a bit more complex:

SELECT E.* FROM EMPLOYEE E, DEPARTMENT D WHERE E.WEEKLY_SALARY > ? AND D.NAME = ? AND E.DEPARTMENT = D.ID

The corresponding query using the domain object model would be:

SELECT FROM Full TimeEmployee

WHERE weeklySalary > :salary && dept.name = :dept

NAVIGATING RELATIONSHIPS IN QUERIES

One of the biggest differences among ORM implementations is how navigation in queries is expressed. In JDOQL (Java Data Objects Query Language), each query filter is a Java Boolean expression. The Boolean collection methods such as contains(), containsKey(), and containsValue() are used to navigate multivalued relationship fields.

Other domain query languages use constructs that are more similar to SQL to navigate relationships. For example, in Java Persistence API, the query language uses special keywords such as JOIN, IN, and OUTER to navigate relationships.

To find instances of Employee where the weekly salary is greater than some parameter, who work in a Department with a specific name, and work on a Project with a specific name, the SQL is even more complex:

SELECT E.* FROM EMPLOYEE E, DEPARTMENT D, PROJECT P,
EMPLOYEE_PROJECT EP

WHERE E.WEEKLY_SALARY > ? AND D.NAME = ?

AND E.DEPARTMENT = D.ID AND E.ID = EP.EMPID

AND P.ID = EP.PROJID AND P.NAME = ?

The corresponding domain model query in JDOQL is:

SELECT FROM Employee WHERE weeklySalary > :salary && dept.name == :dptname && projects.contains(p) && p.name == :prjname

This example query uses the Set.contains(Object) method of the Set<Project> projects field to map to the join table in the relational model. The two tokens :dptname and :prjname are variables that are provided to the query at runtime.

References:

mailto:feedback@acmqueue.com

Archives