Table of Contents
The Spring Framework is a Java-based application framework designed for assisting in application design by providing a way to configure components. The technique used by Spring is a well known design pattern called Dependency Injection (see Inversion of Control Containers and the Dependency Injection pattern). This article will focus on Java-oriented access to MySQL databases with Spring 2.0. For those wondering, there is a .NET port of Spring appropriately named Spring.NET.
Spring is not only a system for configuring components, but also includes support for aspect oriented programming (AOP). This is one of the main benefits and the foundation for Spring's resource and transaction management. Spring also provides utilities for integrating resource management with JDBC and Hibernate.
For the examples in this section the MySQL world sample database will be used. The first task is to set up a MySQL data source through Spring. Components within Spring use the “bean” terminology. For example, to configure a connection to a MySQL server supporting the world sample database, you might use:
<util:map id="dbProps">
<entry key="db.driver" value="com.mysql.cj.jdbc.Driver"/>
<entry key="db.jdbcurl" value="jdbc:mysql://localhost/world"/>
<entry key="db.username" value="myuser"/>
<entry key="db.password" value="mypass"/>
</util:map>
In the above example, we are assigning values to properties that will be used in the configuration. For the datasource configuration:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.jdbcurl}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
The placeholders are used to provide values for properties of this bean. This means that we can specify all the properties of the configuration in one place instead of entering the values for each property on each bean. We do, however, need one more bean to pull this all together. The last bean is responsible for actually replacing the placeholders with the property values.
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="dbProps"/>
</bean>
Now that we have our MySQL data source configured and ready to go, we write some Java code to access it. The example below will retrieve three random cities and their corresponding country using the data source we configured with Spring.
// Create a new application context. this processes the Spring config
ApplicationContext ctx =
new ClassPathXmlApplicationContext("ex1appContext.xml");
// Retrieve the data source from the application context
DataSource ds = (DataSource) ctx.getBean("dataSource");
// Open a database connection using Spring's DataSourceUtils
Connection c = DataSourceUtils.getConnection(ds);
try {
// retrieve a list of three random cities
PreparedStatement ps = c.prepareStatement(
"select City.Name as 'City', Country.Name as 'Country' " +
"from City inner join Country on City.CountryCode = Country.Code " +
"order by rand() limit 3");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
String city = rs.getString("City");
String country = rs.getString("Country");
System.out.printf("The city %s is in %s%n", city, country);
}
} catch (SQLException ex) {
// something has failed and we print a stack trace to analyse the error
ex.printStackTrace();
// ignore failure closing connection
try { c.close(); } catch (SQLException e) { }
} finally {
// properly release our connection
DataSourceUtils.releaseConnection(c, ds);
}
This is very similar to normal JDBC access to MySQL with the main difference being that we are using DataSourceUtils instead of the DriverManager to create the connection.
While it may seem like a small difference, the implications are somewhat far reaching. Spring manages this resource in a way similar to a container managed data source in a J2EE application server. When a connection is opened, it can be subsequently accessed in other parts of the code if it is synchronized with a transaction. This makes it possible to treat different parts of your application as transactional instead of passing around a database connection.