Spring + JdbcTemplate + JdbcDaoSupport examples

In Spring framework, the JdbcTemplate and JdbcDaoSupport classes are used to simplify the overall database operation processes. The last tutorial, Spring + Jdbc example will be reuse to compare the different between a project before and after JdbcTemplate support.

No JdbcTemplate

In the last example, you need to create many redundant codes (create connection , close the connection , handle the exception) in all the DAO persist methods – insert, update and delete. It’s not efficient, ugly, error prone and tedious.

private DataSource dataSource;
 
public void setDataSource(DataSource dataSource) {
	this.dataSource = dataSource;
}
 
public void insert(Customer customer){
 
	String sql = "INSERT INTO CUSTOMER " +
			"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
	Connection conn = null;
 
	try {
		conn = dataSource.getConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setInt(1, customer.getCustId());
		ps.setString(2, customer.getName());
		ps.setInt(3, customer.getAge());
		ps.executeUpdate();
		ps.close();
 
	} catch (SQLException e) {
		throw new RuntimeException(e);
 
	} finally {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {}
		}
	}
}

Use JdbcTemplate

With JdbcTemplate, it will handle all the redundant codes.

 
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
 
public void setDataSource(DataSource dataSource) {
	this.dataSource = dataSource;
}
 
public void insert(Customer customer){
 
	String sql = "INSERT INTO CUSTOMER " +
		"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
 
	jdbcTemplate = new JdbcTemplate(dataSource);
 
	jdbcTemplate.update(sql, new Object[] { customer.getCustId(),
				customer.getName(),customer.getAge()  
	});
 
}

See the different?

Extends JdbcDaoSupport

By extended the JdbcDaoSupport, set the datasource and JdbcTemplate in your class is no longer required, you just need to wire the datasource into JdbcCustomerDAO. The JdbcDaoSupport will handle it, and you can get the JdbcTemplate by using a getJdbcTemplate() method.

public class JdbcCustomerDAO extends JdbcDaoSupport implements CustomerDAO
{
	//no need to set datasource here
 
   public void insert(Customer customer){
 
	String sql = "INSERT INTO CUSTOMER " +
		"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
 
	getJdbcTemplate().update(sql, new Object[] { customer.getCustId(),
			customer.getName(),customer.getAge()  
	});
 
  }
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
  <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/mkyongjava" />
	<property name="username" value="root" />
	<property name="password" value="password" />
  </bean>
 
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
  <bean id="customerDAO" class="com.mkyong.customer.dao.impl.JdbcCustomerDAO">
	<property name="dataSource" ref="dataSource" />
  </bean>
 
</beans>

Conclusion

In Spring JDBC programming, It’s always recommend to use JdbcTemplate and JdbcDaoSupport to simplify the overall processes and make your code more reusable.

You can download this full project here – Spring-IDBC-Example.zip

Maven + Spring + JDBC Example

In this tutorial, you will reuse the last simple Maven + Spring hello world example.

Prerequisite requirement

- Create simple Maven + Spring project in last tutorial.
- Installed and configure Maven
- Installed and configured Eclipse IDE
- Installed and configured MySQL

Here’s a demonstration about how to integrate Spring with JDBC to insert a record into a customer table.

1. Customer table

CREATE TABLE `customer` (
  `CUST_ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `NAME` varchar(100) NOT NULL,
  `AGE` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY (`CUST_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

2. Maven dependency

Add Spring and MySQL dependency in pom.xml file.

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mkyong.common</groupId>
  <artifactId>SpringExample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SpringExample</name>
  <url>http://maven.apache.org</url>
 
  <dependencies>
 
    <!-- Spring framework -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring</artifactId>
		<version>2.5.6</version>
	</dependency>
 
    <!-- MySQL database driver -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.9</version>
	</dependency>
 
  </dependencies>
</project>

3. Customer model

Add a customer model to store the customer’s data.

package com.mkyong.customer.model;
 
import java.sql.Timestamp;
 
public class Customer 
{
	int custId;
	String name;
	int age;
	//getter and setter methods
 
}

4. Data Access Object (DAO) pattern

Add dao layer for the Customer.

package com.mkyong.customer.dao;
 
import com.mkyong.customer.model.Customer;
 
public interface CustomerDAO 
{
	public void insert(Customer customer);
	public Customer findByCustomerId(int custId);
}

DAO JDBC implementation with a simple insert and select statement.

package com.mkyong.customer.dao.impl;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
import javax.sql.DataSource;
 
import com.mkyong.customer.dao.CustomerDAO;
import com.mkyong.customer.model.Customer;
 
public class JdbcCustomerDAO implements CustomerDAO
{
	private DataSource dataSource;
 
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
 
	public void insert(Customer customer){
 
		String sql = "INSERT INTO CUSTOMER " +
				"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
		Connection conn = null;
 
		try {
			conn = dataSource.getConnection();
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, customer.getCustId());
			ps.setString(2, customer.getName());
			ps.setInt(3, customer.getAge());
			ps.executeUpdate();
			ps.close();
 
		} catch (SQLException e) {
			throw new RuntimeException(e);
 
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {}
			}
		}
	}
 
	public Customer findByCustomerId(int custId){
 
		String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
 
		Connection conn = null;
 
		try {
			conn = dataSource.getConnection();
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, custId);
			Customer customer = null;
			ResultSet rs = ps.executeQuery();
			if (rs.next()) {
				customer = new Customer(
						rs.getInt("CUST_ID"),
						rs.getString("NAME"), 
						rs.getInt("Age")
				);
			}
			rs.close();
			ps.close();
			return customer;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
			if (conn != null) {
				try {
				conn.close();
				} catch (SQLException e) {}
			}
		}
	}
}

5. Spring bean configuration

Create the Spring bean configuration file for customerDAO and datasource.

Spring-Customer.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="customerDAO" class="com.mkyong.customer.dao.impl.JdbcCustomerDAO">
	<property name="dataSource" ref="dataSource" />
</bean>
 
</beans>
Spring-Datasource.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<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/mkyongjava" />
	<property name="username" value="root" />
	<property name="password" value="password" />
</bean>
 
</beans>
Spring-Module.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<import resource="database/Spring-Datasource.xml"/>
<import resource="customer/Spring-Customer.xml"/>
 
</beans>

6. Review project structure

7. Run it

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.dao.CustomerDAO;
import com.mkyong.customer.model.Customer;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    		new ClassPathXmlApplicationContext("Spring-Module.xml");
 
        CustomerDAO customerDAO = (CustomerDAO) context.getBean("customerDAO");
        Customer customer = new Customer(1, "mkyong",28);
        customerDAO.insert(customer);
 
        Customer customer1 = customerDAO.findByCustomerId(1);
        System.out.println(customer1);
 
    }
}

output

Customer [age=28, custId=1, name=mkyong]

Done ~ Happy Spring programming !

You can download this whole tutorial in zip file – SpringJDBCExample.zip

Spring – Dependency checking with @Required Annotation

Spring’s dependency checking in bean configuration file is used to check all properties of a certain types (primitive, collection or object). In most scenarios, you just need to make sure a particular property has been set, but not all properties of a certain type.

The dependency checking in XML file is not enough to implement this checking, you will need @Required Annotation to make sure a particular property has been set only.

@Required Annotation Example

A Customer object, apply @Required in setPerson() method to make sure the person property has been set.

package com.mkyong.common;
 
import org.springframework.beans.factory.annotation.Required;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
 
	public Person getPerson() {
		return person;
	}
	@Required
	public void setPerson(Person person) {
		this.person = person;
	}
}

Simply apply the @Required annotation will not enforce the property checking, you have to register an RequiredAnnotationBeanPostProcessor to aware of the @Required annotation in bean configuration file.

The RequiredAnnotationBeanPostProcessor can be enabled in two ways.

1. Include <context:annotation-config />

Add Spring context and <context:annotation-config /> in bean configuration file.

<beans 
...
xmlns:context="http://www.springframework.org/schema/context"
...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
...
<context:annotation-config />
...
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
<context:annotation-config />
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>
 
</beans>

2. Include RequiredAnnotationBeanPostProcessor

Include ‘RequiredAnnotationBeanPostProcessor’ directly in bean configuration file.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>
 
</beans>

If you run it , the following error message will throw, because the person property has not been set.

org.springframework.beans.factory.BeanInitializationException: 
Property 'person' is required for bean 'CustomerBean'

Conclusion

The @Required Annotation is more flexible than dependency checking in XML file, because it can apply to a particular property only.

P.S Please read this article about how to create a new custom @Required-style annotation.

Reference

1. http://static.springsource.org/spring/docs/2.5.x/reference/metadata.html#metadata-annotations-required

How to get current timestamps in Java

Here’s a Java example to show how to get current timestamps in Java.

package com.mkyong.common;
 
import java.sql.Timestamp;
import java.util.Date;
 
public class GetCurrentTimeStamp 
{
    public static void main( String[] args )
    {
	 java.util.Date date= new java.util.Date();
	 System.out.println(new Timestamp(date.getTime()));
    }
}

output

2010-03-08 14:59:30.252
Spring – Properties dependency checking

In Spring framework, you can make sure all the required properties have been set in bean by using properties dependency checking feature.

Dependency checking modes

In Spring, 4 dependency checking modes are supported:

  • none – No dependency checking.
  • simple – If any properties of primitive type (int, long,double…) and collection types (map, list..) have not been set, UnsatisfiedDependencyException will be thrown.
  • objects – If any properties of object type have not been set, UnsatisfiedDependencyException will be thrown.
  • all – If any properties of any type have not been set, an UnsatisfiedDependencyException
    will be thrown.

P.S The default mode is none

Example

A Customer and Person object for the demonstration.

package com.mkyong.common;
 
public class Customer 
{
	private Person person;
	private int type;
	private String action;
 
	//getter and setter methods
}
package com.mkyong.common;
 
public class Person 
{
	private String name;
	private String address;
	private int age;
 
	//getter and setter methods	
}

1. none dependency checking

Spring bean configuration file with ‘none’ dependency checking mode.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer" >
	<property name="action" value="buy" />
</bean>
 
<bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address ABC" />
	<property name="age" value="29" />
</bean>
 
</beans>

If you did not explicitly define the dependency checking mode, it’s default to ‘none’. No dependency checking will perform.

2. simple dependency checking

Spring bean configuration file with ’simple’ dependency checking mode.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer" 
         dependency-check="simple">
 
	<property name="person" ref="PersonBean" />
	<property name="action" value="buy" />
</bean>
 
<bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address ABC" />
	<property name="age" value="29" />
</bean>
 
</beans>

The ‘type’ property (primitive type or collection types) have not been set, an UnsatisfiedDependencyException will throw.

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'CustomerBean' 
defined in class path resource [config/Spring-Customer.xml]: 
Unsatisfied dependency expressed through bean property 'type': 
Set this property value or disable dependency checking for this bean.

3. objects dependency checking

Spring bean configuration file with ‘objects’ dependency checking mode.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer" 
         dependency-check="objects">
 
	<property name="action" value="buy" />
	<property name="type" value="1" />
</bean>
 
<bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address ABC" />
	<property name="age" value="29" />
</bean>
 
</beans>

The ‘person’ property (objects type) have not been set, an UnsatisfiedDependencyException will throw.

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'CustomerBean' 
defined in class path resource [config/Spring-Customer.xml]: 
Unsatisfied dependency expressed through bean property 'person': 
Set this property value or disable dependency checking for this bean.

4. all dependency checking

Spring bean configuration file with ‘all’ dependency checking mode.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="CustomerBean" class="com.mkyong.common.Customer" 
         dependency-check="all">
 
	<property name="action" value="buy" />
</bean>
 
<bean id="PersonBean" class="com.mkyong.common.Person">
	<property name="name" value="mkyong" />
	<property name="address" value="address ABC" />
	<property name="age" value="29" />
</bean>
 
</beans>

The combination of ’simple’ and ‘objects’ mode, if any properties of any type (primitive, collection and object) have not been set, an UnsatisfiedDependencyException will be thrown.

Global default dependency checking

Explicitly define the dependency checking mode for every beans is tedious and error prone, you can set a default-dependency-check attribute in the <beans> root element to force all the beans declared within <beans> root element to apply this rule. However, this root default mode will be overridden by a bean’s own mode if specified.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" 
default-dependency-check="all">
 
	<bean id="CustomerBean" class="com.mkyong.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>
 
	<bean id="PersonBean" class="com.mkyong.common.Person">
		<property name="name" value="mkyong" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>
 
</beans>

All beans declared in this configuration file are default to ‘all’ dependency checking mode.

@Required Annotation

In most scenarios, you just need to make sure a particular property has been set, but not all properties of a certain types (primitive, collection or object). The @Required Annotation can enforce this checking, see detail.