1.Ofbiz 介紹:

? Ofbiz(http://www.ofbiz.org) 是 Open Source 的商務軟件系統,充分利用了各優秀的的Open Source 項目,
像 Tomcat, Ant, BeanShell, Jboss 等,構建了一個強大的系統平臺,Ofbiz 已經完成了大部分商務類軟件系統
都需要的部件,像用戶認證、工作流、商務規則處理等,Ofbiz 的核心技術在于 Entity Engine,其他的組件基本都
是基于它的。簡單來說 Entity Engine 的主要功能是將數據庫表創建、對象與數據表的映射、對象的查詢等做了強大
封裝,你可以在一個簡單的 XML 文件中定義數據庫表結構,Ofbiz 會自動幫你在數據庫建表,并動態生成映射對象,
你在程序中可以只考慮對 Object 的處理,Ofbiz 會自動通過事務邏輯更新到數據庫中。Ofbiz 宣稱的優點之一是用
很少的 Code 完成復雜的處理。

2.Ofbiz 下載與安裝

? 首先要安裝 J2SDK1.4,到 http://java.sun.com 上下載,安裝后設定 JAVA_HOME 環境變量為 J2SDK 的安裝目錄。

? 訪問網站 http://www.ofbiz.org,上面有下載的連接,請選擇 Complete 包,因為這個包中已經包含了運行 Ofbiz
的所有東西,下載下來解開后就可以運行了。

? 解開 Ofbiz 包到一個目錄下,假設是 “C:\ofbiz”,該目錄下將會有 catalina 和 ofbiz 兩個目錄, catalina
目錄是 Tomcat 的目錄,Ofbiz 對其配置做了修改,ofbiz 目錄是 Ofbiz 的程序代碼目錄。在命令行狀態下進入
“c:\ofbiz\catalina\bin” 目錄,運行“ ofbiz run”命令,就可以啟動 Ofbiz,啟動后你可以用瀏覽器訪問
“http://localhost:8080/ecommerce”,這可以訪問 Ofbiz 的電子商務模塊,通過頁面上面的連接你可以訪問到
其他模塊。


3.Ofbiz Schema 的創建

Ofbiz 應用入門:

? 以一個實例說明,假設我們需要建一個客戶資料表,起名為 StudyCustomer,各個段分別如下:
? StudyCustomer {
??? customerId????? Integer,
??? customerName??? String,
??? customerNote??? String,
? }

? 我們來實現基本的數據操作---增/刪/改/查詢,具體步驟如下:


? 1.在 XML 文件中定義數據 Schema:
??? 需要用到三個文件,一個是我們要建的項目的 entitymodel_xxx.xml 和 entityengine.xml,還有
??? entitygroup.xml,
??? entitymodel_xxx.xml 是需要我們自己創建的,假設我們起名為 entitymodel_study.xml,放在
??????????????? “c:\ofbiz\ofbiz\commonapp\entitydef”目錄下,
??? entityengine.xml 是 Ofbiz 已經有的,放在 “c:\ofbiz\commonapp\etc”目錄下,用來包含我們
??????????????? 定義的 entitymodel 文件。
??? entitygroup.xml? 也是 Ofbiz 已經有的,跟 engityengine.xml 在同一目錄下,我們需要把我們的
??????????????? Schema 定義加入到該文件中

??? entitymodel_study.xml 文件的定義格式如下:
<!--================================================================================-->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE entitymodel PUBLIC "-//OFBiz//DTD Entity Model//EN"

"http://www.ofbiz.org/dtds/entitymodel.dtd">

<entitymodel>
?? <title>Entity of an Open For Business Project Component</title>
?? <description>None</description>
?? <copyright>Copyright (c) 2002 The Open For Business Project - www.ofbiz.org</copyright>
?? <author>None</author>
?? <version>1.0</version>

? <!-- ========================================================= -->
? <!-- ======================== Data Model ===================== -->
? <!-- The modules in this file are as follows:????????????????? -->
? <!--? - org.ofbiz.commonapp.study -->
? <!-- ========================================================= -->


? <!-- ========================================================= -->
? <!-- org.ofbiz.commonapp.study -->
? <!-- ========================================================= -->

?? <entity entity-name="StudyCustomer"
???????? package-name="org.ofbiz.commonapp.study"
?? title="Study Customer Entity">
?<field name="customerId" type="id-ne"></field>
?<field name="customerName" type="long-varchar"></field>
?<field name="customerNote" type="long-varchar"></field>
?<prim-key field="customerId"/>
? </entity>
?</entitymodel>

<!--================================================================================-->

? 這個 XML 文件中的 Tag 基本是看得明白的,只是 field 的 type 是 Ofbiz 已經預定義好的,這
是為了保證數據庫間的遷移。

? 在 entityengine.xml 加入我們剛才定義的文件,加入一行在合適的位置:
?? <resource loader="mainfile" location="entitymodel_study.xml"/>
? 具體放的位置我們可以通過查看 entityengine.xml 找到,里面已經有加好的其他文件。

? 在 entitygroup.xml 加入我們的 Schema 定義,在后面加入一行
?? <entity-group group="org.ofbiz.commonapp" entity="StudyCustomer" />

? 這樣我們就定義好了 Schema,現在把 c:\ofbiz\commonapp\etc\entityengine.xml 拷貝到
? c:\ofbiz\catalina\shared\classes 目錄下,這點要切記,我以前就因為沒有拷貝,最后 Schema
? 怎么也創建不了。

? 重新啟動 Ofbiz,訪問 URL: http://localhost:8080/webtools,點擊右上方的 "Login" 鏈接,
? 用 admin/ofbiz 登錄,登錄進入后選擇鏈接“Check/Update Database”,這時會出現 Check 的 Form,
? 該表單可以只檢驗 Schema 是否改變,默認的 GroupName 是“org.ofbiz.commonapp”,這個不需要變,
? 點擊“Check Only”按鈕,Ofbiz 會檢驗變動情況,顯示出一個完整的列表,你可以查一下是否有我們剛建的
? "StudyCustomer",如果沒有,可能是我們前面定義的有些問題,檢查一下再重新做。

? 在檢查到以后,可以再選擇“Check and Add Missing”,這是 Ofbiz 很強大的一個功能,你在 XML 中新
? 增了表,或在某個表中新增了段,它會自動映射到數據庫中,避免我們去直接操作數據庫。

? 現在已經完成了 StudyCustomer Schema 的創建,如果想檢驗一下是否有表創建,我們可以用編輯器打開
? c:\ofbiz\data\ofbiz.script ,在里面查詢 CREATE TABLE StudyCustomer 的字樣,如果前面沒有
? 問題,我們可以找到的。

?

4.如何使用已經定義的 Schema

如何使用已經定義的 Schema

?? Ofbiz 遵循 MVC 的設計模式,在 View 端,即 JSP 端主要使用 Ofbiz 定義的 Tag 來顯示或
?? 提取數據,Control 是一個 Controller Servlet,我們在 Controller Servlet 的 URI mapping
?? 配置文件中定義各 URL 應該指向什么程序,這樣,通過這個 mapping 配置文件,可以保證我們各個頁面
?? 及具體處理程序之間的獨立性,例我們可以通過修改這個配置文件就可以改變某個 Form 的 Post Action
?? 的 URL,而不需要修改實際的 HTML 或 JSP 代碼。

?? Ofbiz 中定義了 Regions 的概念,即將一個 HTML 頁面分成幾個區域,像 Top, Left, Right, Main
?? 等,通過這些 Regions 我們可以方便的組合 UI 界面,并且可以方便改變各部分所處的位置,如我們可以
?? 把菜單很容易的從上方移到下方,只需要改變一個配置文件。Regions 類似于 HTML 中的 Frame,但它是
?? 通過一個頁面來組合界面,Frame 是通過幾個頁面顯示在不同的幀中,Frame 的控制比較復雜,而且需要
?? 改變相關的程序。

?? 在 Ofbiz 中,我們可以直接在 JSP 中操作 Schema 定義的 Object,即我們剛定義的 StudyCustomer,
?? 示例如下:


<%@ taglib uri="ofbizTags" prefix="ofbiz" %>

<%@ page import="java.util.*" %>
<%@ page import="org.ofbiz.core.util.*, org.ofbiz.core.pseudotag.*" %>
<%@ page import="org.ofbiz.core.entity.*" %>

<jsp:useBean id="delegator" type="org.ofbiz.core.entity.GenericDelegator" scope="request" />
<jsp:useBean id="security" type="org.ofbiz.core.security.Security" scope="request" />

<%if(security.hasEntityPermission("PARTYMGR", "_VIEW", session)) {%>

<%
? try {
??? delegator.create("StudyCustomer",
????? UtilMisc.toMap("customerId","1","customerName","Cust1","customerNote","Customer Note 1"));

??? Iterator custs =??????????????

UtilMisc.toIterator(delegator.findAll("StudyCustomer",UtilMisc.toList("customerId","customerName","customerNote")));

??? while(custs.hasNext())
??? {
?GenericValue cust = (GenericValue)custs.next();
?out.println(cust.getString("customerId"));
?out.println(cust.getString("customerName"));
?out.println(cust.getString("customerNote"));
??? }
? } catch(Exception e)
? {
??? out.println(e.getMessage());
? }
%>
<%}else{%>
? <h3>You do not have permission to view this page. ("PARTYMGR_VIEW" or "PARTYMGR_ADMIN" needed)</h3>
<%}%>


? 這段程序挺容易理解,先是通過 delegator 創建一個 Object,該 Object 將會由 Ofbiz 自動同步到
數據庫中。然后通過 delegator 的 findAll 取到所有已保存的 Object,最后通過一個 Iterator 對象
顯示出來。

? 這個程序起名為 testofbiz.jsp,為簡單起見,我們放到 Ofbiz 已有的一個 Webapp 的目錄下,放到
c:\ofbiz\ofbiz\partymgr\webapp\party 目錄下。然后我們需要修改兩個配置文件:controller.xml
和 regions.xml,這兩個文件就是我們上面提到的 mapping 和 regions 配置文件。

? 這兩個文件都在:c:\ofbiz\ofbiz\partymgr\webapp\WEB-INF 下,在 controller.xml 中加入下面

?? <request-map uri="testofbiz">
????? <description>Test Ofbiz</description>
????? <security https="false" auth="false"/>
????? <response name="success" type="view" value="testofbiz"/>
?? </request-map>
? 和
?? <view-map name="testofbiz" type="region"/>
?
? 加入位置請參照 controller.xml 中已經有的配置。在 regions.xml 中加入:
?? <define id='testofbiz' region='MAIN_REGION'>
?????? <put section='title'>Test Ofbiz</put>
?????? <put section='content' content='/party/testofbiz.jsp'/>
?? </define>
? 具體加入位置請參考已有的配置。

? 配置完后,重新啟動 ofbiz,然后訪問 URL:
? http://localhost:8080/partymgr/control/testofbiz

? 由于我們在 testofbiz.jsp 程序中使用了 Ofbiz 的安全控制機制,系統會提示現在沒有訪問
? 權限,需要登錄,點擊右邊的“Login” 用 admin/ofbiz 登錄后會看到我們程序 testofbiz.jsp
? 的運行結果。如果需要增加新記錄,請修改

? UtilMisc.toMap("customerId","1","customerName","Cust1","customerNote","Customer Note 1"));

? 中的各個段的值,然后再訪問 http://localhost:8080/partymgr/control/testofbiz,如果不修改
? 而直接訪問那個 URL 時,系統會提示 Primary key 沖突。


5.按照顯示與邏輯分離的原則使用 Schema:

? 上篇講了如何在 JSP 中使用創建的 Schema 對象,這次我們來講述一下如何把程序
邏輯放到 JavaBeans 中,把顯示處理放到 JSP 中,并使用 controller.xml 將兩
部分整合起來。

? 首先我們來創建一個 JavaBeans,來完成Add/Get/Delete/Update Schema 對象
的操作,程序文件名為 TestOfbiz.java,放置在
? c:\ofbiz\ofbiz\testOfbiz\com\geeyo\ofbiz 目錄下, 具體程序如下:

>=================================================================
package com.geeyo.ofbiz;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.net.*;
import org.ofbiz.core.util.*;
import org.ofbiz.core.entity.*;
import org.ofbiz.core.service.*;
import org.ofbiz.core.security.*;
import org.ofbiz.core.stats.*;

public class TestOfbiz
{
? public static void main(String[] args)
? throws Exception
? {
???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
???? delegator.create("StudyCustomer",UtilMisc.toMap("customerId","3","customerName","Kane3","customerNote","This is test customer.3"));

???? Iterator custs = UtilMisc.toIterator(delegator.findAll("StudyCustomer",UtilMisc.toList("customerId","customerName","customerNote")));

???? while(custs.hasNext())
???? {
??????? GenericValue cust = (GenericValue)custs.next();
??????? System.out.println(cust.getString("customerId"));
??????? System.out.println(cust.getString("customerName"));
??????? System.out.println(cust.getString("customerNote"));
???? }
? }

? public static String createNewRecord(HttpServletRequest request, HttpServletResponse response)
? throws Exception
? {
???? Map paras = UtilMisc.getParameterMap(request);

???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
???? delegator.create("StudyCustomer",paras);

???? return "success";
? }

? public static String lookAllRecords(HttpServletRequest request, HttpServletResponse response)
? throws Exception
? {
???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
???? Iterator custs = UtilMisc.toIterator(delegator.findAll("StudyCustomer",UtilMisc.toList("customerId","customerName","customerNote")));

???? Collection col = new ArrayList();

???? while(custs.hasNext())
???? {
??????? GenericValue cust = (GenericValue)custs.next();
??????? col.add(cust);
??
???? }

???? request.getSession().setAttribute("search_results",col);

???? return "success";
? }

? public static String findRecord(HttpServletRequest request, HttpServletResponse response)
? throws Exception
? {
???? String id = (String)request.getParameter("customerId");

???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");

???? try {
??????? GenericValue cust = delegator.findByPrimaryKey("StudyCustomer",UtilMisc.toMap("customerId",id));

??????? request.getSession().setAttribute("edit_cust",cust);
???? } catch (GenericEntityException gee) {
??????? Debug.logWarning(gee);
???? }

???? return "success";
? }

? public static String updateRecord(HttpServletRequest request, HttpServletResponse response)
? throws Exception
? {
???? Map paras = UtilMisc.getParameterMap(request);

???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
???? GenericValue cust = delegator.findByPrimaryKey("StudyCustomer",UtilMisc.toMap("customerId",paras.get("customerId")));
???? cust.setNonPKFields(paras);
???? cust.store();

???? request.getSession().setAttribute("edit_cust",cust);

???? return "success";
? }

? public static String removeRecord(HttpServletRequest request, HttpServletResponse response)
? throws Exception
? {
???? String strId = request.getParameter("id");
???? GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
???? GenericValue cust = delegator.findByPrimaryKey("StudyCustomer",UtilMisc.toMap("customerId",strId));
???? cust.remove();

???? return "success";
? }
?
}


>=================================================================


程序中的處理大部分可以看懂的,其中有個功能,是
? Map paras = UtilMisc.getParameterMap(request);
這是 Ofbiz 的一個有趣但非常有用的功能,它是把 request 中各段的名字和值映射到一個 Map
對象中,然后使用
? cust.setNonPKFields(paras);
就可以賦給 Object cust 的各個段,免了我們使用 request.getParameter("name")來取各個
值,在值很多的時候這個功能可以大大減少冗余代碼量。

? 基本程序的邏輯是這樣的,
? 1.從 request 讀取傳來的值
 2.使用 delegator 來處理,Add/Update/Delete/Query
? 3.將返回結果放到 Session 中傳給 JSP

? 我做了個 Ant build.xml 文件可以幫助編譯,把這個文件放在:
?? c:\ofbiz\ofbiz\testOfbiz\ 目錄下,然后在命令行窗口下進入該目錄,敲入 ant
? 來編譯(需要保證已經安裝 Ant),編譯后的 .class 會放在
?? c:\ofbiz\ofbiz\testOfbiz\com\geeyo\ofbiz 下,
? 拷貝 c:\ofbiz\ofbiz\testofbiz\com 目錄到 c:\ofbiz\ofbiz\partymgr\webapp\WEB-INF\classes
? 目錄下。

? build.xml
>=============================================================================

<project name="TestOfbiz" default="dist" basedir=".">
??? <description>
??? Test ofbiz
??? </description>

? <!--test cvs-->
? <!-- set global properties for this build -->

? <property name="src" location="."/>
? <property name="build" location="."/>

? <property name="lib_dir"? location="c:/ofbiz/catalina/shared/lib"/>
? <property name="lib1_dir"? location="c:/ofbiz/catalina/common/lib"/>

? <path id="project.class.path">
??? <fileset dir="${lib_dir}">
?????? <include name="*.jar"/>
??? </fileset>
??? <fileset dir="${lib1_dir}">
?????? <include name="*.jar"/>
??? </fileset>
? </path>

? <target name="init">
??? <!-- Create the time stamp -->
??? <tstamp/>
??? <!-- Create the build directory structure used by compile -->
??? <mkdir dir="${build}"/>
? </target>

? <target name="compile" depends="init"
??????? description="compile the source " >
??? <!-- Compile the java code from ${src} into ${build} -->
??? <javac srcdir="${src}" destdir="${build}">
????? <classpath refid="project.class.path"/>
??? </javac>
? </target>

? <target name="dist" depends="compile"
??????? description="generate the distribution" >
??? <!-- Create the distribution directory -->
? </target>

? <target name="clean"
??????? description="clean up" >
??? <!-- Delete the ${build} and ${dist} directory trees -->
? </target>
</project>


>=============================================================================

然后我們來創建 JSP 程序,JSP 程序全部放在
? c:\ofbiz\ofbiz\partymgr\webapp\party 下面

? 1.listofbiz.jsp
>=============================================================================

<%@ taglib uri="ofbizTags" prefix="ofbiz" %>

<%@ page import="java.util.*, org.ofbiz.core.service.ModelService" %>
<%@ page import="org.ofbiz.core.util.*, org.ofbiz.core.pseudotag.*" %>
<%@ page import="org.ofbiz.core.entity.*" %>
<jsp:useBean id="security" type="org.ofbiz.core.security.Security" scope="request" />
<jsp:useBean id="delegator" type="org.ofbiz.core.entity.GenericDelegator" scope="request" />

<script language="JavaScript">
? function confirmDelete()
? {
???? return confirm("Are your sure to delete?");
? }
</script>


<%if(security.hasEntityPermission("PARTYMGR", "_VIEW", session)) {%>

<table width="600" align="center">
? <ofbiz:if name="search_results">
?? <tr><th>Id</th><th>Name</th><th>Note</th><th></th></tr>
??? <ofbiz:iterator name="cust" property="search_results">
????? <tr>
??????? <td><ofbiz:entityfield attribute="cust" field="customerId"/></td>
??????? <td><ofbiz:entityfield attribute="cust" field="customerName"/></td>
??????? <td><ofbiz:entityfield attribute="cust" field="customerNote"/></td>
??????? <td>
????????? <a href='<ofbiz:url>/showtest?customerId=<ofbiz:entityfield attribute="cust" field="customerId"/></ofbiz:url>' class="buttontext">[Edit]</a>
????????? <a href='<ofbiz:url>/removetest?customerId=<ofbiz:entityfield attribute="cust" field="customerId"/></ofbiz:url>' class="buttontext" onclick="return confirmDelete()">[Remove]</a>
??????? </td>
????? </tr>
???? </ofbiz:iterator>
??? </ofbiz:if>
</table>
<table width="200" align="center">
? <tr>
? <td><a href='<ofbiz:url>/createTestForm</ofbiz:url>'>Create customer</a></td>
? </tr>
</table>

<%}else{%>
? <h3>You do not have permission to view this page. ("PARTYMGR_VIEW" or "PARTYMGR_ADMIN" needed)</h3>
<%}%>

>=============================================================================

?上面程序中需要說明的是
? <ofbiz:if name="search_results">
?和
? <ofbiz:iterator name="cust" property="search_results">,
?
?<ofbiz:if name="search_results"> 是用來檢驗在 session 或 pageContext 對象
中是否包含 search_results 對象,該對象是由我們的程序放到 session 中的。
?<ofbiz:iterator name="cust" property="search_results"> 是用來循環讀取對象
search_results(是個 Collection 對象)中存儲的各對象,并賦給cust,然后在循環體
中,我們就可以用 cust 對象來讀取各個段的值了。


2.createofbiz.jsp
>=============================================================================

<%@ taglib uri="ofbizTags" prefix="ofbiz" %>

<%@ page import="java.util.*, org.ofbiz.core.service.ModelService" %>
<%@ page import="org.ofbiz.core.util.*, org.ofbiz.core.pseudotag.*" %>
<%@ page import="org.ofbiz.core.entity.*" %>
<jsp:useBean id="security" type="org.ofbiz.core.security.Security" scope="request" />
<jsp:useBean id="delegator" type="org.ofbiz.core.entity.GenericDelegator" scope="request" />
<%if(security.hasEntityPermission("PARTYMGR", "_VIEW", session)) {%>

<form method="post" action="<ofbiz:url>/createTest</ofbiz:url>" name="createofbiz">
<table width="300" align="center">
? <tr>
?? <td>Id</td><td><input type="text" name="customerId" size="20"></td>
? </tr>
? <tr>
?? <td>Name</td><td><input type="text" name="customerName" size="20"></td>
? </tr>
? <tr>
?? <td>Note</td><td><input type="text" name="customerNote" size="30"></td>
? </tr>
? <tr>
?? <td></td>
? <td><input type="submit"></td>
? </tr>
</table>
</form>

<%}else{%>
? <h3>You do not have permission to view this page. ("PARTYMGR_VIEW" or "PARTYMGR_ADMIN" needed)</h3>
<%}%>
>=============================================================================

? 這個程序很容易理解,需要注意的是每個文本框的名字,要跟 Schema StudyCustomer 的各
個段一致,以使程序中跟容易處理。

?3.showofbiz.jsp
>=============================================================================

<%@ taglib uri="ofbizTags" prefix="ofbiz" %>

<%@ page import="java.util.*, org.ofbiz.core.service.ModelService" %>
<%@ page import="org.ofbiz.core.util.*, org.ofbiz.core.pseudotag.*" %>
<%@ page import="org.ofbiz.core.entity.*" %>
<jsp:useBean id="security" type="org.ofbiz.core.security.Security" scope="request" />
<jsp:useBean id="delegator" type="org.ofbiz.core.entity.GenericDelegator" scope="request" />
<%if(security.hasEntityPermission("PARTYMGR", "_VIEW", session)) {%>

<form method="post" action="<ofbiz:url>/updateTest</ofbiz:url>" name="updateofbiz">
<table width="300" align="center">
? <tr>
?? <td>Id</td><td><input type="text" name="customerId" size="20" value="<ofbiz:entityfield attribute="edit_cust" field="customerId"/>"></td>
? </tr>
? <tr>
?? <td>Name</td><td><input type="text" name="customerName" size="20" value="<ofbiz:entityfield attribute="edit_cust" field="customerName"/>"></td>
? </tr>
? <tr>
?? <td>Note</td><td><input type="text" name="customerNote" size="30" value="<ofbiz:entityfield attribute="edit_cust" field="customerNote"/>"></td>
? </tr>
? <tr>
?? <td></td>
?? <td><input type="submit"></td>
? </tr>
</table>
</form>

<%}else{%>
? <h3>You do not have permission to view this page. ("PARTYMGR_VIEW" or "PARTYMGR_ADMIN" needed)</h3>
<%}%>

>=============================================================================

? 這個程序中,主要是通過
? <ofbiz:entityfield attribute="edit_cust" field="customerId"/>
? 把取到的對象的段顯示出來, 對象 edit_cust 是我們在程序中取到并放到 session 中的。

下面我們來配置 controller.xml 和 regions.xml, 在 controller.xml 中加入:
>=============================================================================

?? <request-map uri="createTestForm">
????? <description>Show the create form</description>
????? <security https="false" auth="false"/>
????? <response name="success" type="view" value="createTestForm"/>
?? </request-map>

?? <request-map uri="testofbiz">
????? <description>Test Ofbiz</description>
????? <security https="false" auth="false"/>
????? <response name="success" type="view" value="testofbiz"/>
?? </request-map>
?
?? <request-map uri="listtest">
????? <description>List all records</description>
????? <security https="false" auth="false"/>
????? <event type="java" path="com.geeyo.ofbiz.TestOfbiz" invoke="lookAllRecords" />
????? <response name="success" type="view" value="listAllTest"/>
?? </request-map>

?? <request-map uri="showtest">
????? <description>Show records</description>
????? <security https="false" auth="false"/>
????? <event type="java" path="com.geeyo.ofbiz.TestOfbiz" invoke="findRecord" />
????? <response name="success" type="view" value="showTest"/>
?? </request-map>

?? <request-map uri="createTest">
?????? <security https="true" auth="true"/>
?????? <event type="java" path="com.geeyo.ofbiz.TestOfbiz" invoke="createNewRecord"/>
?????? <response name="success" type="request" value="listtest"/>
?????? <response name="error" type="view" value="createTestForm"/>
?? </request-map>

?? <request-map uri="updateTest">
????? <description>update a record</description>
????? <security https="false" auth="false"/>
????? <event type="java" path="com.geeyo.ofbiz.TestOfbiz" invoke="updateRecord" />
????? <response name="success" type="request" value="listtest"/>
?? </request-map>

?? <request-map uri="removetest">
????? <description>remove a record</description>
????? <security https="false" auth="false"/>
????? <event type="java" path="com.geeyo.ofbiz.TestOfbiz" invoke="removeRecord" />
????? <response name="success" type="request" value="listtest"/>
?? </request-map>

?? <view-map name="listAllTest" type="region"/>
?? <view-map name="createTestForm" type="region"/>
?? <view-map name="showTest" type="region"/>
>=============================================================================

? 在 regions.xml 中加入:
>=============================================================================
?? <define id='createTestForm' region='MAIN_REGION'>
?????? <put section='title'>Create Ofbiz</put>
?????? <put section='content' content='/party/createofbiz.jsp'/>
?? </define>

?? <define id='listAllTest' region='MAIN_REGION'>
?????? <put section='title'>List Ofbiz</put>
?????? <put section='content' content='/party/listofbiz.jsp'/>
?? </define>

?? <define id='showTest' region='MAIN_REGION'>
?????? <put section='title'>Show Ofbiz</put>
?????? <put section='content' content='/party/showofbiz.jsp'/>
?? </define>

>=============================================================================

? 現在就完成了,我們重新啟動 Ofbiz,然后用 IE 訪問:
? http://localhost:8080/partymgr/control/listtest,用admin/ofbiz 登錄后就可以
看到我們剛才的工作成果了,你現在可以增加/刪除/修改記錄。


6.Ofbiz 通過 XML 來完成數據庫操作(非常強大的功能)

? 這是 Ofbiz 的一個非常強大的功能,可能通過簡單的 XML 文件來完成數據增/刪/改的處理,
這些處理在數據庫應用中是非常多的,因為很多需要維護的數據,所以寫程序也是最花時間的,
Ofbiz 把這些操作通過 XML 來完成,不能不說是一大革命---使我們不用寫程序就可以完成大
部分處理,這是每個程序員都向往的終極目標。

? 我們下面舉例來講述一下,處理的數據還是利用我們前面創建的 StudyCustomer,使用 XML
配置文件來完成前面程序 TestOfbiz.java 的大部分操作。

? 在 c:\ofbiz\ofbiz\testOfbiz\com\geeyo\ofbiz 目錄下創建文件 TestOfbizServices.xml,
該文件的內容如下:

>=================================================================

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE simple-methods PUBLIC "-//OFBiz//DTD Simple Methods//EN" "http://www.ofbiz.org/dtds/simple-methods.dtd">

<simple-methods>

?? <!-- TestOfbiz methods -->
?? <simple-method method-name="createNewRecord" short-description="Create a new record">
?????? <check-permission permission="STUDYCUSTOMER" action="_CREATE"><fail-message message="Security Error: to run createRecord you must have the STUDYCUSTOMER_CREATE permission"/></check-permission>??????? <check-errors/>

?????? <make-value entity-name="StudyCustomer" value-name="newEntity"/>
?????? <set-pk-fields map-name="parameters" value-name="newEntity"/>
?????? <set-nonpk-fields map-name="parameters" value-name="newEntity"/>

?????? <create-value value-name="newEntity"/>
?? </simple-method>
?? <simple-method method-name="updateRecord" short-description="Update a record">
?????? <check-permission permission="STUDYCUSTOMER" action="_UPDATE"><fail-message message="Security Error: to run updateRecord you must have the STUDYCUSTOMER_UPDATE permission"/></check-permission>

?????? <check-errors/>

?????? <make-value entity-name="StudyCustomer" value-name="lookupPKMap"/>
?????? <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
?????? <find-by-primary-key entity-name="StudyCustomer" map-name="lookupPKMap" value-name="lookedUpValue"/>
?????? <set-nonpk-fields map-name="parameters" value-name="lookedUpValue"/>
??????
?????? <store-value value-name="lookedUpValue"/>
?? </simple-method>

?? <simple-method method-name="findRecord" short-description="lookup a record">
?????? <check-errors/>

?????? <make-value entity-name="StudyCustomer" value-name="lookupPKMap"/>
?????? <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
?????? <find-by-primary-key entity-name="StudyCustomer" map-name="lookupPKMap" value-name="edit_cust"/>
?? <field-to-session field-name="edit_cust"/>
?? </simple-method>

?? <simple-method method-name="removeRecord" short-description="Delete a record">
?????? <check-permission permission="STUDYCUSTOMER" action="_DELETE"><fail-message message="Security Error: to run deleteRecord you must have the STUDYCUSTOMER_DELETE permission"/></check-permission>
?????? <check-errors/>

?????? <make-value entity-name="StudyCustomer" value-name="lookupPKMap"/>
?????? <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
?????? <find-by-primary-key entity-name="StudyCustomer" map-name="lookupPKMap" value-name="lookedUpValue"/>
?????? <remove-value value-name="lookedUpValue"/>
?? </simple-method>

?? <simple-method method-name="lookAllRecords" short-description="lookup suitable records">
?????? <check-errors/>
?????? <find-by-and entity-name="StudyCustomer" list-name="search_results"/>
?? <field-to-session field-name="search_results"/>
?? </simple-method>
??
</simple-methods>


>=================================================================

?上面的 XML 基本是不用解釋的,定義了

? createNewRecord
? updateRecord
? lookAllRecords
? removeRecord
? findRecord

? 這幾個方法,而且都有對用戶權限的檢查,這幾個方法對應于前面 TestOfbiz.java 中的幾個方法,
這樣來做數據庫操作顯然比用 Java 程序寫要簡單得多,

? 下面還需要在 controller.xml(具體文件得位置請參照前面的教程)更改一下 mapping 的設置,
更改如下,以前使用 TestOfbiz.java 時的配置我以注釋的方式保留著以做參照:

>=================================================================

?? <request-map uri="createTestForm">
????? <description>Show the create form</description>
????? <security https="false" auth="false"/>
????? <response name="success" type="view" value="createTestForm"/>
?? </request-map>

?? <request-map uri="listtest">
????? <description>List all records</description>
????? <security https="false" auth="false"/>
???????? <event type="simple" path="com/geeyo/ofbiz/TestOfbizServices.xml" invoke="lookAllRecords" />
????? <response name="success" type="view" value="listAllTest"/>
?? </request-map>

?? <request-map uri="showtest">
????? <description>Show records</description>
????? <security https="false" auth="false"/>
???????? <event type="simple" path="com/geeyo/ofbiz/TestOfbizServices.xml" invoke="findRecord" />
????? <response name="success" type="view" value="showTest"/>
?? </request-map>

?? <request-map uri="createTest">
?????? <security https="true" auth="true"/>
?????? <event type="simple" path="com/geeyo/ofbiz/TestOfbizServices.xml" invoke="createNewRecord"/>
?????? <response name="success" type="request" value="listtest"/>
?????? <response name="error" type="view" value="createTestForm"/>
?? </request-map>

?? <request-map uri="updateTest">
????? <description>update a record</description>
????? <security https="false" auth="false"/>
????? <event type="simple" path="com/geeyo/ofbiz/TestOfbizServices.xml" invoke="updateRecord" />
????? <response name="success" type="request" value="listtest"/>
?? </request-map>

?? <request-map uri="removetest">
????? <description>remove a record</description>
????? <security https="false" auth="false"/>
????? <event type="simple" path="com/geeyo/ofbiz/TestOfbizServices.xml" invoke="removeRecord" />
????? <response name="success" type="request" value="listtest"/>
?? </request-map>

?? <view-map name="listAllTest" type="region"/>
?? <view-map name="createTestForm" type="region"/>
?? <view-map name="testofbiz" type="region"/>
?? <view-map name="showTest" type="region"/>

>=================================================================

? 配置該文件的方法請參照前面的教程,regions.xml 不需改動。

? 配置完后請用前面講過的方法訪問 URL: http://localhost:8080/partymgr/control/listtest

? 現在我們可以看到,Ofbiz 在 MVC 方面做得非常好,我們可以把后端的處理程序從 java 改
成用 XMl 控制,而其他部分(像 JSP)不需任何改動,這可以保證我們系統各部分的獨立性。