Spring JDBC: Introduction to JdbcTemplate (III)--JdbcTemplate Derivatives

1. JdbcDaoSupport

public abstract class JdbcDaoSupport extends DaoSupport {
	private JdbcTemplate jdbcTemplate;
	public final void setDataSource(DataSource dataSource) {
		if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
			this.jdbcTemplate = createJdbcTemplate(dataSource);
			initTemplateConfig();
		}
	}
	public final JdbcTemplate getJdbcTemplate() {
	  return this.jdbcTemplate;
	}
}

As we can see from the source code that DaoSupport simply added a JdbcTemplate property.

And when we extends JdbcDaoSupport, we don't need to write the redundancy code of setDataSource().

When we need get jdbcTemplate, we simply call getJdbcTemplate() method.

package edu.xmu.jdbc.dao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import edu.xmu.jdbc.bean.Student;

public class JdbcSupportDao extends JdbcDaoSupport {

    public void createStudent(Student student) {
	String sql = "insert into student(name, age) value(?, ?)";
	JdbcTemplate jdbcTemplate = getJdbcTemplate();
	jdbcTemplate.update(sql, student.getName(), student.getAge());
    }
}

2. NamedParameterDaoSupport

public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport {

	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
	  return namedParameterJdbcTemplate;
	}
}

As we can see, when our dao need NamedParameterJdbcTemplate instead of JdbcTemplate,

we can extends NamedParameterDaoSupport.

Spring JDBC: Introduction to JdbcTemplate (III)--JdbcTemplate Derivatives

3. NamedParameterJdbcTemplate

When we execute preparedStatements, we need to use ? as place holder.

But NamedParameterJdbcTemplate offers a mechanism that we can use specific name as holder.

package edu.xmu.jdbc.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

import edu.xmu.jdbc.bean.Student;

public class NamedParameterJdbcTemplateDao extends NamedParameterJdbcDaoSupport {

    /**
     * In this method, we use MapSqlParameterSource for placeholder value
     * mapping
     * 
     * @param student
     */
    public void createStudent(Student student) {
	String sql = "insert into student(name, age) value(:name, :age)";
	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();

	MapSqlParameterSource namedParameters = new MapSqlParameterSource(
		"name", student.getName());
	namedParameters.addValue("age", student.getAge());
	jdbcTemplate.update(sql, namedParameters);
    }

    /**
     * In this method, we use BeanPropertySqlParameterSource for placeholder
     * value mapping
     * 
     * @param student
     */
    public void createStudent2(Student student) {
	String sql = "insert into student(name, age) value(:name, :age)";
	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();

	SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(
		student);
	jdbcTemplate.update(sql, parameterSource);
    }

    /**
     * In this method, we use HashMap for placeholder value mapping
     * 
     * @param student
     */
    public void createStudent3(Student student) {
	String sql = "insert into student(name, age) value(:name, :age)";
	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();

	Map<String, Object> map = new HashMap<String, Object>();
	map.put("name", student.getName());
	map.put("age", student.getAge());

	jdbcTemplate.update(sql, map);
    }

    public Student retrieveStudent(int id) {
	String sql = "select id, name, age from student where id=:id";
	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();

	SqlParameterSource parameters = new MapSqlParameterSource("id", id);
	return jdbcTemplate.queryForObject(sql, parameters,
		new RowMapper<Student>() {

		    public Student mapRow(ResultSet rs, int rowNum)
			    throws SQLException {
			int id = rs.getInt("id");
			String name = rs.getString("name");
			int age = rs.getInt("age");
			return new Student(id, name, age);
		    }

		});
    }

    public void clearTable() {
	String sql = "truncate table student";
	getJdbcTemplate().execute(sql);
    }
}
package edu.xmu.jdbc.dao;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import edu.xmu.jdbc.bean.Student;

public class NamedParameterJdbcTemplateDaoTest {
    private DriverManagerDataSource dataSource;
    private String url = "jdbc:mysql://localhost:3306/jdbctest";
    private String username = "root";
    private String password = "root";

    private NamedParameterJdbcTemplateDao dao;

    @Before
    public void setUp() {
	dataSource = new DriverManagerDataSource(url, username, password);
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");

	dao = new NamedParameterJdbcTemplateDao();
	dao.setDataSource(dataSource);
    }

    @Test
    public void createStudentTest() {
	Student student = new Student("Davy", 24);
	dao.createStudent(student);
	Student returnStudent = dao.retrieveStudent(1);
	System.out.println(returnStudent);
    }

    @Test
    public void createStudent2Test() {
	Student student = new Student("Davy", 24);
	dao.createStudent2(student);
	Student returnStudent = dao.retrieveStudent(1);
	System.out.println(returnStudent);
    }

    @Test
    public void createStudent3Test() {
	Student student = new Student("Davy", 24);
	dao.createStudent3(student);
	Student returnStudent = dao.retrieveStudent(1);
	System.out.println(returnStudent);
    }

    @After
    public void tearDown() {
	dao.clearTable();
    }
}

There are three approaches by which we can substitute placeholdes.

1> Use MapSqlParameterSource

2> Use BeanPropertySqlParameterSource

3> Use simple Map

Spring JDBC: Introduction to JdbcTemplate (III)--JdbcTemplate Derivatives

4. SimpleJdbcTemplate --> Depreciated

1> Enables uncertain query parameters with the technology provided since Java 1.5.

     But this function has been added to JdbcTemplate as well.

2> Enables named placeholder, which is the main function of NamedParameterJdbcTemplate.

3> This class is now depreciated as all its function provided are also provided by other classes.

/**
 * @deprecated since Spring 3.1 in favor of {@link org.springframework.jdbc.core.JdbcTemplate} and
 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}. The JdbcTemplate and
 * NamedParameterJdbcTemplate now provide all the functionality of the SimpleJdbcTemplate.
 */
@Deprecated
public class SimpleJdbcTemplate implements SimpleJdbcOperations{
...
}

5. Retrieve auto-generated keys

1) When we use auto-generated policy in db primary key generation,

    after we execute CUD operation, we need to get the new ID.

    That would be redundancy if we execute a query after that.

2) Spring JDBC offers a class KeyHolder for this special purpose.

1> Method in JdbcTemplate

public int update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder);

2> Method in NamedParameterJdbcTemplate

public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder);
public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames);

Example for JdbcTemplate:

package edu.xmu.jdbc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import edu.xmu.jdbc.bean.Student;

public class JdbcTemplateKey extends JdbcDaoSupport {

    public int createStudent(final Student student) {
	final String sql = "insert into student(name, age) values(?, ?)";

	JdbcTemplate jdbcTemplate = getJdbcTemplate();
	KeyHolder keyHolder = new GeneratedKeyHolder();

	jdbcTemplate.update(new PreparedStatementCreator() {
	    public PreparedStatement createPreparedStatement(Connection con)
		    throws SQLException {
		PreparedStatement ps = con.prepareStatement(sql,
			new String[] { "id" });
		ps.setString(1, student.getName());
		ps.setInt(2, student.getAge());
		return ps;
	    }
	}, keyHolder);

	return keyHolder.getKey().intValue();
    }
}

Example for NamedParameterJdbcTemplate

package edu.xmu.jdbc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import edu.xmu.jdbc.bean.Student;

public class NamedParameterJdbcTemplateKey extends NamedParameterJdbcDaoSupport {

    public int createStudent(final Student student) {
	final String sql = "insert into student(name, age) values(?, ?)";

	JdbcTemplate jdbcTemplate = getJdbcTemplate();
	KeyHolder keyHolder = new GeneratedKeyHolder();

	jdbcTemplate.update(new PreparedStatementCreator() {
	    public PreparedStatement createPreparedStatement(Connection con)
		    throws SQLException {
		PreparedStatement ps = con.prepareStatement(sql,
			new String[] { "id" });
		ps.setString(1, student.getName());
		ps.setInt(2, student.getAge());
		return ps;
	    }
	}, keyHolder);

	return keyHolder.getKey().intValue();
    }

    public int createStudent2(Student student) {
	String sql = "insert into student(name, age) values(:name, :age)";

	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();
	KeyHolder keyHolder = new GeneratedKeyHolder();

	SqlParameterSource paramSource = new BeanPropertySqlParameterSource(
		student);

	int rowCount = jdbcTemplate.update(sql, paramSource, keyHolder);
	System.out.println(rowCount + " row affected.");

	return keyHolder.getKey().intValue();
    }

    public int createStudent3(Student student) {
	String sql = "insert into student(name, age) values(:name, :age)";

	NamedParameterJdbcTemplate jdbcTemplate = getNamedParameterJdbcTemplate();
	KeyHolder keyHolder = new GeneratedKeyHolder();

	SqlParameterSource paramSource = new BeanPropertySqlParameterSource(
		student);

	int rowCount = jdbcTemplate.update(sql, paramSource, keyHolder,
		new String[] { "id" });

	System.out.println(rowCount + " row affected.");

	return keyHolder.getKey().intValue();
    }
}
package edu.xmu.jdbc.dao;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import edu.xmu.jdbc.bean.Student;

public class NamedParameterJdbcTemplateKeyTest {
    private DriverManagerDataSource dataSource;
    private String url = "jdbc:mysql://localhost:3306/jdbctest";
    private String username = "root";
    private String password = "root";

    private NamedParameterJdbcTemplateKey dao;

    @Before
    public void setUp() {
	dataSource = new DriverManagerDataSource(url, username, password);
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");

	dao = new NamedParameterJdbcTemplateKey();
	dao.setDataSource(dataSource);
    }

    @Test
    public void createStudentTest() {
	Student student = new Student("Davy", 24);
	int id = dao.createStudent(student);

	System.out.println("Generated id: " + id);
    }

    @Test
    public void createStudent2Test() {
	Student student = new Student("Davy", 24);
	int id = dao.createStudent2(student);

	System.out.println("Generated id: " + id);
    }

    @Test
    public void createStudent3Test() {
	Student student = new Student("Davy", 24);
	int id = dao.createStudent3(student);

	System.out.println("Generated id: " + id);
    }

    @After
    public void tearDown() {
    }
}

相关推荐