Connecting the Data Source Using a DataSourceProvider

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:

  1. 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: 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.

  2. Manually create the database you defined in your service.xml.

  3. 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 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
    
  4. Restart your server if you defined your data source using portal properties.

  5. Connect your Service Builder module to the data source by implementing the DataSourceProvider interface. Since the DataSourceProvider must be visible to your *-service module class loader, it’s common to put the DataSourceProvider in the *-service module.

    This example uses DataSourceFactoryUtil to create a data source from portal properties that have the prefix jdbc.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);
    		}
    	}
    
    }
    
  6. 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 the DataSourceProvider implementation from the previous step.

    com.liferay.external.data.source.test.internal.DataSourceProviderImpl
    
  7. Run Service Builder.

  8. Deploy your -service module. If your DataSourceProvider is in a different project, deploy it too.

Congratulations! Your module’s Service Builder services are persisting data to your external data source.

Connecting to JNDI Data Sources

Service Builder

Business Logic with Service Builder

« Connecting Service Builder to an External DatabaseConnecting the Data Source Using Spring Beans »
Was this article helpful?
2 out of 4 found this helpful