Configuring Spring to useMultiple Data Sources - java

I am trying to connect 2 different schemas within my spring boot application.
To do this I have got 2 different data sources. How should I configure this within my properties files?
I seen this answer which gave me an idea of how to do so. I currently have the following 3 property files in my application:
1. application.properties
2. hibernate.properties
3. multiple-db.properties
application.properties is currently empty. Below are the other 2 files:
hibernate.properties:
# Connection configuration
hibernate.connection.username= my_uname1
hibernate.connection.password= my_pword1
multiple-db.properties:
# Schema 1-Data source configuration
oracle.db.username1= my_uname1
oracle.db.password1= my_pword1
oracle.db.url1= my_url1
# Schema 2-Data source configuration
oracle.db.username2= my_uname2
oracle.db.password1= my_pword2
oracle.db.url2= my_url2
# JPA configuration
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
# Hibernate configuration
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.url=my_url
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider
Is this the correct approach? Do I need 3 properties files, or could I do this all in one?

The Spring documentation suggests a way to create primary and secondary data sources:
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources
Each data source can be configured as described here:
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-configure-a-datasource
You can access them by using #Autowire from other beans. You can associate a prefix to each data source so you can configure it in your application.properties or application.yml file.
You can also set one as primary.

With Spring you can do this easily.
It would be something like this:
<bean id="dataSource_1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/northwind" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="dataSource_2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/northwind_dup" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
You could also use your properties files and do something like this:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
And you could use only one file, or three. It is really up to you.

Related

What is difference between PropertyOverrideConfigurer and PropertyPlaceholderConfigurer?

What are the differences between using PropertyOverrideConfigurer and PropertyPlaceholderConfigurer in the Spring framework? I'm unable to find any solid difference between these 2 classes.
PropertyOverrideConfigurer :
"Property resource configurer that overrides bean property values in
an application context definition. It pushes values from a properties
file into bean definitions."
it allows you to override some values that beans take, means you can override some values of spring beans from properties defined in property file
declare:
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="location" value="classpath:myproperties.properties" />
</bean>
<bean id="person" class="com.sample.Employee" >
<property name="name" value="Dugan"/>
<property name="age" value="50"/>
</bean>
myproperties.properties:
person.age=40
person.name=Stanis
so when you load the bean
Employee e = (Employee)context.getBean(Employee.class);
e.getAge() => 40
e.getName() => "Stanis"
PropertyPlaceholderConfigurer :
resolves ${...} placeholders against local properties and/or system
properties and environment variables.
it allows you to resolve ${..} placeholders in bean definitions, it also checks for System properties for values. This behavior can be controlled with systemPropertiesMode
never (0): Never check system properties
fallback (1): Check system properties if not resolvable in the
specified properties files. This is the default.
override (2): Check system properties first, before trying the
specified properties files. This allows system properties to override
any other property source.
to configure
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="password" />
<property name="systemPropertiesMode" value="0" />
</bean>
move the 'dataSource' properties to property files
database.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password=password
then refer them with place holders =>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>database.properties</value>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

JAVA + PostgreSQL + Spring

I want to use Spring to connect to my local PostgreSQL db. I don't know if it is possible, cause I didn't find any tutorials for this. So is it possible? If yes, please explain me where can I find some fine tutorial. If no, how can I do it? I know I can make it via postgresql jdbc, but I want to do it like in real company.
Of course you can. The database vendor is immaterial. Java hides database details using JDBC.
Here is a Spring tutorial that shows you how to do it in 15 minutes or less.
First you need to create a spring project from https://start.spring.io/ and add postgresql to its dependencies. You will then see it build up in your pom.xml file. Then you have to enter the information of the postgresql database you want to connect to in the application.yml file.
Here is my example.
applicationContext.xml :
<!-- the setting msg -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/database.properties</value>
</list>
</property>
</bean>
<!-- PostgreSQL datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- ibatis client -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:config/SqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

Apache Camel - Read JDBC dataSource properties from file

i'm using Apache Camel and i try to load datasource properties from this file
config.properties:
url = my_url
user = user_name
password = user_pass
this is dataSource (blueprint.xml):
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="my_url"/>
<property name="user" value="user_name"/>
<property name="password" value="user_pass"/>
</bean>
How can i read values from config.properties and insert them into dataSource properties ?
You talk about blueprint.xml, and camel, so I assume you are in an osgi container like Karaf/ServiceMix, and you are using Aries Blueprint.
Then you can use the cm namespace and a property-placeholder. If you use camel and want your properties to be dynamically reloaded, then you can use too an update strategy reload, which start/stop the blueprint container when the configuration change. This will load the configuration with pid "datasource" (ie, in karaf, the file etc/datasource.cfg) :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0">
<cm:cm-properties id="myProps" persistent-id="datasource" update-strategy="reload"/>
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="${url}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
</blueprint>
If you want to use your configuration file without using ConfigurationAdmin or dynamically reload your bundle, then you can use the ext namespace :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0">
<ext:property-placeholder>
<ext:location>file:config.properties</ext:location>
</ext:property-placeholder>
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="${url}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
</blueprint>
According to code I assume you use probably spring as container. General solution in spring is to use PropertyPlaceHolder, your configuration will look like this:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>config.properties</value>
</property>
</bean>
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="${jdbc.myUrl}"/>
<property name="user" value="${jdbc.user_name}"/>
<property name="password" value="${jdbc.user_pass}"/>
</bean>
Please check the example for details.

Advantage of org.springframework.jdbc.datasource.DriverManagerDataSource over oracle.jdbc.pool.OracleDataSource

I currently use this configuration for my projects:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="URL" ...
<property name="user" ...
<property name="password" ...
<property name="connectionCachingEnabled" value="true" />
And it works fine, pretty fast.
I happened to see, on an old project (spring 2.5) this configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url"...
<property name="username" ...
<property name="password" ...
</bean>
From documentation it would seem that this last option does not make use of a connection pool. I see no reason to use this configuration over mine, but it still exists so I am curious: where's the advantage/limitation?
1st configuration is oracle specific, whereas 2nd configuration is generic. You can explicitly define driver class.
This is the only major difference I can see in them other than connection pool support of OracleDataSource.
You can use it for generic behavior as mentioned below:
<bean id="baseDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="username" value="user"/>
<property name="password" value="pwd" />
</bean>
<bean id="mySqlDataSource" parent="baseDataSource">
<property name="driverClassName" value="${mySQL.driver}" />
<property name="url" value="${mySQL.url}"/>
</bean>
<bean id="oracleDataSource" parent="baseDataSource">
<property name="driverClassName" value="${oracle.driver}" />
<property name="url" value="${oracle.url}"/>
</bean>
Property values you can externalized.
You can explore Apache Jakarta Commons DBCP which has all the features of DriverManagerDataSource
along with connection pool feature.

How to do arithmetic in Spring properties, with values from a properties file?

Example use-case: properties file passes in a numeric value in millis, and you want to use it in seconds.
Your .properties file:
jdbc.timeout= 2000
Your applicationContext.xml currently
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"value="jdbc:mysql://myserver/mydb" />
<property name="username" value="user" />
<property name="password" value="changeme" />
<property name="validationQuery" value="SELECT 1;"/>
<property name="validationQueryTimeout" value="${jdbc.timeout}" />
</bean>
You want the validationQueryTimeout value to be in seconds, how do you convert it?
If you're using Spring 3.0 or later, you can use the property inside the SpEL expression like this:
<property name="validationQueryTimeout" value="#{${jdbc.timeout}/1000}" />

Categories