ofbiz之entity 实体解析

2024-03-11 21:08
文章标签 解析 实体 entity ofbiz

本文主要是介绍ofbiz之entity 实体解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ofbiz 之entity实体 
1. 实体定义文件 
实体定义文件一般存放位置是在对应模块的entity文件夹下面,以party为例,party的实体定义文件路径为%ofbiz-home%\applications\party\entitydef\entitymodel.xml。 
通过对应模块的ofbiz-component.xml进行加载。 
   <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/> 
<entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel_old.xml"/> 
实体定义文件可以为多个。 
2. 实体类型 
2.1. 普通实体 
<entity entity-name="TenantDataSource" package-name="org.ofbiz.entity.tenant"> 
        <description> 
            There should be one record for each tenant and each group-map for the active delegator. 
            The jdbc fields will override the datasource -> inline-jdbc values for the per-tenant delegator. 
        </description> 
        <field name="tenantId" type="id-ne"/> 
        <field name="entityGroupName" type="name"/> 
        <field name="jdbcUri" type="long-varchar"/> 
        <field name="jdbcUsername" type="long-varchar"/> 
        <field name="jdbcPassword" type="long-varchar"></field> 
        <prim-key field="tenantId"/> 
        <prim-key field="entityGroupName"/> 
        <relation type="one" fk-name="TNTDTSRC_TNT" rel-entity-name="Tenant"> 
        <key-map field-name="tenantId"/> 
        </relation> 
</entity> 
普通实体和数据库中的表是一一对应的。程序会根据实体定义在数据库中创建表,索引,外键约束等。 
2.2. 视图实体 
<view-entity entity-name="WorkEffortAssocView" 
            package-name="org.ofbiz.workeffort.workeffort" 
            title="Work Effort Association Entity with Name"> 
      <member-entity entity-alias="WA" entity-name="WorkEffortAssoc"/> 
      <member-entity entity-alias="WETO" entity-name="WorkEffort"/> 
      <alias-all entity-alias="WA"/> 
      <alias entity-alias="WETO" name="workEffortToName" field="workEffortName"/> 
      <alias entity-alias="WETO" name="workEffortToSetup" field="estimatedSetupMillis"/> 
      <alias entity-alias="WETO" name="workEffortToRun" field="estimatedMilliSeconds"/> 
      <alias entity-alias="WETO" name="workEffortToParentId" field="workEffortParentId"/> 
      <alias entity-alias="WETO" name="workEffortToCurrentStatusId" field="currentStatusId"/> 
      <alias entity-alias="WETO" name="workEffortToWorkEffortPurposeTypeId" field="workEffortPurposeTypeId"/> 
      <alias entity-alias="WETO" name="workEffortToEstimatedStartDate" field="estimatedStartDate"/> 
      <alias entity-alias="WETO" name="workEffortToEstimatedCompletionDate" field="estimatedCompletionDate"/> 
      <alias entity-alias="WETO" name="workEffortToActualStartDate" field="actualStartDate"/> 
      <alias entity-alias="WETO" name="workEffortToActualCompletionDate" field="actualCompletionDate"/> 
      <view-link entity-alias="WA" rel-entity-alias="WETO"> 
        <key-map field-name="workEffortIdTo" rel-field-name="workEffortId"/> 
      </view-link> 
      <relation type="one-nofk" fk-name="WK_EFFRTASSV_FWE" title="From" rel-entity-name="WorkEffort"> 
        <key-map field-name="workEffortIdFrom" rel-field-name="workEffortId"/> 
      </relation> 
</view-entity> 
View entity 一般用做多表连接复杂查询,view entity 不会在数据库中反映出来。 
2.3. 扩展实体 
<extend-entity entity-name="UserLogin"> 
        <field name="partyId" type="id"></field> 
        <relation type="one" fk-name="USER_PARTY" rel-entity-name="Party"> 
            <key-map field-name="partyId"/> 
        </relation> 
        <relation type="one-nofk" rel-entity-name="Person"> 
            <key-map field-name="partyId"/> 
        </relation> 
        <relation type="one-nofk" rel-entity-name="PartyGroup"> 
            <key-map field-name="partyId"/> 
        </relation> 
</extend-entity> 
继承已存在的实体并对其进行扩展。 
2.4. 动态实体 
DynamicViewEntity salesUsageViewEntity = new DynamicViewEntity(); 
            salesUsageViewEntity.addMemberEntity("OI", "OrderItem"); 
            salesUsageViewEntity.addMemberEntity("OH", "OrderHeader"); 
            salesUsageViewEntity.addMemberEntity("ItIss", "ItemIssuance"); 
            salesUsageViewEntity.addMemberEntity("InvIt", "InventoryItem"); 
            salesUsageViewEntity.addViewLink("OI", "OH", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("orderId")); 
            salesUsageViewEntity.addViewLink("OI", "ItIss", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("orderId", "orderId", "orderItemSeqId", "orderItemSeqId")); 
            salesUsageViewEntity.addViewLink("ItIss", "InvIt", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("inventoryItemId")); 
    salesUsageViewEntity.addAlias("OI", "productId"); 
    salesUsageViewEntity.addAlias("OH", "statusId"); 
    salesUsageViewEntity.addAlias("OH", "orderTypeId"); 
    salesUsageViewEntity.addAlias("OH", "orderDate"); 
    salesUsageViewEntity.addAlias("ItIss", "inventoryItemId"); 
    salesUsageViewEntity.addAlias("ItIss", "quantity"); 
salesUsageViewEntity.addAlias("InvIt", "facilityId"); 
EntityListIterator salesUsageIt = delegator.findListIteratorByCondition(salesUsageViewEntity, 
EntityCondition.makeCondition( 
UtilMisc.toList( 
         EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId), 
          EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId), 
            EntityCondition.makeCondition("statusId", 
EntityOperator.IN, 
UtilMisc.toList("ORDER_COMPLETED", "ORDER_APPROVED", "ORDER_HELD")), 
        EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"), 
           EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime) 
), 
EntityOperator.AND),null, null, null, null 
); 
在程序中手动创建实体,对其进行查询。 
3实体定义 
3.1. 命名规则 
实体名称(entity-name)首字母大写,如果实体名称由多个关键字组成,那么关键字首字母大写,例如entity-name="TenantDataSource",ofbiz 会在创建数据库表的时候根据entity-name 实体名称除首字母之外的大写字母前加“_”,所以entity-name="TenantDataSource"生成的数据库表名为“Tenant_Data_Source”. 
所以要控制entity-name 实体名称不要超过25个字母。 
Field 表字段,命名规则与实体名称差不多,唯一不同的是首字母小写。 
3.2. 实体与数据库的关联 
    <entity-group group="org.ofbiz.olap" entity="SalesInvoiceItemFact"/> 
<entity-group group="org.ofbiz.olap" entity="SalesInvoiceItemStarSchema"/> 
Entity-group(一般定义在各个模块的\entitydef\entitygroupXXX.xml中) 对实体进行分组,使不同的实体分属不同的entity-group。 
也许你会发现并不是每个entity都进行了entity-group 分组。事实上如果你没有对实体进行分组归类的话,系统启动的时候他会将实体默认归类到"org.ofbiz"中。 
查看数据库定义文件%ofbiz_home%/framework/entity/config/entityengine.xml 
可以发现: 
<delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" distributed-cache-clear-enabled="false"> 
        <group-map group-name="org.ofbiz" datasource-name="localderby"/> 
        <group-map group-name="org.ofbiz.olap" datasource-name="localderbyolap"/> 
        <group-map group-name="org.ofbiz.tenant" datasource-name="localderbytenant"/> 
</delegator> 
可以发现delegator 将多个group-name组织到一起并将group-name与 datasource-name对应起来,datasource-name又是什么?通过查看 entityengine.xml 我们可以发现: 
<datasource name="localderby" 
            helper-class="org.ofbiz.entity.datasource.GenericHelperDAO" 
            schema-name="OFBIZ" 
            field-type-name="derby" 
            check-on-start="true" 
            add-missing-on-start="true" 
            use-pk-constraint-names="false" 
            use-indices-unique="false" 
            alias-view-columns="false" 
            use-order-by-nulls="true"> 
        <read-data reader-name="seed"/> 
        <read-data reader-name="seed-initial"/> 
        <read-data reader-name="demo"/> 
        <read-data reader-name="ext"/> 
        <inline-jdbc 
                jdbc-driver="org.apache.derby.jdbc.EmbeddedDriver" 
                jdbc-uri="jdbc:derby:ofbiz;create=true" 
                jdbc-username="ofbiz" 
                jdbc-password="ofbiz" 
                isolation-level="ReadCommitted" 
                pool-minsize="2" 
                pool-maxsize="250" 
                time-between-eviction-runs-millis="600000"/> 
</datasource> 
Datasource定义了数据库驱动,数据库用户名、密码等,所以datasource就是我们说的数据库。 
总结一下:我们通过entity-group将各个实体和数据库之间关联起来,然后再将一个或多个数据库归属到一个delegator 中,那我们又是怎么使用数据库进行数据库操作的呢??查看每个模块应用底下的web.xml 我们可以发现: 
<context-param> 
        <param-name>entityDelegatorName</param-name> 
        <param-value>default</param-value> 
        <description>The Name of the Entity Delegator to use, defined in entityengine.xml</description> 
</context-param> 
针对不同的应用,我们可以使用不同的delegator .如果不定义则使用default. 
在启动各个应用模块的时候,系统会根据web.xml 中的 entityDelegatorName 
生成delegator 对象,然后将delegator 对象存放到servletContext 中备用。 
我们就是使用这个delegator对象执行数据库操作,以后会介绍如何使用。 
delegator = DelegatorFactory.getDelegator(delegatorName); 
    servletContext.setAttribute("delegator", delegator); 


3.3. no-auto-stamp 
no-auto-stamp="false" 
entity 属性之一: 将此值设置为true , 则 创建数据库表时将来不创建lastUpdatedStamp、lastUpdatedTxStamp、createdStamp、createdTxStamp 
这四个字段。 
3.4. Field.type 
<field name="tenantId" type="id-ne"/> 
Type , 将数据字段类型 与 java 类型关联起来的设置。 定义文件路径为: 
%ofbiz_home%\framework\entity\fieldtype\fieldtypeXXXXX.xml 
其中XXXX为你使用的数据库名称。 
<field-type-def type="email" sql-type="VARCHAR(255)" java-type="String"/> 
3.5. prim-key 
<prim-key field="agreementId"/> 
定义主键,其中field 需要是已经被定义过的字段,即field 定义过。 
实体支持组合主键,即一个实体定义中可以有多个prim-key节点。 
如果不定义主键的话,数据库是不会创建表的。 

3.6. relation 
relation 定义当前实体和其他实体之间的关系,一般用做创建外键和根据关系查询使用。 
:rel-entity-name:被关联实体名称。 
:fk-name:如果创建外键,那么定义外键的名称。 
:title:给当前关系起个别名。 
: field-name:当前实体的字段,指明当前实体的哪个字段与被关系实体有关系。 
:rel-entity-name:被关系实体名称 
:rel-field-name:被关系的实体的字段名称。指明field-name和被关系实体的哪个字段有关系。如果rel-field-name与field-name相同,那么rel-field-name可以不定义。 
:type="one-nofk":关联类型,主要有三类 “one”、”one-nofk”、”many” 
很多资料上将one 解释为 one-to-one ,将 many 解释为 one-to-many . 
个人感觉不是很好理解,如果从数据库方面去理解的话,one、one-nofk  的使用条件是被关系实体的rel-field-name为主键,而many 的使用条件是被关系实体的rel-field-name为非主键。而one 与 one-nofk 的区别在于one会在数据库表结构中创建外键约束,而one-nofk 则不会。 
Relation 除了用来创建外键约束之外还被用来做关系查询。 
当访问关系的时候可以用 .getRelated("") 或者 .getRelatedOne("") 。用 title+entityName 作为参数。 
当实体一个"many"关系的时候使用getRelated 返回一个列表,当实体一个"one"关系的时候使用getRelatedOne 返回一个实体对象。 

3.7. Index 
<index name="WEFF_KWD_KWD" unique="false"> 
            <index-field name="keyword" function="lower"/> 
</index> 
创建索引。 
: name:给索引起个别名。 
: unique:是否唯一索引。 
:index-field:name:对实体哪个字段创建索引,function待确定。 
4. 定义视图实体 
4.1. Member-entity 
<member-entity entity-alias="EMPPOS" entity-name="EmplPosition"/> 
      <member-entity entity-alias="EMPPOSFUL" entity-name="EmplPositionFulfillment"/> 
member-entity首先定义当前视图实体可能会用到的实体。entity-name实体名称 
entity-alias实体别名。实体定义顺序很重要,除了第一个实体之外其他都是被关联实体。 

4.2. alias 
<alias entity-alias="EMPPOSFUL" name="partyId" field="partyId"/> 
    <alias entity-alias="EMPPOSFUL" name="emplPositionId" function="count"/> 
<alias entity-alias="EMPPOSREPST" name="emplPositionIdReportingTo" group-by="true"/> 

Alias 定义当前视图实体中会用到的字段。entity-alias为实体别名,指当前字段是哪个实体的,field实体字段名称,name字段别名。group-by依据当前字段进行group-by 分组查询。function对当前字段执行function 函数处理 。 
4.3. alias-all 
<alias-all entity-alias="ODD" prefix="orderDate" group-by="true"> 
            <exclude field="dimensionId"/> 
</alias-all> 
alias-all 将某个实体的全部字段定义进来。Prefix定义以规定字段字符开头的字段。 
Exclude 将实体中某些字段剔除出去。 

4.4. View-link 
<view-link entity-alias="SOIF" rel-entity-alias="ODD" rel-optional="false"> 
    <key-map field-name="orderDateDimId" rel-field-name="dimensionId"/> 
   </view-link> 
视图实体中relation 只能用来做关系查询。 
而view-link 用来做 join 关联查询。在entityengine.xml中<datasource ..>元素当中的join-style属性当中设置你的数据库join语法。 
: rel-optional:关联类型,默认是内连接,如果将此属性值设为true ,则为外连接 

4.5. Entity-condition 
<entity-condition> 
     <order-by field-name="sequenceId"/> 
</entity-condition> 
待定 

4.6. 复杂字段 
<alias entity-alias="OI" name="quantityOrdered" function="sum"> 
          <complex-alias operator="-"> 
              <complex-alias-field entity-alias="OI" field="quantity" default-value="0"/> 
              <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0"/> 
          </complex-alias> 
</alias> 
结果为: 
Select  SUM((COALESCE(OI.QUANTITY, 0) - COALESCE(OI.CANCEL_QUANTITY, 0))) 。。。。。。 
一个缺省值是一个良好的习惯,否则当他们之中有一个为空就会导致结果为空 
  这个操作可以支持你使用数据库的所有函数例如  +, -, * 和 /,字符串连接符||。 
你也可以添加一个 function="" 实现min, max, sum, avg, count, count-distinct, upper 和 lower 在 complex-alias-field中。比如: 
<alias entity-alias="OI" > 
      <complex-alias operator="-"> 
          <complex-alias-field entity-alias="OI" field="quantity" default-value="0" function="sum"/> 
          <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0" 
function="sum"/> 
      </complex-alias> 
  </alias> 
结果为SELECT (SUM(COALESCE(OI.QUANTITY,'0')) - SUM(COALESCE(OI.CANCEL_QUANTITY,'0'))) 

这篇关于ofbiz之entity 实体解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799080

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端