要从多个数据库中获取数据,那么必然要连接多个数据库,所以必须配置对应的多个datasource。
配置连接数据库在%OFBIZ_HOME%\framework\entity\config\entityengine.xml文件中定义。(ofbiz 16.11版本)
例如:
<datasource name="mysql30"
helper-class="org.apache.ofbiz.entity.datasource.GenericHelperDAO"
field-type-name="mysql"
check-on-start="true"
add-missing-on-start="true"
check-pks-on-start="false"
use-foreign-keys="true"
join-style="ansi-no-parenthesis"
alias-view-columns="false"
drop-fk-use-foreign-key-keyword="true"
table-type="InnoDB"
character-set="utf8"
collate="utf8_general_ci">
<read-data reader-name="tenant"/>
<read-data reader-name="seed"/>
<read-data reader-name="seed-initial"/>
<read-data reader-name="demo"/>
<read-data reader-name="ext"/>
<read-data reader-name="ext-test"/>
<read-data reader-name="ext-demo"/>
<inline-jdbc
jdbc-driver="com.mysql.jdbc.Driver"
jdbc-uri="jdbc:mysql://localhost/ofbiz?autoReconnect=true"
jdbc-username="ofbiz"
jdbc-password="ofbiz"
isolation-level="ReadCommitted"
pool-minsize="2"
pool-maxsize="250"
time-between-eviction-runs-millis="600000"/><!-- Please note that at least one person has experienced a problem with this value with MySQL
and had to set it to -1 in order to avoid this issue.
For more look at http://markmail.org/thread/5sivpykv7xkl66px and http://commons.apache.org/dbcp/configuration.html-->
<!-- <jndi-jdbc jndi-server-name="localjndi" jndi-name="java:/MySqlDataSource" isolation-level="Serializable"/> -->
</datasource>
配置好数据连接后,只能说明和数据库数据传输通路打通了,数据能相互传输了。
但ofbiz的实体引擎还是不知道实体是与哪个数据库对应的,所以必须配置实体与数据库的映射。
ofbiz是通过对实体进行分组,然后把实体组与数据库连接关联起来。
我们每定义一个实体就应该明确的将该实体分到对应的实体分组中,一个实体分组可以包含多个实体。
(猜测:同一个delegator里的一个实体只能对应一个实体分组,如果对应二个分组,这二个分组在不同的delegator应该没问题,但如果在同一个delegator,实体引擎应该会报错。一般一个实体对应一个实体分组就好了。)
默认情况下,实体被分组到了 org.apache.ofbiz 分组中(16.11版本是这样,之前版本好像是org.ofbiz)。
实体分组定义在%OFBIZ_HOME%\specialpurpose\bi\entitydef\entitygroup.xml文件中定义。
<entitygroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitygroup.xsd">
<!-- Dimensions -->
<entity-group group="org.apache.ofbiz.olap" entity="CurrencyDimension"/>
<entity-group group="org.apache.ofbiz.olap" entity="DateDimension"/>
<entity-group group="org.apache.ofbiz.olap" entity="ProductDimension"/>
</entitygroup>
实体组与数据库连接关联的定义在%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.apache.ofbiz" datasource-name="localderby"/>
<group-map group-name="org.apache.ofbiz.olap" datasource-name="localderbyolap"/>
<group-map group-name="org.apache.ofbiz.tenant" datasource-name="localderbytenant"/>
</delegator>
通过上面的配置就可以实现ofbiz项目与多个数据库交互了。
进一步了解。
我们是怎么使用数据库进行数据库操作的呢??查看每个模块应用底下的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>
在启动各个应用模块的时候,系统会根据web.xml 中的 entityDelegatorName
生成delegator 对象,然后将delegator 对象存放到servletContext 中备用。
我们就是使用这个delegator对象执行数据库操作。
delegator = DelegatorFactory.getDelegator(delegatorName);
servletContext.setAttribute("delegator", delegator);
一般情况下,定义一个default就够用了,如果定义多个delegator
针对不同的应用,我们可以修改不同应用下web.xml的 entityDelegatorName配置,将其值设置为对应的delegator名称。
测试:
1.不同数据库的实体能否组成一个实体视图?
结果:可以组成一个实体,可以正常启动,并且在web工具可以查看到定义的实体视图,但是无法查询数据,查询数据时会报错,提示表不存在。
<view-entity entity-name="TestGoupEntity"
package-name="org.apache.ofbiz.system"
never-cache="true"
title="测试不同数据库实体是否可以组成试图">
<member-entity entity-alias="P" entity-name="Product"/>
<member-entity entity-alias="PD" entity-name="ProductDimension"/>
<alias entity-alias="P" name="productId"/>
<alias entity-alias="P" name="productTypeId"/>
<alias entity-alias="PD" name="dimensionId"/>
<view-link entity-alias="P" rel-entity-alias="PD" rel-optional="true">
<key-map field-name="productId"/>
</view-link>
</view-entity>
web工具查看实体视图:
点击查找后报错:
所以一般不要使用不同数据库实体组成一个实体视图。
如果确实有需求要这么做的话,我们可以根据上面的提示知道,报错是由与表不存在,那么我们是不是可以在数据库中定义一个同名的视图,然后这个视图远程连接另一个数据库对应的实体表。