在上一章,我們說到了 Entity Object 和一些基本 Entity的 Validation 的制訂,所以我們可以將一些相關的 Check,在 ADF 的Entity 中進行實作,然後如果發生相關 Exception,可以透過 ADF Framework 丟給前端的 JSP 或是 JClient 來顯示相關的錯誤,但是在這章節,我們將要來介紹 ADF 的另一項元件,就是 Data Model Component,其中包含 View Object、View Link 和 Application Module,以下我們將會慢慢針對這些主題一一說明,並且舉出一些例子。
首先針對之前的範例進行一下版本 Update,因為在寫到第 8 章前,Oracle 已經最
新 release最新版的 Oracle JDeveloper 10g(10.1.2),並且已經將原來的 9.0.5.2
的部分修正達 800 個 Bug,所以從這章起,將使用新版的 Oracle JDeveloper 10g。
轉換 Oracle JDeveloper 10g:
先到 c:\jdev9052\jdev\mywork,找到mywork這個資料夾,這個資料夾是所有你之前所做的範例存放區,所以先行將此資料夾複製。
我們到剛剛才 unzip 好的資料夾。
到 c:\ojdev1012\jdev下按下貼上,將剛剛所複製的mywork 複製到此目錄下,
將 c:\jdev1012\jdev\bin下的 jdevw.exe 捉到桌面當捷徑。
目前已經將之前所開發的相關 Project 移轉到新的 Oracle JDeveloper 版本。
打開你的 Oracle JDevloper 10g,點在 Applications 中按下開啟舊檔的圖示。
選到 mywork 資料夾,Oracle JDeveloper Default 會存放相關的Workspace 在此。
選到之前的Workspace,一一的開啟起來。
例如,點到 AdfOverviewWS這個Workspace 中,選到 AdfOverviewWS.jws 這個檔案,這是關於Workspace 的相關主要檔案。
如果你是從舊版的 Oracle JDeveloper 所做的Workspace,來到新版 Oracle
JDeveloper 中打開,則 Oracle JDeveloper會自動幫你做相關的 migrate。
Oracle JDeveloper 自動進行相關程式檔案修正。
如下圖所示,可以將之前的Workspace 做相關的 Import。
請剩餘的Workspace 陸續的自行開啟,這樣檔案才能進行mirgate。如下圖所示,將之前已經做過的範例一一開啟。
以上是轉換到 Oracle JDeveloper 1012 版本的作法,轉換到這個版本,可以修
正 Oracle JDeveloper 9052 這個版本將近 800 Bug,所以轉換過來後,我們可
以繼續往下看。
關於這一章,我們會來談有關於 OracleADF 中的 Data Model Component,在
之前,我們談到 OracleADF 中含有幾個 Component,之前談過 Entity Object、
Association等等,接下來,我們會來談有關於 View Object 部分,所以這章結束
後,應該可以對於 ADF Framework 有多一點的認識。
之前談過 Entity Object,會建立和後端 DB 的關係,當然會不會是和 DB Column 有關,則是看你對於 Entity Object是不是選擇 Persistent(持續),我們會在 ADF 中建立一個 Entity Cache,暫時 Cache Entity Object 的資料,至於我們本章的重點,Data Model Component,則是可以替我們去 Entity Cache 中去蒐集資料,以便提供給前端的 MVC程式使用,OracleADF 中,並不希望你直接去存取 Entity Object 或是 Association 等等,你需要建立 View Object、View Link 和 Application Module,才能給前端介面(JClient 或是 JSP)使用,所以我們會漸漸來做說明。
在 View Object 中,包含了兩種形式的 View Attribute,分別是 Entity-derived和
SQL-only 兩種,Entity-derived view attribute是代表基於 Entiy Object 中的 attribute,換言之,是和 Entity 會有所關係,其餘的都是 SQL-onlyviewattribute,只是一段 SQL,去找出你所需要的資料,我們會在範例中說明,View 端也有 View Cache,所以在 ADF中會有兩段 Cache,主要是要增加 Performance,所以 ADF 會幫你管理,將資料 Cache 在 Memory中,會提早存取的效能。
為了能趕緊有所感覺,我們先來看一個例子。
我們先介紹一下如何用之前所建的 ADF BC。 PS:本章例子參考 10g Handbook
先建立一個 ApplicationWorkspace。
請輸入名稱:HRApp,Prefix:hrapp,以及 WebApplication【Default】。
如下圖,可以先行 New 出一個新的 ApplicationWorkspace。
因為我們需要 Import 之前我們所建的 ADFBC,所以我們先在 Model Project
中,按下右鍵並且選擇 Project Properties。
如下圖,選到 Paths,並且在 Additional Classpath,選擇 Edit。
因為我們必須 Import 額外的 ADF BC 進來 Model 的Project,選擇 Add Entry。
因為我們要去 Import HR Project 的 ADF BC,所以我們選到 HR\Model\classes。
按一下 Select。
確定一下相關路徑,如果沒有問題,可以直接按下 確定。
接下來,直接點選 FileÎ Import 來 Import 已經有的 ADF BC。
選擇我們需要 Import 的類型,例如我們需要 ImportADF BC,我應該去選擇
如果還沒有連線,會需要先行建立。
選擇好後,可以直接按下確定。確認一下使用者帳號和密碼,也就是 DB 的帳號密碼。
下一步,需要 Import 相關的 XML 檔,所以請將目錄切到之前的 HR Project
下,切換到 HR\Model\classes\hr\model\businessdomain 下選 businessdomain.xml。
出現 Import 確認的對話方塊,選擇是否需要將 Object 加入你的新 Project。
所以我們可以 Import bussinessdomain 的 Component。接著我們來 Import 已有的 Data Model 的 Component。一樣的,我們選一下 檔案 Î Import。
選擇 Business Components 這種類型。
一樣的,我們選到 HR Project 下的 HR\Model\classes\model 下的 model.xml。
如下面的圖顯示,因為 HR Project 中 Model 並沒有建立,所以只會 Import businessdomain 這個 Package。
接著,我們接著建立 DataModel 的相關 Component,所以我們來建立一個
Business Component Diagram,在 Model 上按右鍵,選擇 New。
選擇 Business Components 中的 Business Components Diagram。
輸入 Name:Data Model Diagram,Package:hrapp.model.datamodel。
如下圖,我們已經為了 DataModel 部分建立一個 ADF BC UMLDiagram。
我們之前示範是如何從另一個 Project 中 ImportADF BC 進入一個新的 Project,當然你也可以重新建立,只是說明如何共用,一般來說,我個人都是建一份我系統所需要的 ADF BC。
接下來,我們來看一下一些範例,請往下頁看。
* 第二個範例:建立一個簡單的 View Object,包含不同型態 Attribute。接著,我們選到 View Object,可以建立一個 View Object。
點一下 View Object,並且拉到 Business Component Diagram,如果沒有和資料庫連線,會跳出確認對話方塊,輸入一下密碼確認。
我們將 View Object 拉到 Data Model Diagram中,我們可以看到這樣圖示,預設會顯示 ViewObject1。
接著我們將 ViewObject1 改成 JobsView,因為我們必須建立一個 View Object,來關連 Job 的 Entity Object。
所以我們看到導覽區中的ADFBC中的businessdomain,將Jobs這個Entity Object
向右拉取到 JobView 圖示中(注意:是圖示內)
拉取好後,如下圖顯示,會看到有一個 Entity Object Usage:Job1,所謂 EntityObject Usage 則是在 View Object加入一個 Entity Object,則該 Entity Object 則稱為 Entity Object Usage,在此引入一個觀念:
1. Entity-derived view attribute:則是該 View Attribute 是基於 Entity attribute,也就是說該 View attribute 是和該資料庫有直接關係。
2. SQL-only view attribute:則是該 View attribute 只是提供 Select,除了
Entity-derived view attribute以外,都可以稱為 SQL-only view attribute。
將圖放大一點。
將 Job1 點兩下,將名稱更改成 Job。
直接將 JobView 點兩下,可以打開 View Object Editor,如下圖。
選到 Attributes,預設會將 Jobs 的 View Object 的 View attribute 全選。
將 JobTitle、MinSalary 和 MaxSalary 的欄位選到 Available,僅僅留下JobId。
JobId 本身是 Entity-derived view attribute,因為他是基於 Jobs 這個 EntityObject,而接著我們來建立一個 SQL-only view attribute。我們點下面 New。
輸入 Name:JobTitle,Type:String。
在下面的Query Column,請輸入Alias:JobTitle、Type:VARCHAR2(35),Expression則是:Job.JOB_TITILE。
看一下 Query,其實 View Object另一個層面是在建立一段 SQL,所以剛剛我們
兩個欄位屬性不同,其實是在建立該 SQL,可以按一下 Test,來測試該段 SQL
是否正確,或是看一下 ExplainPlan,可以去看一下 SQLPerformance。
接下來,我們來看一下結果,所以我們必須要建立 Application module,好將 View
Object 包裝起來,所以選到 Application Module 並且拉到左邊。
如下圖,我們將一個 ApplicationModule 建立好。
我們將名稱 ApplicationModule1更改成為 TestModule。
將 JobsView 拉到 TestModule 的ApplicationModule 中,如下圖。
如下圖,已經將 JobsView 移到 ApplicationModule 中,可以開始進行測試。
我們到導覽區,可以看到已經有 TestModule加入導覽區,我們選一下右鍵,並
且選擇 Test。
看一下 DB連線資訊,按一下 Connect。
我們已經打開 Oracle Business Component Browser,我們可以看到兩個欄位,JobId
可以進行更改,但是 JobTitle 則是單純 Select。
所以看一下幾筆,JobId 可以修改,也就是 Entity-derived view attribute,而 JobTitle
則是代表 SQL-only view attribute,接下來繼續看一下例子。
剛剛我們已經示範了一個例子,該 View Object 包含兩個 Attribute,包括 JobId
是和底層的 Entity Object 是互相同步,然而,另一個 Attribute 則是採用 SQL-only
的 Attribute,所以該欄位只能 Select,
* 第二個範例:建立一個簡單的 View Object。
當我們點到我們剛剛建立的 DataModel Diagram,我們應該可以在 JDeveloper 右邊看到這個 Component Palatte,如果看不到,可以在最上排的 View 中選到 Component Palatte,將這個東西打開,我們可以選到 View Object,接著將該項拉
到 DataModel Diagram。
如下畫面,預設是會帶預設名稱,我們可以將名稱改為 DepartmentView。
我們將 DepartmentView點兩下,可以打開 View Object Editor,並且選到 Query。
我們輸入以下的 Query Statement,以下是將 EMPLOYEES 和 DEPARTMENTS這兩個 Table做 Join,並且抓出相關欄位。
我們按了一下 Test,可以去檢查該 SQLStatement 是否格式正確,以及指出相關問題點發生在哪。
先提供一下以下 Query Statement:
SELECTDepartment.DEPARTMENT_ID, Department.DEPARTMENT_NAME, Department.MANAGER_ID, Manager.LAST_NAME
FROM DEPARTMENTS Department, EMPLOYEES Manager
WHERE Department.MANAGER_ID = Manager.EMPLOYEE_ID
正確的話,可以看到 Query is vaild,代表 SQLStatement 是格式正確。
請選一下套用。
我們可以將 Attribute點開,可以看到 DepartmentId、DepartmentName、ManagerId
和 LastName,先選到 DepartmentId,注意,要選上圖的套用喔。
因為該欄位是 SQL-onlyAttribute,你必須要在整個 View Object Cache 中分辨每一筆資料列的不同,所以在 SQL-only 中 M,你必須要選 KeyAttribute,使得 DepartmentId 成為一個 Key 欄位,可以進行分辨資料列,接著,按一下確定。
我們將該 DepartmentView的 View Object 圖示,拉到我們的 TestModule 中,方
便我們將 View Object包裝成 Application Module。
接著,我們在 TestModule 按一下右鍵,選一下 Test。
選一下 Connect,可以連接到 Oracle 資料庫。
我們看到 DepartmentsView1,可以看到我們剛剛所設的 SQLStatement,已經成功的 Select出來,因為我們 DepartmentId有勾選 KeyAttribute,所以我們才能分辨不同的資料列。
我們找到 DepartmentId是 90 的,將 DepartmentName:Managerial更改名稱。
將 DepartmentName 更改成 plural,並且選擇 Commit,將資料 Commit。
接著我們關掉 Oracle Business Component Browser,我們再來開啟一次,可以找
到 DepartmentId為 90的,可以看到結果為:
資料不變,因為我們是實做 SQL-OnlyViewObject,所以 ADF BC不會幫你
Commit,所以本例子介紹 SQL_Only 的用法。
剛剛我們看到了兩個例子,包括我們建立兩個 View Object,其中一個是示範該 View Object 包含 Entity-derived view attribute和 SQL-only view attribute,另外一個例子,則是單純我們直接輸入 Query Statement,建立 SQL-only view Object,示範如何使用。
緊接著,我們要來示範一個例子,我們建立一個 View Object 中,包含兩個 Entity
Object Usage,看看如何使用。
一樣的,我們選一下 View Object,並且將其拉到 Data Model Diagram中,所以可以協助我們建立 View Object。
如下圖,我們將 View Object 拉好,並且定義名稱為 EmployeesView,且我們到導覽區看一下,我們可以看到已經建立一個 EmplyeesView,接著,我們即可以開始加入 Entity Object成為 Entity Object Usage。
我們先選到導覽區的 Employees 的 Entity Object,並且拉到剛剛所建立的
EmployeesView中,預設時,Entity Object Usage 會命名成 Employees1。
一樣的,我們將 Entity Object Usage 重新命名為 Employees。
一樣的動作,我們再去導覽區拉一個 Employees的 EntityObject 進來
EmployeesView中,並且更名成為 Manager,如下圖。
一樣的,我們在 EmployeesView上直接點兩下,可以協助我們開啟 View Object
Editor,我們可以繼續看以下內容。
打開 View Object Editor 後,可以看到已經有兩個 EntityObject 已經被選擇,其中兩個都是屬於 Employees這個 Entity Object。
我們點到 Manager(Employees)上,因為我們是用了兩次 Employees這個 Table,
所建立的Entity Object,所以View Object本身就是在建立一段SQL,所以本View Object 是在建立員工和主管的關係,所以必須拿員工檔中的主管員工編號欄位和另一個員工檔的員工編號欄位進行 Join,建立Where 條件。
所以確認 Association End 是 ManagerIdE…,而 Reference 的勾勾要打勾。因為當主管員工編號異動,則所有對應會立即更動,就需要打這勾勾。
接著,我們選到 Attributes 上,可以看到預測上,所有欄位都會全選,所以會看到那麼多欄位,但是我們並不需要那麼多,所以選全部向左,移除掉欄位。
當已經選好,會跳出警告訊息,因為至少需要選擇一個欄位,所以按一下 OK,
選擇你所需要的欄位。
所以我們選幾個欄位,包括 Employees中的 EmployeeId、LastName、Email 和
ManagerId,選擇向右選擇,可以將這些欄位拉到右邊。
一樣的,我們針對 Manager 這個 Entity Object Usage 中,我們選兩個欄位,包括
EmployeeId和 LastName。
其實以上的動作,就是在建立 SQL 中的 Select XXX,XXX fromtable where…..
其中 XXX即為我們所選的欄位。
我們將剛剛所選好的欄位選到右邊,如下圖所示:
我們切到該 Attributes 的選項,我們可以看到剛剛已經選到的欄位,我們可以看到一個欄位 EmployeeId1,因為已經有一個 EmployeeId,所以該欄位才會更名成這樣名稱。
所以我們將該名稱更名成:ManagerEmpId。
同樣的,我們將 LastName1 更名成 ManagerName,以便於辨識該名稱。
我們切到 Query 選項,我們可以看到產生的 SQLStatement,其實我們之前的動作,都是在建立這段 SQL,這是很重要的觀念。
確定後,我們看到 hrapp.model.datamodel 中有一個 View Object:EmployeesView,先行進行存檔。
我們回到 Data Model Diagram,我們已經完成建立 View Object,我們接著需要將
該 View Object 加入 Application Module,所以我們將該 View Object 拉到
ApplicationModule。
如下圖,我們已經將該 View Object 拉入 Application Module。
我們直接 Run Oracle Business Component Browser,可以看到該畫面,我們看到其中一個 View Object則是 EmployeesView1,我們先行選擇該 View Object。
我們去找到 EmployeeId是 201,我們注意一下,我們的 ManagerId 和
ManagerEmpId應該是需要同步,因為該欄位互相 Join,所以應該一樣。
我們將 ManagerId 更改成 101,因為該 View Object 是基於 Entity Object 的,所以應該會和 DB 同步,所以更改完後,我們先行 Commit,並且關掉視窗。
我們重新打開 Oracle Business Component Browser,找到員工編號是 201 的,因
為剛剛我們更改後,已經 Commit進入資料庫,所以當我們再次要求,就已經是我們新改的值,且 ManagerId 和 ManagerEmpId 是一樣的。
我們再來看一下另外的例子,我們也可以使用專家模式,直接撰寫 SQL 來建立我們的 View Object,接下來,就是相關的範例。
我們可以從 Component palette中將 View Object 拉到 Data Model Diagram。
我們可以在 Data Model Diagram中看到已經拉好圖示,注意,我們已經將 Default
的名稱改掉,改成 ManagersView。
我們回到導覽區,將剛剛的 Employees的 Entity Object 選好,直接拉到
ManagersView中。
如下圖所示,我們已經拉好相關 Entity Object,這裡我們稱為 EntityUsage。
將 Entity Usage的名稱 Employees1更名成為 Manager。
我們直接在 Data Model Diagram中的 ManagersView點兩下,可以打開 View
Object Editor。
我們選到 Attributes,可以看到 Employee 這個 Enitty Object 所有欄位,但是我們不需要那麼多,所以我們移除全部欄位,除了 EmployeeId以外。
實務上,我們會全部移除,再來新增,我個人認為比較好。
如下圖,只剩下一個 EmployeeId,這是透過 Entity Object 取的。
切到 Query 選項,可以看到實際 SQL 如下,準備來使用專家模式。
我們勾了 Expert Mode,接下來我們輸入以下 SQLStatement。
輸入以下的 SQLStatement:
SELECTManager.EMPLOYEE_ID, Manager.LAST_NAME, Manager.SALARY, Manager.JOB_ID,
COUNT(Reports.EMPLOYEE_ID)AS NUM_REPORTS FROM EMPLOYEES Manager, EMPLOYEES Reports
WHERE Manager.EMPLOYEE_ID = Reports.MANAGER_ID GROUPBYManager.EMPLOYEE_ID,
Manager.LAST_NAME, Manager.SALARY, Manager.JOB_ID
我們另外 Join 一個 Employee 的 Table,將 EmployeeId和 ManagerId 進行 Join,並且進行 Group By,如上 SQLStatement 所示。
寫完後,我們可以選一下 Test,測試一下 Query 正不正確。
接下來,我們來建立 Attribute Mapping。
因為我們剛剛在於 Entity Object 中,我們只選到 EmployeeId,所以只有該欄位是 Entity ObjectAttribute,其餘都是 SQL-onlyAttribute,我們可以重新定義 Attribute Mapping,所以我們將 LastName拉下來,可以選到 Managers下的 LastName,換言之,就是該欄位變成 Entity Object Related,不再是 SQL-only attribute。
一樣的,JobId 也一樣進行更動 Attribute Mapping。
接下來,我們必須將該 View Object 進行包裝,所以我們需要將 View Object 拉到
TestModule中。
如下圖所示,可以看到已經大致包裝好。
一樣的,我們選一下 Test,去啟動 Oracle Business Component Browser。
選一下 Connect,來進行測試。
選到 ManagersView,我們找到 employeeId是 101 的,我們看到 LastName 是
Kochhar,因為該欄位已經是 Entity Related,所以我們更動一下值。
我們將 LastName 更改成為 Kochhar2,並且進行 Commit,我們切回
EmployeesView1中。
可以看到 LastName 已經可以更改成為 Kochhar2,因為該欄位是 Entity Object
Attribute,而其他欄位則是 SQL_only,所以改值也不會更動。
接下來,我們來談 View Link 和 ApplicationModule,View Link 可以說是底層就
是 Association,何謂 Association,就是兩個 Entity Object的關係,一般來說,就
是 FK,所以 View Link 是兩個 View Object的關係,之前提過,View Object 本身就是一段 SQL,所以 View Link 是兩段 SQL的 Join,達成 Master-Detail的關係。其中有包括 1 對多、1 對 1、多對多等等,詳細請參閱 Database Design。
關於 Application Module,簡單的說,就是將所有 EntityObject、Association、View Object 和 View Link 的東西,全部打包成一包,包成一個 Aopplication Module,可以提供給予前端 View 作為 Model,其中 Application Module 可以是巢狀式,可以是 Application Module 包另一個 Application Module,所以可以因應需求使用,基本上,你應該不用針對 Application Module做任何事,除非需要進階使用,之後,我們也會看到相關的範例。
我們來看一下一個簡單範例,另外的進階範例,請參考 OTN 或是 10g handbook。我們持續使用前面範例的東西,我們之前共建立了 4 個 View Object和一個
ApplicationModule,我們接下來示範一下 View Link 和 ApplicationModule。
Data Model Diagram。
我們先於 Component 中選到View Link,並且拉到
我們從 ManagerView拉到 EmployeesView,來建立 View Link。
如下圖所示,Default 的 View Link 已經建立好,接下來,我們進行修改。
我們點到該線,可以看到該View Link名稱和SourceAccessor Name和Destination
Accessor Name,所以我們可以將 ViewLink1 點兩下,讓該處可以變成編輯。
如下圖,我們將 View Link Name 更改一下。
我們將 View Object 更名為 EmpManagerFkLink。
我們直接將 EmpManagerFkLink點兩下,可以打開 View Link Editor。
這兩個 View Object 的關係,可以於 Cardinality 選取相對的關係,因為
ManagerView和 EmployeesView是適用 0…1 to *,所以我們選第一個。
我們看一下 View Link SQL,這邊是表示 SQLWhere,也就是條件句,也就是員工檔中的主管員工編號去 Join 主管員工編號,可以達成 Master-Detail關係。
看一下 View Link Properties,因為我們選 0…1 to *,所以 Accessor Name 只有一邊可以編輯,有時候,這個名稱是蠻重要的。
我們可以將 DestinationAccessorName 更名成 ReportsView。
我們之前的 TestModule,是我們上一個範例的測試 ApplicationModule,所以我們先去除掉,再建立一個新的,所以我們先在 TestModule 中按一下右鍵,選一
個 Erase fromDisk,可以將 TestModule 清除掉。
接下來,我們可以在 Component 中選到 Application Module,並且拉到 Data Model
Diagram。
我們將 DefaultApplication Module Name 更名成 HrAppModule。
將剛剛所拉好的 Model,拉到 HrAppModule,即可以建立好 HrAppModule。
一旦拉好,如下圖所示:
在導覽區按一下 HrAppModule,並且按右鍵選一下 Test。
選一下 Connect。
你可以看到 EmpManagerFkLink1 這個 Node,可以看到相關的 Master-Detail的關係,當然之後這些都可以提供 View 端,成為 Model。
一樣的,在 HrAppModule 中,不止有 EmpManagerFkLink 的 Model,同時也有單純的 EmployeesView1 的 View Object,都可以提供前端 View 使用。
在這 8 章完成後,ADFBC已經大致告一段落,不敢說所有觀念都對,但是希望可以讓大家對於 OracleADF BC有多一點認識,接下來的章節中,我們會來介紹 View 端,至於其餘進階章節會陸續加入,希望大家持續加油。