Oracle TopLink Developer's Guide
10g Release 3 (10.1.3) B13593-01 |
|
![]() Previous |
![]() Next |
You can use TopLink to define an SQL query for each basic persistence operation (insert, update, delete, read-object, read-all, or does-exist) so that when you query and modify your relational-mapped objects, the TopLink runtime will use the appropriate SQL query instead of the default SQL query.
SQL strings can include any fields that the descriptor maps, as well as arguments. You specify arguments in the SQL string using #<arg-name>
, such as:
select * from EMP where EMP_ID = #EMP_ID
The insert and update SQL strings can take any field that the descriptor maps as an argument.
The read-object, delete and does-exist SQL strings can only take the primary key fields as arguments.
The read-all SQL string must return all instances of the class and thus can take no arguments.
You can define a custom SQL string for insert, update, delete, read-object, and read-all using TopLink Workbench (see "Using TopLink Workbench").
You can define a custom SQL string or Call
object for insert, update, delete, read-object, read-all, and does-exist using Java (see "Using Java"). Using a Call
, you can define more complex SQL strings and invoke custom stored procedures.
For 2.0 CMP projects, the ejb-jar.xml
file stores query lists. You can define the queries in the file and then read them into TopLink Workbench (see "Reading From the ejb-jar.xml File"), or define them on the Queries tab and write them to the file (see "Writing to the ejb-jar.xml File").
Note: When you customize the update persistence operation for an application that uses optimistic locking (see "Configuring Locking Policy"), the custom update string must not write the object if the row version field has changed since the initial object was read. In addition, it must increment the version field if it writes the object successfully.For example: update Employee set F_NAME = #F_NAME, VERSION = VERSION + 1 where (EMP_ID = #EMP_ID) AND (VERSION = #VERSION) The update string must also maintain the row count of the database. |
Note: TopLink does not validate the SQL code that you enter. Enter the SQL code appropriate for your database platform (see "Data Source Platform Types"). |
To configure custom SQL queries for basic persistence operations:
In the Navigator, select a descriptor in a relational database project.
Click the Queries tab in the Editor.
Click the appropriate SQL function tab and type your own SQL string to control these actions for a descriptor. Use the following information to complete the tab:
The DescriptorQueryManager
generates default SQL for the following persistence operations:
Insert
Update
Delete
Read-object
Read-all
Does-exist
Using Java code, you can use the descriptor query manager to provide custom SQL strings to perform these functions on a class-by-class basis.
Use ClassDescriptor
method getQueryManager
to acquire the DescriptorQueryManager
, and then use the DescriptorQueryManager
methods that Table 29-2 lists.
Table 29-2 Descriptor Query Manager Methods for Configuring Custom SQL
To Change the Default SQL for ... | Use Descriptor Query Manager Method ... |
---|---|
Insert
|
|
|
|
|
|
Update
|
|
|
|
|
|
Delete
|
|
|
|
|
|
Read
|
|
|
|
|
|
Read all
|
|
|
|
|
|
Does exist
|
|
|
|
|
Example 29-5 shows how to implement an amendment method to configure a descriptor query manager to use custom SQL strings. Alternatively, using an SQLCall
, you can specify more complex SQL strings using features such as in, out, and in-out parameters and parameter types (see "Using SQL Calls").
Example 29-5 Configuring a Descriptor Query Manager with Custom SQL Strings
public static void addToDescriptor(ClassDescriptor descriptor) { // Read-object by primary key procedure descriptor.getQueryManager().setReadObjectSQLString( "select * from EMP where EMP_ID = #EMP_ID" ); // Read-all instances procedure descriptor.getQueryManager().setReadAllSQLString( "select * from EMP" ); // Insert procedure descriptor.getQueryManager().setInsertSQLString( "insert into EMP (EMP_ID, F_NAME, L_NAME, MGR_ID) values (#EMP_ID, #F_NAME, #L_NAME, #MGR_ID)" ); // Update procedure descriptor.getQueryManager().setUpdateSQLString( "update EMP set (F_NAME, L_NAME, MGR_ID) values (#F_NAME, #L_NAME, #MGR_ID) where EMP_ID = #EMP_ID" ); }
Example 29-6 shows how to implement an amendment method to configure a descriptor query manager to use Oracle stored procedures using a StoredProcedureCall
(see "Using a StoredProcedureCall"). This example uses output cursors to return the result set (see "Handling Cursor and Stream Query Results").
Example 29-6 Configuring a Descriptor Query Manager with Custom Stored Procedure Calls
public static void addToDescriptor(ClassDescriptor descriptor) { // Read-object by primary key procedure StoredProcedureCall readCall = new StoredProcedureCall(); readCall.setProcedureName("READ_EMP"); readCall.addNamedArgument("P_EMP_ID", "EMP_ID"); readCall.useNamedCursorOutputAsResultSet("RESULT_CURSOR"); descriptor.getQueryManager().setReadObjectCall(readCall); // Read-all instances procedure StoredProcedureCall readAllCall = new StoredProcedureCall(); readAllCall.setProcedureName("READ_ALL_EMP"); readAllCall.useNamedCursorOutputAsResultSet("RESULT_CURSOR"); descriptor.getQueryManager().setReadAllCall(readAllCall ); // Insert procedure StoredProcedureCall insertCall = new StoredProcedureCall(); insertCall.setProcedureName("INSERT_EMP"); insertCall.addNamedArgument("P_EMP_ID", "EMP_ID"); insertCall.addNamedArgument("P_F_NAME", "F_NAME"); insertCall.addNamedArgument("P_L_NAME", "L_NAME"); insertCall.addNamedArgument("P_MGR_ID", "MGR_ID"); descriptor.getQueryManager().setInsertCall(insertCall); // Update procedure StoredProcedureCall updateCall = new StoredProcedureCall(); updateCall.setProcedureName("UPDATE_EMP"); updateCall.addNamedArgument("P_EMP_ID", "EMP_ID"); updateCall.addNamedArgument("P_F_NAME", "F_NAME"); updateCall.addNamedArgument("P_L_NAME", "L_NAME"); updateCall.addNamedArgument("P_MGR_ID", "MGR_ID"); descriptor.getQueryManager().setUpdateCall(updateCall); }