Skip to content
Snippets Groups Projects
Commit a8cc0068 authored by Costin Leau's avatar Costin Leau Committed by Mic
Browse files

SPR-6447

+ extracted datasource definition into a separate file to eliminate redundancy
+ introduce jdbc: namespace



parent 5db88f47
No related branches found
No related tags found
No related merge requests found
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.config;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.Resource;
/**
* A factory that creates a data source fit for use in a system environment. Creates a DBCP simple data source
* from the provided connection properties.
*
* This factory returns a fully-initialized DataSource implementation. When the DataSource is returned, callers are
* guaranteed that the database schema and data will have been loaded by that time.
*
* Is a FactoryBean, for exposing the fully-initialized DataSource as a Spring bean. See {@link #getObject()}.
*
* @author Chris Beams
* @author Scott Andrews
*/
public class DbcpDataSourceFactory implements FactoryBean<DataSource>, DisposableBean {
// configurable properties
private String driverClassName;
private String url;
private String username;
private String password;
private boolean populate;
private Resource schemaLocation;
private Resource dataLocation;
private Resource dropLocation;
/**
* The object created by this factory.
*/
private BasicDataSource dataSource;
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
/**
* The data source connection URL
*/
public void setUrl(String url) {
this.url = url;
}
/**
* The data source username
*/
public void setUsername(String username) {
this.username = username;
}
/**
*The data source password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Indicates that the data base should be populated from the schema and data locations
*/
public void setPopulate(boolean populate) {
this.populate = populate;
}
/**
* Sets the location of the file containing the schema DDL to export to the database.
* @param schemaLocation the location of the database schema DDL
*/
public void setSchemaLocation(Resource schemaLocation) {
this.schemaLocation = schemaLocation;
}
/**
* Sets the location of the file containing the data to load into the database.
* @param testDataLocation the location of the data file
*/
public void setDataLocation(Resource testDataLocation) {
this.dataLocation = testDataLocation;
}
/**
* Sets the location of the file containing the drop scripts for the database.
* @param testDataLocation the location of the data file
*/
public void setDropLocation(Resource testDropLocation) {
this.dropLocation = testDropLocation;
}
// implementing FactoryBean
// this method is called by Spring to expose the DataSource as a bean
public DataSource getObject() throws Exception {
if (dataSource == null) {
initDataSource();
}
return dataSource;
}
public Class<DataSource> getObjectType() {
return DataSource.class;
}
public boolean isSingleton() {
return true;
}
// implementing DisposableBean
public void destroy() throws Exception {
dataSource.close();
}
// internal helper methods
// encapsulates the steps involved in initializing the data source: creating it, and populating it
private void initDataSource() {
// create the database source first
this.dataSource = createDataSource();
if (this.populate) {
// now populate the database by loading the schema and data
populateDataSource();
}
}
private BasicDataSource createDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(this.driverClassName);
dataSource.setUrl(this.url);
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
return dataSource;
}
private void populateDataSource() {
DatabasePopulator populator = new DatabasePopulator(dataSource);
if (dropLocation != null) {
try {
populator.populate(this.dropLocation);
}
catch (Exception e) {
// ignore
}
}
populator.populate(this.schemaLocation);
populator.populate(this.dataLocation);
}
/**
* Populates a in memory data source with data.
*/
private class DatabasePopulator {
private DataSource dataSource;
/**
* Creates a new database populator.
* @param dataSource the data source that will be populated.
*/
public DatabasePopulator(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Populate the database executing the statements in the provided resource against the database
* @param sqlFile spring resource containing SQL to run against the db
*/
public void populate(Resource sqlFile) {
Connection connection = null;
try {
connection = dataSource.getConnection();
try {
String sql = parseSqlIn(sqlFile);
executeSql(sql, connection);
} catch (IOException e) {
throw new RuntimeException("I/O exception occurred accessing the database schema file", e);
} catch (SQLException e) {
throw new RuntimeException("SQL exception occurred exporting database schema", e);
}
} catch (SQLException e) {
throw new RuntimeException("SQL exception occurred acquiring connection", e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
}
// utility method to read a .sql txt input stream
private String parseSqlIn(Resource resource) throws IOException {
InputStream is = null;
try {
is = resource.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringWriter sw = new StringWriter();
BufferedWriter writer = new BufferedWriter(sw);
for (int c=reader.read(); c != -1; c=reader.read()) {
writer.write(c);
}
writer.flush();
return sw.toString();
} finally {
if (is != null) {
is.close();
}
}
}
// utility method to run the parsed sql
private void executeSql(String sql, Connection connection) throws SQLException {
Statement statement = connection.createStatement();
statement.execute(sql);
}
}
}
......@@ -22,10 +22,8 @@ jdbc.username=sa
jdbc.password=
# Properties that control the population of schema and data for a new data source
jdbc.populate=true
jdbc.schemaLocation=classpath:db/hsqldb/initDB.txt
jdbc.initLocation=classpath:db/hsqldb/initDB.txt
jdbc.dataLocation=classpath:db/hsqldb/populateDB.txt
jdbc.dropLocation=classpath:db/hsqldb/dropTables.txt
# Property that determines which Hibernate dialect to use
# (only applied with "applicationContext-hibernate.xml")
......@@ -43,14 +41,12 @@ jpa.database=HSQL
#jdbc.driverClassName=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/petclinic
#jdbc.username=pc
#jdbc.password=pc
#jdbc.username=root
#jdbc.password=
# Properties that control the population of schema and data for a new data source
#jdbc.populate=false
#jdbc.schemaLocation=classpath:db/mysql/initDB.txt
#jdbc.dataLocation=classpath:db/mysql/populateDB.txt
#jdbc.dropLocation=classpath:db/mysql/dropTables.txt
# Property that determines which Hibernate dialect to use
# (only applied with "applicationContext-hibernate.xml")
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
Application context definition for PetClinic Datasource.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<!-- ========================= DATASOURCE DEFINITION ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- DataSource configuration for Apache Commons DBCP. -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}"/>
<!-- JNDI DataSource for JEE environments -->
<!--
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
-->
<!-- Database initializer. If any of the script fails, the initialization stops. -->
<!-- As an alternative, for embedded databases see <jdbc:embedded-database/>. -->
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="${jdbc.initLocation}"/>
<jdbc:script location="${jdbc.dataLocation}"/>
</jdbc:initialize-database>
</beans>
\ No newline at end of file
......@@ -4,41 +4,18 @@
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<!-- (in this case, Hibernate-related settings for the sessionFactory definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
Uses Apache Commons DBCP for connection pooling. See Commons DBCP documentation
for the required JAR files. Alternatively you can use another connection pool
such as C3P0, similarly configured using Spring.
-->
<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"/>
<!-- DataSource configuration for Apache Commons DBCP. -->
<!--
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
-->
<!-- JNDI DataSource for JEE environments -->
<!--
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
-->
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingResources="petclinic.hbm.xml">
......@@ -94,4 +71,4 @@
<!-- Hibernate's JMX statistics service -->
<bean name="petclinic:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/>
</beans>
</beans>
\ No newline at end of file
......@@ -3,45 +3,18 @@
Application context definition for PetClinic on JDBC.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
Spring FactoryBean that creates a DataSource using Apache Commons DBCP for connection
pooling. See Commons DBCP documentation for the required JAR files. This factory bean
can populate the data source with a schema and data scripts if configured to do so.
An alternate factory bean can be created for different connection pool implementations,
C3P0 for example.
-->
<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"/>
<!-- DataSource configuration for Apache Commons DBCP. -->
<!--
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
-->
<!-- JNDI DataSource for JEE environments -->
<!--
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
-->
<!-- import the dataSource definition -->
<import resource="applicationContext-dataSource.xml"/>
<!-- Transaction manager for a single JDBC DataSource (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
......@@ -88,4 +61,4 @@
<!-- Call monitoring aspect that monitors call count and call invocation time -->
<bean id="callMonitor" class="org.springframework.samples.petclinic.aspects.CallMonitoringAspect"/>
</beans>
</beans>
\ No newline at end of file
......@@ -4,17 +4,18 @@
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- import the dataSource definition -->
<import resource="applicationContext-dataSource.xml"/>
<!--
Activates a load-time weaver for the context. Any bean within the context that
implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
......@@ -23,34 +24,10 @@
<context:load-time-weaver/>
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<!-- (in this case, JDBC-related settings for the JPA EntityManager definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
Spring FactoryBean that creates a DataSource using Apache Commons DBCP for connection
pooling. See Commons DBCP documentation for the required JAR files. This factory bean
can populate the data source with a schema and data scripts if configured to do so.
An alternate factory bean can be created for different connection pool implementations,
C3P0 for example.
-->
<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"/>
<!-- DataSource configuration for Apache Commons DBCP. -->
<!--
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
-->
<!-- JNDI DataSource for JEE environments -->
<!--
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
-->
<!-- JPA EntityManagerFactory -->
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
......@@ -108,4 +85,4 @@
-->
<bean id="clinic" class="org.springframework.samples.petclinic.jpa.EntityManagerClinic"/>
</beans>
</beans>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment