Sometimes you want to use a database other than Liferay DXP’s. To do this, its
data source must be defined in portal-ext.properties
or configured as a JNDI
data source on the app server. This tutorial shows how to connect
Service Builder
to a data source. Here’s how:
Step 1: Specify Your Database and a Data Source Name in Your service.xml
In your service.xml
file, specify the same arbitrary data source name for all of the entities, a unique table name for each entity, and a database column name for each column. Here’s an example:
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.1.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_7_1_0.dtd">
<service-builder package-path="com.liferay.example" >
<namespace>TestDB</namespace>
<entity local-service="true" name="Foo" table="testdata" data-source="extDataSource"
remote-service="false" uuid="false">
<column name="id" db-name="id" primary="true" type="long" />
<column name="foo" db-name="foo" type="String" />
<column name="bar" db-name="bar" type="long" />
</entity>
</service-builder>
Note the example’s <entity>
tag attributes:
data-source
: The liferayDataSource
alias ext-spring.xml
specifies.
table
: Your entity’s database table.
Also note that your entity’s <column>
s must have a db-name
attribute set to the column name.
Step 2: Create the Database Manually
Create the database per the database specification in your service.xml
.
Next, use portal properties to set your data source.
Step 3: Specify the Data Source
If the application server defines the data source using JNDI, skip this step.
Otherwise, specify the data source in a portal-ext.properties
file.
Distinguish it from Liferay’s default data source by giving it a prefix other
than jdbc.default.
. This example uses prefix jdbc.ext.
:
jdbc.ext.driverClassName=org.mariadb.jdbc.Driver
jdbc.ext.password=userpassword
jdbc.ext.url=jdbc:mariadb://localhost/external?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.ext.username=yourusername
Step 4: Create a Spring Bean that Points to the Data Source
To do this, create a parent context extension (e.g.,ext-spring.xml
) in your
Service Builder module’s src/main/resources/META-INF/spring/parent
folder or
in your traditional portlet’s WEB-INF/src/META-INF/parent
folder. Create this
folder if it doesn’t exist already.
Define the following elements:
-
A data source factory Spring bean for the data source. It’s different based on the type.
-
JNDI: Specify an arbitrary property prefix and prepend the prefix to a JNDI name property key. Here’s an example:
<bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean" id="liferayDataSourceFactory"> <property name="propertyPrefix" value="custom." /> <property name="properties"> <props> <prop key="custom.jndi.name">jdbc/externalDataSource</prop> </props> </property> </bean>
-
Portal Properties: Specify a property prefix that matches the prefix (e.g.,
jdbc.ext.
) you used inportal-ext.properties
.<bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean" id="liferayDataSourceFactory"> <property name="propertyPrefix" value="jdbc.ext." /> </bean>
-
-
A Liferay data source bean that refers to the data source factory Spring bean.
-
An alias for the Liferay data source bean.
Here’s an example ext-spring.xml
that points to a JNDI data source:
<?xml version="1.0"?>
<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- To define an external data source, the liferayDataSource Spring bean
must be overridden. Other default Spring beans like liferaySessionFactory
and liferayTransactionManager may optionally be overridden.
liferayDataSourceFactory refers to the data source configured on the
application server. -->
<bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
id="liferayDataSourceFactory">
<property name="propertyPrefix" value="custom." />
<property name="properties">
<props>
<prop key="custom.jndi.name">jdbc/externalDataSource</prop>
</props>
</property>
</bean>
<!-- The data source bean refers to the factory to access the data source.
-->
<bean
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
id="liferayDataSource">
<property name="targetDataSource" ref="liferayDataSourceFactory" />
</bean>
<!-- In service.xml, we associated our entity with the extDataSource. To
associate the extDataSource with our overridden liferayDataSource, we define
this alias. -->
<alias alias="extDataSource" name="liferayDataSource" />
</beans>
The liferayDataSourceFactory
above refers to a JNDI data source named
jdbc/externalDataSource
. If the data source is in a portal-ext.properties
file, the bean requires only a propertyPrefix
property that matches the data
source property prefix.
The data source bean liferayDataSource
is overridden with one that refers to
the liferayDataSourceFactory
bean. The override affects this bundle (module or
Web Application Bundle)
only.
The alias extDataSource
refers to the liferayDataSource
data source bean.
Step 5: Set Your Entity’s Data Source to the liferayDataSource
Alias
In your service.xml
file, set your entity’s data source to the
liferayDataSource
alias you specified in your ext-spring.xml
file. Here’s
an example:
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.1.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_7_1_0.dtd">
<service-builder package-path="com.liferay.example" >
<namespace>TestDB</namespace>
<entity local-service="true" name="Foo" table="testdata" data-source="extDataSource"
remote-service="false" uuid="false">
<column name="id" db-name="id" primary="true" type="long" />
<column name="foo" db-name="foo" type="String" />
<column name="bar" db-name="bar" type="long" />
</entity>
</service-builder>
Note the example’s <entity>
tag attributes:
data-source
: The liferayDataSource
alias ext-spring.xml
specifies.
table
: Your entity’s database table.
Also note that your entity’s <column>
s must have a db-name
attribute set to
the column name.
Step 6: Run Service Builder
Run Service Builder. Now your Service Builder services use the data source. You can use the services in your business logic as you always have regardless of the underlying data source.
Congratulations! You’ve connected Service Builder to your external data source.
Related Topics
Connecting to JNDI Data Sources
Running Service Builder and Understanding the Generated Code