OFBiz的探索进阶

主要参照https://cwiki.apache.org/OFBIZ/ofbiz-tutorial-a-beginners-development-guide.html这个教程,实现的过程教程上很详细,故这里不多说

还参考了下http://www.hotwaxmedia.com/apache-ofbiz-blog/ofbiz/ofbiz-tutorials/ofbiz-tutorial-building-a-simple-product-list-screen这个教程

Part 1

教程上说得很详细,只说一下需要注意的地方:

  • 关于web.xml文件,我们需要去framework/example下搜索example的web.xml,然后按照教程修改下列几项:

    <context-param><param-name>webSiteId</param-name><param-value>PRACTICE</param-value><description>A unique ID used to look up the WebSite entity to get information about catalogs, etc.</description>
    </context-param>
    <context-param><param-name>localDispatcherName</param-name><param-value>practice</param-value><description>A unique name used to identify/recognize the local dispatcher for the Service Engine</description>
    </context-param>
    <context-param><param-name>mainDecoratorLocation</param-name><param-value>component://practice/widget/CommonScreens.xml</param-value><description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description>
    </context-param>
    

    效果如图所示:

Part 2

最初版本

  • CommonScreens.xml这个文件同样也是去framework/exmaple中找,然后加入他所示的代码。
  • 需要注意,如果使用了网站上的代码,要特别注意person的大小写,源代码与网上教程的代码中,person的大小写是不同的,这个一定要小心
  • 第2步中,我们创建了一个menu,代码如下

    <?xml version="1.0" encoding="UTF-8"?>
    <menus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-menu.xsd"><menu name="PracticeAppBar" title="PracticeApplication" extends="CommonAppBarMenu" extends-resource="component://common/widget/CommonMenus.xml"><menu-item name="main" title="Main"><link target="main"/></menu-item></menu>
    </menus>
    

    这里的

    <menu-item name="main" title="Main"><link target="main"/></menu-item>

    对于菜单上的一项,如图所示


至于那个

<link target="main"/>

可以理解为当你选了Main这个菜单项的时候,相当于发出了main这个请求,然后去controller找对应的请求要怎么做就行了

  • 第5步中,我们使用了如下的代码建立一个叫做person的screen

    <screen name="person"><section><actions><script location="component://practice/webapp/practice/WEB-INF/actions/Person.groovy"/></actions><widgets><decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}"><decorator-section name="body"><platform-specific><html><html-template location="component://practice/webapp/practice/Person.ftl"/></html></platform-specific></decorator-section></decorator-screen></widgets></section></screen>
    

    这里对这段代码做一下简单的解析: 
    1、the screen decorator is used to decorate our screen with all the application menus, the header and footer that are shared by all the screens;
    2、the screen specific content will go in the “body” section of the decorator, that is why we use the “decorator-section” element and add the screen specific content there
    3、the path to the form widget definition is expressed in the format “component://<ofbiz component name>/<relative path to the form definition xml file>”; this format is widely used in ofbiz and it is useful because makes the system independent from the actual location of the ofbiz home folder and also enables the extension mechanism of OFBiz

  • 由于我们使用了新的请求,所以需要在controller.xml中添加相应的request-map,代码如下

    <?xml version="1.0" encoding="UTF-8"?>
    <site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/site-conf.xsd"><include location="component://common/webcommon/WEB-INF/common-controller.xml"/><description>Practice Component Site Configuration File</description><owner>Copyright 2001-2009 The Apache Software Foundation</owner><handler name="screen" type="view" class="org.ofbiz.widget.screen.ScreenWidgetViewHandler"/><!-- Request Mappings --><request-map uri="main"><security https="false" auth="false"/><response name="success" type="view" value="main"/></request-map><request-map uri="person"><security https="false" auth="false"/><response name="success" type="view" value="person"/></request-map><!-- end of request mappings --><!-- View Mappings --><view-map name="main" type="screen" page="component://practice/widget/PracticeScreens.xml#main"/><view-map name="person" type="screen" page="component://practice/widget/PracticeScreens.xml#person"/><!-- end of view mappings -->
    </site-conf>
    

     

Now moving to create a form for showing the content of Person entity on the screen (Using Form Widget)

controller.xml的改动如下:

<?xml version="1.0" encoding="UTF-8"?>
<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/site-conf.xsd"><include location="component://common/webcommon/WEB-INF/common-controller.xml"/><description>Practice Component Site Configuration File</description><owner>Copyright 2001-2009 The Apache Software Foundation</owner><handler name="screen" type="view" class="org.ofbiz.widget.screen.ScreenWidgetViewHandler"/><!-- Request Mappings --><request-map uri="main"><security https="false" auth="false"/><response name="success" type="view" value="main"/></request-map><request-map uri="person"><security https="false" auth="false"/><response name="success" type="view" value="person"/></request-map><request-map uri="personForm"><security https="false" auth="false"></security><response name="success" type="view" value="personform"/></request-map><!-- end of request mappings --><!-- View Mappings --><view-map name="main" type="screen" page="component://practice/widget/PracticeScreens.xml#main"/><view-map name="person" type="screen" page="component://practice/widget/PracticeScreens.xml#person"/><view-map name="personform" type="screen" page="component://practice/widget/PracticeScreens.xml#personForm"/><!-- end of view mappings -->
</site-conf>
  • 需要注意,这里的request的personForm的F是大写的,写成小写翻页会出现错误
    访问http://localhost:8080/practice/control/personForm,效果如图所示:

Create main Decorator for decorating this application

在 CommonScreens.xml中加入main-decorator的定义后,我们需要改进一下CommonPracticeDecorator的代码:

<!-- CommonParcticeDecorator for use main-decorator--><screen name="CommonPracticeDecorator"><section><widgets><decorator-screen name="main-decorator"><decorator-section name="body"><decorator-section-include name="body"/></decorator-section></decorator-screen></widgets></section></screen>

然后重新访问
效果如图:

突然发现炫了好多....

Now its the time to show practice application in the app bar

貌似没有发现什么变化...

Create UI Labels

  • config文件夹建立在E:\apache-ofbiz-10.04.02\hot-deploy\practice目录下,就是说与ofbiz-component.xml同一级
  • 加入config文件夹后,ofbiz-component.xml的修改如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <ofbiz-component name="practice"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"><resource-loader 	name="main" type="component"/><classpath type="dir" location="config"/><webapp name="practice"title="Practice"server="default-server"base-permission="OFBTOOLS"location="webapp/practice"mount-point="/practice"app-bar-display="true"/>
    </ofbiz-component>
    

     

PracticeUiLabels.xml这样写:

<?xml version="1.0" encoding="UTF-8"?>
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><property key="PracticeApplication"><value xml:lang="en">This is first 	practice</value></property><property key="PracticeCompanyName"><value xml:lang="en">OFBiz: Practice</value></property>
</resource>

至于这里写了两个key有什么用,官方的tutorial表述不是很轻,而在http://www.hotwaxmedia.com/apache-ofbiz-blog/ofbiz/ofbiz-tutorials/ofbiz-tutorial-building-a-simple-product-list-screen这篇文章的Internationalization这一部分中有一定的解答,这里的PracticeUiLabels.xml的作用我感觉有点像android中的string.xml,就定义了一个变量名(容许我这么说),然后它对应的值,然后我们不在直接用值,而是用这个变量,这里是间接的思想吧。

Secure Your Application by Authentication

很遗憾,这一步我没有做出来,因为我找了ExampleMenus.xml这个文件,但我没有在里面找到所说的login and logout options,以后回头再看看这里吧

Part3

Writing CRUD Operations

Writing services

需要特别注意的:由于所有的service都需要在在ofbiz启动时候载入,所以,我们需要在ofbiz-component.xml中加入service的定义

<?xml version="1.0" encoding="UTF-8"?>
<ofbiz-component name="practice"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"><resource-loader 	name="main" type="component"/><classpath type="dir" location="config"/><classpath type="dir" location="script"/><service-resource type="model" loader="main" location="servicedef/services.xml"/><webapp name="practice"title="Practice"server="default-server"base-permission="OFBTOOLS"location="webapp/practice"mount-point="/practice"app-bar-display="true"/>
</ofbiz-component>

其中,minilang的定义如下:
Minilang can help developers to reduce the time it takes to implement simple and repetitive tasks. Code does not need to be compiled and can therefore be implemented faster, breaking the typical Java code-compile-test cycle. Minilang gives the advantage of being able to change the code without a restart of the application. 
简单来说它是ofbiz专用的语言,用来处理CRUD操作,认证操作等操作,效率上比java快,但由于我们的项目是用java的,故这里仅作简单了解。

Writing CRUD Operations for Party Entity

1、在servicedef目录下创建services.xml(有个s别少打了!)

2、在services.xml中写Party的CRUD的操作,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd"><description>Practice Services</description><vendor>OFBiz</vendor><version>1.0</version><!-- CRUD Operations for Party Entity --><service name="createPracticeParty" default-entity-name="Party" engine="simple"location="component://practice/script/org/ofbiz/practice/PracticeServices.xml" invoke="createPracticeParty" auth="true"><description>Create a Party</description><auto-attributes include="pk" mode="OUT" optional="false"/><auto-attributes include="nonpk" mode="IN" optional="true"/></service><service name="updatePracticeParty" default-entity-name="Party" engine="simple"location="component://practice/script/org/ofbiz/practice/PracticeServices.xml" invoke="updatePracticeParty" auth="true"><description>Update a Party</description><auto-attributes include="pk" mode="IN" optional="false"/><auto-attributes include="nonpk" mode="IN" optional="true"/></service><service name="deletePracticeParty" default-entity-name="Party" engine="simple"location="component://practice/script/org/ofbiz/practice/PracticeServices.xml" invoke="deletePracticeParty" auth="true"><description>Delete a Party</description><auto-attributes include="pk" mode="IN" optional="false"/></service>

Writing CRUD Operations for Person Entity

按照教程加入代码,最后访问http://localhost:8080/practice/control/personForm,效果如图:

不知道怎么,排版不像教程那样好看。

尝试点击update或者delete,发现什么都不能做,所以我们在controller.xml中加入对应的request-map

<request-map uri="deletePracticePerson"><security https="false" auth="true"></security><event type="service" invoke="deletePracticePerson"></event><response name="success" type="view" value="personform"></response></request-map><request-map uri="updatePracticePerson"><security https="false" auth="true"></security><event type="service" invoke="updatePracticePerson"></event><response name="success" type="view" value="personform"></response></request-map>

这样一来,这两个键就能正常使用了

Writing Events

1、在menu bar上加入Event这个tag

<menu name="PracticeAppBar" title="PracticeApplication" default-menu-item-name="personList" default-selected-style="selected"extends="CommonAppBarMenu" extends-resource="component://common/widget/CommonMenus.xml"><menu-item name="main" title="Main"><link target="main"/></menu-item><menu-item name="person" title="Person"><link target="person"></link></menu-item><menu-item name="personList" title="Person List"><link target="personForm"></link></menu-item><menu-item name="events" title="Events"><link target="events"/></menu-item></menu>

效果:

需要注意的是,由于我们还没有在controller.xml中写关于events的request-map,所以这时候如果点Events是会报错的

2、创建一个包含EventMinilang"和"EventJava“的menu

<menu name="EventMenu" default-menu-item-name="eventMinilang" default-selected-style="selected"type="simple" menu-container-style="button-bar button-style-1" selected-menuitem-context-field-name="headerItem"><menu-item name="eventMinilang" title="Create Person --- Event MiniLang"><link target="createPracticePersonEventM"/></menu-item><menu-item name="eventJava" title="Create Person --- Event Java"><link target="createPracticePersonEventJ"/></menu-item>   
</menu>

其实EventMenu在界面上知识对应这一块

3、不知道什么意思

4、在PracticeSreens.xml创建不同event对应的界面

<screen name="CreatePracticePersonEventM"><section><actions><set field="headerItem" value="eventMinilang"/><set field="titleProperty" value="PageTitleSimpleEventForms"/></actions><widgets><decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}"><decorator-section name="body"><include-menu location="component://practice/widget/PracticeMenus.xml" name="EventMenu"/><label text="New Person --- Simple Event" style="h1"/><include-form name="CreatePersonSimpleForm" location="component://practice/widget/PracticeForms.xml"/></decorator-section></decorator-screen>        </widgets></section></screen><screen name="CreatePracticePersonEventJ"><section><actions><set field="headerItem" value="eventJava"/><set field="titleProperty" value="PageTitleJavaEventForms"/></actions><widgets><decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}"><decorator-section name="body"><include-menu location="component://practice/widget/PracticeMenus.xml" name="EventMenu"/><label text="New Person --- Java Event" style="h1"/><include-form name="CreatePersonJavaForm" location="component://practice/widget/PracticeForms.xml"/></decorator-section></decorator-screen></widgets></section></screen>

5、在PracticeForm.xml中加入如下代码:

<form name="CreatePersonSimpleForm" type="single" target="createPracticePersonSimpleEvent"><auto-fields-service service-name="createPracticePerson"/><field name="submitButton" title="${uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button-type="button"/></field></form><form name="CreatePersonJavaForm" type="single" target="createPracticePersonJavaEvent"><auto-fields-service service-name="createPracticePerson"/><field name="submitButton" title="${uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button-type="button"/></field></form>

现在我们就在controller.xml加入相应的request-map

menu bar上events对应的request-map

<request-map uri="events"><security https="false" auth="true"/><response name="success" type="view" value="CreatePracticePersonEventM"/>
</request-map>

Event Menu中两项对应的request-map

<request-map uri="CreatePracticePersonEventM"><security https="false" auth="true"/><response name="success" type="view" value="CreatePracticePersonEventM"/>
</request-map>
<request-map uri="CreatePracticePersonEventJ"><security https="false" auth="true"/><response name="success" type="view" value="CreatePracticePersonEventJ"/>
</request-map>

PracticeForm中对应的request-map

<request-map uri="createPracticePersonSimpleEvent"><security https="true" auth="true"/><event type="simple" path="org/ofbiz/practice/PracticeEvents.xml" invoke="createPracticePersonSimpleEvent"/><response name="success" type="view" value="CreatePracticePersonEventM"/><response name="error" type="view" value="CreatePracticePersonEventM"/></request-map><request-map uri="createPracticePersonJavaEvent"><security https="true" auth="true"/><event type="java" path="org.ofbiz.practice.PracticeEvents" invoke="createPracticePersonJavaEvent"/><response name="success" type="view" value="CreatePracticePersonEventJ"/><response name="error" type="view" value="CreatePracticePersonEventJ"/></request-map>

 

添加相应的view-map

<view-map name="CreatePracticePersonEventM" type="screen" page="component://practice/widget/PracticeScreens.xml#CreatePracticePersonEventM"/>
<view-map name="CreatePracticePersonEventJ" type="screen" page="component://practice/widget/PracticeScreens.xml#CreatePracticePersonEventJ"/>       

需要注意:网站上给的源码中,在view-map这里有一个Events的view-map,这个是没有用到的,而且在PracticeScreen.xml中并没有Events这个Sreen,所以这里完全是没用的,故不要加进去

效果:

Simple Minilang Event

Java Event

需要做的有三件事:

1、在hot-deploy/practice目录下建立一个/src/org/ofbiz/practice的目录

2、在这个目录中建立一个PracticeEvents.java文件,内容如下:

package org.ofbiz.practice;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.GenericServiceException;
public class PracticeEvents {public static final String module = PracticeEvents.class.getName();public static String createPracticePersonJavaEvent(HttpServletRequest request, HttpServletResponse response) {LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");GenericDelegator delegator = (GenericDelegator) request.getAttribute("delegator");GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");String salutation = (String) request.getParameter("salutation");String firstName = (String) request.getParameter("firstName");String middleName=(String) request.getParameter("middleName");String lastName=(String) request.getParameter("lastName");String suffix=(String) request.getParameter("suffix");//         Map createPersonContext = new HashMap();
//         createPersonContext.put("firstName", firstName);
//         createPersonContext.put("middleName", middleName);
//         createPersonContext.put("lastName", lastName);
//         createPersonContext.put("suffix", suffix);Map createPersonCtx = UtilMisc.toMap("salutation", salutation, "firstName", firstName, "middleName", middleName, "lastName", lastName, "suffix", suffix, "userLogin", userLogin);try {Map person = dispatcher.runSync("createPracticePerson", createPersonCtx);} catch (GenericServiceException e) {Debug.logError(e.toString(), module);return "error";}return "success";}           }

自己的理解是每一个Event对应一个方法,这里的createPracticePersonJavaEvent对应到controller.xml的下面语句

<request-map uri="createPracticePersonJavaEvent"><security https="true" auth="true"/><event type="java" path="org.ofbiz.practice.PracticeEvents" invoke="createPracticePersonJavaEvent"/><response name="success" type="view" value="CreatePracticePersonEventJ"/><response name="error" type="view" value="CreatePracticePersonEventJ"/></request-map>

3、在ofbiz-component.xml中加入一句:

4、在practice目录下建立一个build.xml文件

这个文件是用来给ant编译我们的java的event的。但是我没有安装ant。所以,需要到apache的官网上下一个ant,我下的是apache-ant-1.8.4。

安装方法:

1)将安装包解压到某个盘,我解压到E盘

2)在用户变量中添加ANT_HOME

需要注意:是用户变量而不是系统变量,系统变量我加了没成功

3)修改PATH

4)命令行运行ant看是否成功

如果出现上图就说明安装ant配置好了

接下来我们就在命令行进入到practice所在目录,输入ant

5、最后重启ofbiz,java event就完成了。

Part 4

ECA(Event Condition Action)

1、在menu bar上添加ECA这个选项

在PracticeMenu.xml中加入这样一个选项

<menu-item name="eca" title="ECA"><link target="eca"/></menu-item>

在controller.xml中加入相对应的request-map

<request-map uri="eca"><security https="false" auth="true"></security>
</request-map>

2、在PracticeMenu.xml加入ECA的menu

<menu name="EcaMenu" default-menu-item-name="seca" default-selected-style="selected"type="simple" menu-container-style="button-bar button-style-2" selected-menuitem-context-field-name="headerItem"><menu-item name="seca" title="Create Person --- SECA"><link target="seca"/></menu-item><menu-item name="eeca" title="Create Person --- EECA"><link target="eeca"/></menu-item>   
</menu>

并且在controller.xml中加入对应的request-map

<request-map uri="eca"><security https="false" auth="true"></security></request-map><request-map uri="seca"><security https="false" auth="true"></security></request-map><request-map uri="eeca"><security https="false" auth="true"></security></request-map>

SECA

1、在service.xml中加入createPartyRoleVisitor这个服务

<service name="createPartyRoleVisitor" engine="simple" location="org/hotwax/practice/PracticeServices.xml" 	             invoke="createPartyRoleVisitor" default-entity-name="PartyRole" auth="true"><description>Create a new PartyRole when a party is created</description><attribute name="partyId" mode="IN" type="String" optional="false"/>
</service>

2、在servicedef目录下创建secas.xml文件,写入如下的内容:

<?xml version="1.0" encoding="UTF-8"?>
<service-eca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/service-eca.xsd"><eca service="createPracticePerson" event="commit"><condition field-name="partyId" operator="is-not-empty"/><action service="createPartyRoleVisitor" mode="sync"/></eca>
</service-eca>

进进从代码上看,应该是如果在createPracticePerson进行commit的时候,如果partyId不为空,就会自动调用createPartyRoleVisitor服务

3、修改ofbiz-component.xml,加入下面语句

<service-resource type="eca" loader="main" location="servicedef/secas.xml"/>

4、完善controller中的跳转

<request-map uri="eca"><security https="false" auth="true"></security><response name="success" type="view" value="seca"></response>
</request-map>
<request-map uri="seca"><security https="false" auth="true"></security><response name="success" type="view" value="seca"></response>
</request-map>
<request-map uri="eeca"><security https="false" auth="true"></security><response name="success" type="view" value="eeca"></response>
</request-map>

 

<view-map name="seca" type="screen" page="component://practice/widget/PracticeScreens.xml#seca"></view-map>
<view-map name="eeca" type="screen" page="component://practice/widget/PracticeScreens.xml#eeca"></view-map>

5、在PracticeScreen.xml中创建对应的界面

	<screen name="seca"><section><actions><set field="headerItem" value="seca"/><set field="titleProperty" value="PageTitleSecaForm"/></actions><widgets><decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}"><decorator-section name="body"><include-menu location="component://practice/widget/PracticeMenus.xml" name="EcaMenu"/><label text="New Person --- SECA" style="h1"/><include-form name="CreatePerson" location="component://practice/widget/PracticeForms.xml"/></decorator-section></decorator-screen></widgets></section></screen><screen name="eeca"><section><actions><set field="headerItem" value="eeca"/><set field="titleProperty" value="PageTitleEecaForm"/></actions><widgets><decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}"><decorator-section name="body"><include-menu location="component://practice/widget/PracticeMenus.xml" name="EcaMenu"/><label text="New Person --- EECA" style="h1"/><include-form name="CreatePerson" location="component://practice/widget/PracticeForms.xml"/></decorator-section></decorator-screen></widgets></section></screen>

6、重启ofbiz,访问localhost:8080/practice/control/eca进行测试

这是效果,但由于我不知道在哪里查看教程上说的PartyRole entity,所以也不清楚有了这个seca会带来什么变化

EECA

1、createPartyRoleCustomer的代码如下:

<service name="createPartyRoleCustomer" engine="simple" location="org/hotwax/practice/PracticeServices.xml" invoke="createPartyRoleCustomer" default-entity-name="PartyRole" auth="true"><description>Create a new PartyRole when a party is created</description><attribute name="partyId" mode="IN" type="String" optional="false"/></service>

2、创建一个entitiydef目录,在其中写一个eeca.xml文件,代码如下

<?xml version="1.0" encoding="UTF-8"?>
<entity-eca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entity-eca.xsd"><!-- To create party role whenever a party is created --><eca entity="Party" operation="create" event="return"><condition field-name="partyId" operator="is-not-empty"/><action service="createPartyRoleCustomer" mode="sync"/></eca></entity-eca>  

3、在ofbiz-component.xml中添加进队eecas.xml的定义

4、重启,测试

问题和SECA一样,由于我不知道在哪里查看PartyRole,所以无法得知EECA会带来什么变化,直观上来看,当创建了一个Party示例时候,就会同步地创建一个PartyRoleCustomer实体

Group Service

暂略

Interface

暂略

Part 5

Creating Custom Entity

暂略

Extending an Existing OOTB Entity

暂略

Preparing Data For Custom Application

我们可以自己定义一些数据,然后载入到ofbiz中进行测试

按照教程,建立data目录与PracticeData.xml,写入

<?xml version="1.0" encoding="UTF-8"?>
<entity-engine-xml><Party partyId="MyDemoUser" partyTypeId="PERSON"/><Person partyId="MyDemoUser" firstName="ZTK_Practice" lastName="ZTK_Person"/><PartyRole partyId="MyDemoUser" roleTypeId="VISITOR"/><ContactMech contactMechId="5000" contactMechTypeId="EMAIL_ADDRESS" infoString="mypractice.person@gmail.com"/><PartyContactMech partyId="MyDemoUser" contactMechId="5000" fromDate="2001-05-13 00:00:00.000" allowSolicitation="Y"/><PartyContactMechPurpose partyId="MyDemoUser" contactMechId="5000" contactMechPurposeTypeId="PRIMARY_EMAIL" fromDate="2001-05-13 00:00:00.000"/><WebSite webSiteId="MYPRACTICE" siteName="Practice Application" visualThemeSetId="BACKOFFICE"/>
</entity-engine-xml>

保存,然后用命令行进入到ofbiz的主目录,运行ant run-install,就像刚开始按照那样,这里大概需要2到3分钟。

加载完数据后,运行startofbiz.bat,访问 https://localhost:8443/webtools/control/entitymaint

在Person这个表中搜索,可以看到

在Party这个表中搜索,可以看到

在ContactMech这个表中搜索,可以看到

说明我们成功地向数据库中添加进了自己定义的数据!

转载于:https://www.cnblogs.com/ztk3939339/archive/2012/08/08/2627686.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对GCD的一些理解和实践

对GCD的一些理解和实践GCD GCD&#xff0c;全程Grand Central Dispatch&#xff0c;是苹果为了多核并行提出的解决方案。它是使用C语言实现&#xff0c;但是由于用了block来处理回调&#xff0c;所以使用起来十分方便。并且GCD会自动管理线程的生命周期&#xff0c;不需要我们去…

[Buzz Today]2012.08.08

# Dark Reign 2 源代码现身Google Code Pandemic工作室开发的即时战略游戏《Dark Reign 2》源代码被泄露到了Google Code http://code.google.com/p/darkreign2/ # Warsow 1.0发布 Set in a futuristic cartoonish world, Warsow is a completely free fast-paced first-person…

PyTorch训练中Dataset多线程加载数据,比Dataloader里设置多个workers还要快

PyTorch训练中Dataset多线程加载数据&#xff0c;而不是在DataLoader 背景与需求 现在做深度学习的越来越多人都有用PyTorch&#xff0c;他容易上手&#xff0c;而且API相对TF友好的不要太多。今天就给大家带来最近PyTorch训练的一些小小的心得。 大家做机器学习、深度学习都…

python调用摄像头人脸识别代码_利用face_recognition,dlib与OpenCV调用摄像头进行人脸识别...

用已经搭建好 face_recognition&#xff0c;dlib 环境来进行人脸识别 未搭建好环境请参考&#xff1a; 使用opencv 调用摄像头 import face_recognition import cv2 video_capture cv2.videocapture(0) # videocapture打开摄像头&#xff0c;0为笔记本内置摄像头&#xff0c;1…

【转】彻底搞清计算结构体大小和数据对齐原则

数据对齐: 许多计算机系统对基本数据类型合法地址做出了一些限制&#xff0c;要求某种类型对象的地址必须是某个值K(通常是2&#xff0c;4或8)的倍数。这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件设计。例如&#xff0c;假设一个处理器总是从存储器中取出8个字节…

Pytorch 学习率衰减 之 余弦退火与余弦warmup 自定义学习率衰减scheduler

学习率衰减&#xff0c;通常我们英文也叫做scheduler。本文学习率衰减自定义&#xff0c;通过2种方法实现自定义&#xff0c;一是利用lambda&#xff0c;另外一个是继承pytorch的lr_scheduler import math import matplotlib.pyplot as plt import numpy as np import torch i…

c++ 字符串赋给另一个_7.2 C++字符串处理函数

点击上方“C语言入门到精通”&#xff0c;选择置顶第一时间关注程序猿身边的故事作者闫小林白天搬砖&#xff0c;晚上做梦。我有故事&#xff0c;你有酒么&#xff1f;C字符串处理函数C语言和C提供了一些字符串函数&#xff0c;使得用户能很方便地对字符串进行处理。这些是放在…

如何检测远程主机上的某个端口是否开启

有时候我们要测试远程主机上的某个端口是否开启&#xff0c;无需使用太复杂的工作&#xff0c;windows下就自带了工具&#xff0c;那就是telnet。怎么检测呢&#xff0c;按下面的步骤&#xff1a; 1、安装telnet。我的win7下就没有telnet&#xff0c;在cmd下输入telnet提示没有…

Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python运行环境(含虚拟环境)

配置WSL windows桌面下&#xff0c;按下面顺序可以找到 "启动或关闭windows功能” &#xff0c; 开始 -> 设置 -> 应用 -> 应用和功能 -> 可选功能 -> 相关设置下 更多Windows功能&#xff08;滚动鼠标到底部&#xff09;点击后&#xff0c;会弹出 启动或…

2019编译ffepeg vs_如何在windows10下使用vs2017编译最新版本的FFmpeg和ffplay

该文章描述了如何在windows10 64位系统下面编译出FFmpeg的库及其自带的ffplay播放器&#xff0c;而且全部采用最新的版本&#xff0c;这样我们可以在vs2017的ide下调试ffplay&#xff0c;能使我们更容易学习FFmpeg的架构以及音视频播放器的原理。步骤&#xff1a;1.安装vs2017在…

训练集山准确率高测试集上准确率很低_推荐算法改版前的AB测试

编辑导语&#xff1a;所谓推荐算法就是利用用户的一些行为&#xff0c;通过一些数学算法&#xff0c;推测出用户可能喜欢的东西&#xff1b;如今很多软件都有这样的操作&#xff0c;对于此系统的设计也会进行测试&#xff1b;本文作者分享了关于推荐算法改版前的AB测试&#xf…

C#实现渐变颜色的Windows窗体控件

C#实现渐变颜色的Windows窗体控件! 1,定义一个BaseFormGradient,继承于System.Windows.Forms.Form2,定义三个变量: privateColor _Color1 Color.Gainsboro; privateColor _Color2 Color.White; privatefloat_ColorAngle 0f;3,重载OnPaintBackground方法 protecte…

Windows下 jupyter notebook 运行multiprocessing 报错的问题与解决方法

文章目录测试用的代码错误解决方法测试用的代码 下面每一个对应一个jupyter notebook的单元格 import time from multiprocessing import Process, Queuedef generator():c 0while True:time.sleep(1.0) # read somethingyield cc 1%%timeds generator() for i in range(3…

vc mysql_vc6.0连接mysql数据库

一、MySQL的安装Mysql的安装去官网下载就可以。。。最新的是5.7版本。。二、VC6.0的设置(1)打开VC6.中选0 工具栏Tools菜单下的Options选项&#xff0c;在Directories的标签页中右边的“Show directories for:”下拉列表中“Includefiles”&#xff0c;然后在中间列表框中添加你…

python class用法_python原类、类的创建过程与方法

【小宅按】今天为大家介绍一下python中与class 相关的知识……获取对象的类名python是一门面向对象的语言&#xff0c;对于一切接对象的python来说&#xff0c;咱们有必要深入的学习与了解一些知识首先大家都知道&#xff0c;要获取一个对象所对应的类&#xff0c;需要使用clas…

深度学习中的一些常见的激活函数集合(含公式与导数的推导)sigmoid, relu, leaky relu, elu, numpy实现

文章目录Sigmoid(x)双曲正切线性整流函数 rectified linear unit &#xff08;ReLu&#xff09;PReLU(Parametric Rectified Linear Unit) Leaky ReLu指数线性单元 Exponential Linear Units &#xff08;ELU&#xff09;感知机激活%matplotlib inline %config InlineBackend.f…

最牛X的GCC 内联汇编

正如大家知道的&#xff0c;在C语言中插入汇编语言&#xff0c;其是Linux中使用的基本汇编程序语法。本文将讲解 GCC 提供的内联汇编特性的用途和用法。对于阅读这篇文章&#xff0c;这里只有两个前提要求&#xff0c;很明显&#xff0c;就是 x86 汇编语言和 C 语言的基本认识。…

mysql的告警日志_MySQL Aborted connection告警日志的分析

前言&#xff1a;有时候&#xff0c;连接MySQL的会话经常会异常退出&#xff0c;错误日志里会看到"Got an error reading communication packets"类型的告警。本篇文章我们一起来讨论下该错误可能的原因以及如何来规避。1.状态变量Aborted_clients和Aborted_connects…

hosts多个ip对应一个主机名_一个简单的Web应用程序,用作连接到ssh服务器的ssh客户端...

WebSSH一个简单的Web应用程序&#xff0c;用作连接到ssh服务器的ssh客户端。它是用Python编写的&#xff0c;基于tornado&#xff0c;paramiko和xterm.js。特征支持SSH密码验证&#xff0c;包括空密码。支持SSH公钥认证&#xff0c;包括DSA RSA ECDSA Ed25519密钥。支持加密密钥…

Shell Notes(1)

> vi复制粘贴 光标移动到要复制的部分的开头&#xff0c;Esc退出插入模式&#xff0c;按v进入Visual模式&#xff0c;用hjkl选中要复制的部分 按Y或者yy&#xff0c;复制 移动光标到目标位置&#xff0c;按p&#xff0c;粘贴 > echo –e 参数 –e 可以使echo解释由反斜杠…