Connecting to an external database by creating and registering a
DataSourceProvider
as a JDK
ServiceProviderInterface
(SPI) is the easiest way. This approach works regardless of whether your Service
Builder module uses the ds
or spring
dependency injection option
and it requires the fewest files and steps.
Here are the steps:
-
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.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_2_0.dtd"> <service-builder dependency-injector="spring" 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
: TheliferayDataSource
aliasext-spring.xml
specifies.table
: Your entity’s database table.Also note that your entity’s
<column>
s must have adb-name
attribute set to the column name. -
Manually create the database you defined in your
service.xml
. -
Define the data source. One way is to use portal properties in a
portal-ext.properties
file. Distinguish your data source from Liferay’s default data source by giving it a prefix other thanjdbc.default.
. This example uses prefixjdbc.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
-
Restart your server if you defined your data source using portal properties.
-
Connect your Service Builder module to the data source by implementing the
DataSourceProvider
interface. Since theDataSourceProvider
must be visible to your*-service
module class loader, it’s common to put theDataSourceProvider
in the*-service
module.This example uses
DataSourceFactoryUtil
to create a data source from portal properties that have the prefixjdbc.ext.
.package com.liferay.external.data.source.test.internal; import com.liferay.portal.kernel.dao.jdbc.DataSourceFactoryUtil; import com.liferay.portal.kernel.dao.jdbc.DataSourceProvider; import com.liferay.portal.kernel.util.PropsUtil; import javax.sql.DataSource; public class DataSourceProviderImpl implements DataSourceProvider { @Override public DataSource getDataSource() { try { return DataSourceFactoryUtil.initDataSource( PropsUtil.getProperties("jdbc.ext.", true)); } catch (Exception e) { throw new RuntimeException(e); } } }
-
Register the implementation as a JDK
ServiceProviderInterface
(SPI) in a/META-INF/services/com.liferay.portal.kernel.dao.jdbc.DataSourceProvider
file in your*-service
module. For example, this file registers theDataSourceProvider
implementation from the previous step.com.liferay.external.data.source.test.internal.DataSourceProviderImpl
-
Deploy your
-service
module. If yourDataSourceProvider
is in a different project, deploy it too.
Congratulations! Your module’s Service Builder services are persisting data to your external data source.