CHAPTER 11 Creating Data Model Components

download report

Transcript CHAPTER 11 Creating Data Model Components

Creating Data Model Components
Creating Data Model Components
In this chapter you will learn how to expose data to a client application.
ADF BC does not allow MVC applications to access entity object
definitions and associations directly. Instead, you select exactly what data
you want clients to be able to access by exposing it through data model
components (view object definitions, view link definitions,
application module definitions).
The first part of this chapter shows how to create view object definitions
and later in the chapter you will learn how to use view link definitions to
represent relationships between your view object definitions and using
application module definitions to aggregate the data and relationships
that an application will need.
Creating Data Model Components
Remember these facts about view object definitions:
• A view object definition is the representation of a SQL query.
• A view object definition includes view attributes for every column in the
query result set. The attribute types are Java classes that correspond to the SQL
types of the columns.
• View attributes can be, but do not need to be, based on entity attributes.
• Associated with each view object definition is an XML file containing tags
representing the query, the view attributes, and any entity objects that contain
entity attributes that the view attributes are based on.
• Also associated with each view object definition is a class that contains a
number of methods that return view rows, which represent one row from the
View Attributes, Entity Attributes, and Caching
View attributes can, but do not need to, be based on entity attributes.
View attributes based on entity attributes are called entity-derived view
attributes and other view attributes are called SQL-only view attributes.
The primary difference between the two is the way in which they are
cached. Caching is holding copies of data in memory, which generally
optimizes performance. ADF BC’s caching optimizes performance by
holding data in the middle tier, eliminating repeated trips to the database.
This section discusses how values for entity-derived and SQL-only view
attributes are cached and then explains how to decide whether a
particular attribute should be entity-derived or SQL-only.
How Entity-Derived View Attributes are Populated
When a view object instance with entity-derived view attributes first
executes its query, it sends the query to the database. The database
returns a result (shown below).
How Entity-Derived View Attributes are Populated
The columns in the query result are mapped to view attributes and to
entity attributes they are base on, as shown below.
attributes from
Entity attributes
How Entity-Derived View Attributes are Populated
Next, entity object instances are created, and the attributes are populated with the
appropriate result column data, and inserted into caches (one for each entity object
definition), as shown below.
How Entity-Derived View Attributes are Populated
Finally, view rows are created, and the attributes are populated with pointers to the
entity attributes in the entity cache. These view rows are inserted into the view cache
for the view object instance.
How Entity-Derived View Attributes are Populated
In summary, there are two sorts of caches:
• Entity caches
• View caches
As entity-derived attributes are concerned, entity caches hold the data in
those attributes, and view caches hold pointers to the data.
How SQL-Only Attributes are Populated
SQL-only view attributes retrieve data from the database just as entity-derived attributes
do. However, after the data is retrieved, SQL-only view attributes are NOT added to
the entity cache. Instead, when the view cache is created, the appropriate attribute is
populated directly with the data, instead of a pointer to data in an entity cache as
shown below:
SQL-only view
view attributes
Entity-Derived vs. SQL-Only View Attributes
The only reason to use an entity-derived attribute is to make changes to
a database column. From Chapter 9, all updates to a database are made
through persistent entity attributes. If you need to change a database
column, it must do it through an entity-derived view attribute based on
a persistent entity attribute.
If you do not need to make changes (the attribute is read-only) a SQLonly attribute is more efficient than an entity-derived attribute because
it skips the step of storing the data in the entity cache and maintaining a
pointer to it.
However, there are a few reasons you might want to use an entityderived attribute
It May Save Space Within a View Cache
Contrast the figures below:
In the right figure, the data 90 and Executive are stored three times (once for each
row in the query result). In the left figure, a single entity object containing the data is
created, and multiple view rows can point to that entity object.
It May Save Space Within a View Cache
Using entity-derived attributes for a department having hundreds of
employees is a significant savings, but for a department with 10 to 20
employees the savings in memory is not worth the overhead of a twolevel caching system.
It Ensures Synchronization
Different view object instances can have overlapping data.
If the department’s name is changed in the AllEmployees’ view, it will not
automatically be changed in the others.
It Ensures Synchronization
If the DepartmentName view attribute is entity-derived, Department 90’s name will
only be stored once, in the Departments entity cache. Making a change in one of the
view caches really changes the data in the Departments entity cache. This change will
be immediately visible in the other view caches as shown below:
SQL-Only View Object Definitions
A SQL-only view object definition is a view object definition with no
entity usages.
SQL-only view object definitions bypass entity caching, saving not only
the resources required to populate entity attributes but also those
required to instantiate entity object instances.
View object definitions that retrieve read-only data should be SQL-only,
because their object definitions represent a substantial performance
improvement over view object definitions that contain entity usages.
Entity Object Usages and Table Aliases
Consider a view object definition, EmployeesView, with the following
Manager.EMPLOYEE_ID AS ManagerEmpId,
Manager.LAST_NAME AS ManagerName
Employee.MANAGER_ID = Manager.EMPLOYEE_ID;
Entity Object Usages and Table Aliases
If all the attributes are entity-derived, a single view row from EmployeesView must
point at multiple entity object instances as shown below.
This is done by adding multiple usages of Employees to EmployeeView. The two
usages, Employee and Manager, correspond to the two table aliases for
EMPLOYEES in the preceding query. EmployeeId, LastName, and Email are
derived from the Employee usage; ManagerId and ManagerName are derived
from the Manager usage.
Refining a View Object's Query
Once you select the attributes for a query, the View Object Wizard
creates a query to retrieve the persistent and SQL-only attributes. The
SELECT clause is a list of all the database columns that correspond
to the persistent and SQL-only columns. The FROM clause is a list of
the tables that correspond to the entity objects on which the view
object is based.
If a view object is based on more than one table, the wizard attempts
to assemble a WHERE clause for you.
Setting the WHERE and ORDER BY Clauses
You can change the WHERE clause (including the WHERE clause to do the
outer join), or add an ORDER BY clause, using the Query page of the View
Object Wizard shown here:
Do not type WHERE or
ORDER BY in the fields;
the wizard add those for
Expert Mode
This mode allows you to create view objects based on any valid SQL
query. Not only do you have control over the WHERE and
ORDER BY clauses of the query, but you can also type in the entire
query and specify the SELECT clause, the FROM clause, and even
other clauses such as GROUP BY. Instead of storing the query
clauses as attributes of the <ViewObject> XML tag, an expertmode view object stores the entire query as a single XML attribute.
There are two ways to use expert mode:
• With SQL-only view objects
• With view objects based on entity objects
SQL-only View Objects
You may have a view object with only SQL-only and transient
attributes. If you are not making changes to the database and you do
not need the advantages of synchronization or memory saving
features of entity objects, there is no reason to have any persistent or
entity-derived attributes at all.
In this case, you can use a SQL-only view object. These objects do
not use entity objects (which saves space and time if you do not need
them), but they also allow you to use expert mode easily.
SQL-only View Objects
When a SQL-only view object is created, JDeveloper creates
attributes for each query column, using the following convention:
• The first letter is capitalized.
• Underscores will be removed, and the first letter after them
will be capitalized.
• All other letters will be lowercase.
• Symbols not valid for Java identifiers (such as parentheses) will
be removed.
Expert Mode with Entity Objects Usages
You may need the query flexibility of a SQL-only view object, but you
want or need to use the entity-object layer (because you want to write to
the database or take advantage of the synchronization and space saving
provided by entity object). The expert mode can also be used with view
objects bases on entity objects, but this is more complicated.
When a persistent view attribute is created from an entity attribute,
JDeveloper maintains the mapping between the query column and the
entity attribute automatically. When using the expert mode you write the
SQL query yourself, and you have to specify the mappings yourself. This
can lead to errors and problems, especially with complex queries.
Expert Mode with Entity Objects Usages
For example, the query for an expert mode view object called
MgrReportsExpertView, based on a single entity object, Employees,
looks like the following:
Expert Mode with Entity Objects Usages
The following mappings should be made:
• EMPLOYEE_ID should map to a persistent view attribute
based on Employee's EmployeeId attribute.
• SALARY should map to a persistent view attribute based on
Employee's Salary attribute.
NUM_REPORTS should may to a SQL-only view attribute.
See book for an example of possible mapping errors you might make.
Usually ADF BC will detect mapping errors, and throw a
RowInconsistentException instead of corrupting the data.
Hands-on Practice:
Create View Object Definitions
Pages 342 to 356
Representing Relationships Between Query Result Sets
Relationships linking query result sets are represented by view links that
link view objects. A view link associates one or more attributes
(persistent, SQL-only, entity derived, or transient) in one view object
(called the "source" view object) with one or more persistent or SQLonly attributes in another (the "destination” view object).
View Link SQL
When a view link is created, JDeveloper creates a parameterized SQL
expression called the view link SQL, which represents the relationship
between the view objects. The view link has a bind variable for each
source attribute, and sets each bind variable equal to the SQL expression
for the corresponding destination attribute.
For example, consider a view link EmpDeptFkLink, which associates
the DepartmentId attribute in DeptMgrView (source) with the
DepartmentId attribute in EmpDeptView (destination). The SQL
expression for the destination attribute is
Employee.DEPARTMENT_ID, so JDeveloper creates an expression
setting a bind variable (a stand in for the source attribute) equal to
Employee.DEPARTMENT_ID, as follows:
:1 = Employee.DEPAERTMENT_ID
View Link SQL
This expression is the view link SQL for EmpDeptFkLink.
ADF BC uses the view link SQL to associate a row of the source view
object with one or more rows of the destination view object. The
source view attributes are passed into the bind variable, and the resulting
SQL is added to the WHERE clause of the detail view object to return
a more restrictive set of rows.
View Link SQL
For example, consider a row of EmpDeptFkLink is used to create a
master-detail relationship between AllDepartments, and instance of
DeptMgrView, and EmployeesInDepartment, an instance of
EmpDeptView. Suppose the following row in AllDepartments’ view
cache row:
The value of JOB_ID in this row is passed as a bind variable to
EmpJobLink's SQL, yielding the following expression:
60 = Employee.DEPARTMENT_ID
View Link SQL
You can view and change view link SQL on the View Link SQL page
of the Create View Link Wizard, as shown below:
Entity Objects and View Link Accessors
Consider this view link. All the view link's source attributes are
persistent and are associated with attributes from a single entity object.
For example, in EmpJobLink, there was only one source attribute,
JobId, which was associated with a single entity object, Employees.
Entity Objects and View Link Accessors
A single entity instance, because it contains values for all source attributes, above
completely determines a set of destination view rows as shown below:
Entity Objects and View Link Accessors
In addition to being able to generate a view link accessor in the source
view object, you can have the option of generating one in the relevant
entity object. This adds an element to the entity object's XML file and a
getter method (such as getJobsView()) to the entity object class.
You can do this because all source attributes come from a single entity
View Link Directionality and Cardinality
The most commonly used view links are "parent-child" or "masterdetail" relationship. View links can also work in more complex ways.
Bidirectional View Links
You might want to be able to use a view link in both directions, not only
to access rows of the destination view object from a row of the source
view object, but to access rows of the source view object from a row of
the destination view object as well.
For example, you might want to have the option of using
EmpJobsLink to access rows of DeptEmpView from rows of
JobsView, such as the row corresponding to the following row of the
following query result:
Bidirectional View Links
You might want to use the EmpJobsLink in such a way that you can
traverse it from this row to access the rows of DeptEmpView with a
JOD_ID of IT_PROG. This can be done providing these conditions
are satisfied:
• You do not change the view linkSQL generated by JDeveloper.
• All of the source attributes are persistent or SQL-only.
One-to-One, One-to-Many, and Many-to-Many View Links
Like associations, view links have a cardinality. They have a lot in
common with association cardinality like the following properties:
• View links can be one-to-one, one-to-many, of many-to-many
like associations.
• A view link's cardinality affects the Java type of the view link
accessor attributes. The attribute corresponding to a "many" end
of a view link is a RowIterator. The attribute corresponding to a
"one" end of a view link is a Row.
Associations represent table relationships and are based on
identifications between table columns. View links can represent arbitrary
relationships between query columns. A table relationship can only be
many-to-many through the use of an intersection table, but a view link
can be many-to-many with no intersection.
One-to-One, One-to-Many, and Many-to-Many View Links
For example, consider a view link between DeptEmpView and JobsView, where
DeptEmpView's Salary is the source attribute, and the view link SQL is as follows:
Each row of DeptEmpView will correspond to many rows of JobsView (because
each employee's salary is within the salary range of many jobs) and each row of
JobsView will correspond to many rows of DeptEmpView (because each job's
salary range encompasses the salaries of many employees). However, there is no
intersection table-– EMPLOYEES and JOBS are the only tables used.
This relationship cannot be used in a bidirectional view link because it requires
changing the view link SQL. An intersection table must be used if the view link is to
be both many-to-many and bidirectional.
See further discussion in textbook.
Data Models
Once the view objects that will select the data the client needs and the view links
needed to link them have been created, an application module that represents the data
model can be created. From Chapter 9:
• An application module contains the view usages your client needs for a single
transaction. One view object can have several usages in a single application
• An application module specifies the way in which these view usages are related
by view links.
• These relationships are represented by a tree, called the application module's
data model.
• View usages represented by child nodes are details of the view usages
represented by the parent nodes.
Detail View Usages
You can use a view link accessor to get from a view row in one view
object to all the corresponding rows in another view object. However,
you can also associate master and detail rows by making a view usage a
detail in a data model.
Detail view usages are automatically synchronized with their masters.
Consider the following:
Here, the usage JobsView, JobsView1, is a detail of the usage of
DeptEmpView, DeptEmpView1.
See further discussion in textbook.
Nested Application Modules
You may find that a number of your application modules share part of their data
model. For example, you might find that, over and over again, you are using a
independent usage DeptEmpView with JobsView as its detail via EmpJobsLink.
You can save time by creating an application module with just the often-used portion
of your data model, and nest usages of this application module into other application
modules on the Application Modules page of the Application Module Wizard
shown here:
Hands-on Practice:
Create View Link and Application
Module Definitions
Pages 362 to 367
SQL-only View Attributes
These attributes map to a query column but are not based on any entity
attribute. The query retrieves data from the database and stores it directly
in the view attribute.
SQL-only attributes cannot be used to update the database, only retrieve
data. They can be more efficient than persistent attributes (if the
attributes can be read-only), because it skips the step of storing the data
in the entity object and maintaining a pointer to it.
A SQL-only attribute does not need to derive its value from a single
database column. You can specify any SQL expression (so long as it
requires only tables in the FROM clause of the view object's query). The
expression will be calculated in the database instead of in Java in the
middle tier. This can be faster than calculating attributes in Java, but you
cannot use entity object synchronization.
SQL-only View Attributes
A Java-calculated attribute will immediately change as soon
as relevant related attributes change in the cache. For
example, the attribute YearlyPay is designed to change as
soon as Salary or CommissionPct change. SQL-calculated
attributes will not change until existing data is posted and
the view object's query is re-executed.
Transient View Attributes
These attributes correspond to neither entity attributes nor SQL query
columns. They work just like entity-derived attributes do, and must be
populated by hand or as calculated attributes. However, unlike entityderived attributes, they do not correspond to transient entity attributes.
The main difference between types of view attributes is the way that they
are cached (which is holding copies of data in memory). The primary
benefit of caching is optimizing performance. ADF BC caches data in
the middle-tier, eliminating repeated trips to the database.
ADF BC uses a two-level form of caching:
• Maintaining caches for entity objects
• Maintaining caches view rows
It also provides other benefits when you understand the internal
workings of the attribute types.
Use and Reuse of Business Logic
View objects do all their writing through entity objects. Therefore, any
validation logic in your entity objects will get enforced for all persistent
attributes. Also, using persistent and entity-derived view attributes lets
you take advantage of other business logic (such as defaulting for
persistent view attributes, or calculation for entity-derived attributes) in
your entities.
Creating an XML Element for the Source View Object
When a view link is created, the source view object's XML file gets an XML accessor
element which is similar to an association's XML accessor element. They both contain
a unique accessor name and the name of the destination view object. For example,
when a view link called EmpJobLink between DeptEmpView and JobsView is
created, an XML accessor element called "JobsView" with a reference to the entity
object JobsView will be added to DeptEmpView.xml.
ADF BC treats view link accessors as view attributes. For example, you can think of
DeptEmpView having attributes called JobsView and JobsView1. These attributes
will not appear in the View Object Wizard, but you can pass them to getAttribyute()
method on the view object's view rows.
DeptEmpViewImpl.first().getAttribute("JobsView") will return the associated
view rows from JobsView.
Creating an XML File for the View Link
Like associations, view links have their own XML files. They contain the
logical definition of the view link, including elements that speciy the
view objects at each end of the view link, the XML accessor element
names for the destination view object, and the source and destination