日期:2014-05-16  浏览次数:20459 次

Spring数据库访问(HSQL)(三)
    本文接上一篇继续研究JDBC模板。
    之前说的都是插入操作,在我们使用自增主键的时候有时我们想立刻获得数据库为我们生成的主键值,那么jdbcTemplate是支持这个操作的,只是写起来麻烦一些,可以这么来做:
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		KeyHolder keyHolder = new GeneratedKeyHolder();
		jdbcTemplate.update(new PreparedStatementCreator() {
			public PreparedStatement createPreparedStatement(Connection conn)
					throws SQLException {
				String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
				PreparedStatement pstat = conn.prepareStatement(sql);
				pstat.setString(1, vehicle.getPlate());
				pstat.setString(2, vehicle.getChassis());
				pstat.setString(3, vehicle.getColor());
				pstat.setInt(4, vehicle.getWheel());
				pstat.setInt(5, vehicle.getSeat());
				return pstat;
			}
		}, keyHolder);
		System.out.println("PK: " + keyHolder.getKey().intValue());

    不过HSQL不支持这种写法,那么只能用原始的方法了。调用它特有的获取最后主键值的函数来查找了:
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		jdbcTemplate.update(sql, vehicle.getPlate(), vehicle.getChassis(),
				vehicle.getColor(), vehicle.getWheel(), vehicle.getSeat());
		int id = jdbcTemplate.queryForInt("CALL IDENTITY()");
		System.out.println("PK: " + id);

    这样就会获取到生成主键的值。插入操作的最后一部分是批量插入,批量插入属于和数据库交互比较密集的操作,容易出现性能问题,而jdbc模板为我们提供了简便的方法来执行批量操作,我们来看:
	public void insertBatch(final List<Vehicle> vehicles) {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
			public void setValues(PreparedStatement pstat, int i)
					throws SQLException {
				Vehicle vehicle = vehicles.get(i);
				pstat.setString(1, vehicle.getPlate());
				pstat.setString(2, vehicle.getChassis());
				pstat.setString(3, vehicle.getColor());
				pstat.setInt(4, vehicle.getWheel());
				pstat.setInt(5, vehicle.getSeat());
			}
			public int getBatchSize() {
				return vehicles.size();
			}
		});
	}

    测试时,也很简单:
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(		"classpath:org/ourpioneer/vehicle/spring/applicationContext.xml");
		VehicleDAO vehicleDAO = (VehicleDAO) ctx.getBean("vehicleDAO");
		Vehicle vehicle1 = new Vehicle("辽B-000000", "1A00000001", "RED", 4, 4);
		Vehicle vehicle2 = new Vehicle("辽B-000001", "1A00000002", "RED", 4, 4);
		vehicleDAO.insertBatch(Arrays
				.asList(new Vehicle[] { vehicle1, vehicle2 }));
	}

    到此,JDBC模板的更新操作就介绍完了,以插入操作为例来说明,逐步深入,使用JDBC模板的各种实现方式,其中以可变参数形式传递参数最为简单。下面来看看数据查询,这是概念比较多的一块儿。先从通用的方法来开始看:
	public Vehicle findById(int id) {
		String sql = "select * from vehicle where ID=?";
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		final Vehicle vehicle = new Vehicle();
		jdbcTemplate.query(sql, new Object[] { id }, new RowCallbackHandler() {
			public void processRow(ResultSet rs) throws SQLException {
				vehicle.setId(rs.getInt("ID"));
				vehicle.setPlate(rs.getString("PLATE"));
				vehicle.setChassis(rs.getString("CHASSIS"));
				vehicle.setColor(rs.getString("COLOR"));
				vehicle.setWheel(rs.getInt("WHEEL"));
				vehicle.setSeat(rs.getInt("SEAT"));
			}
		});
		return vehicle;
	}

    用的还是内部类,用返回的结果集对象来填充bean,就得到了结果。第二种方法是使用RowMapper来映射字段到对象。这个也很简单,单独写一个RowMapper的实现:
package org.ourpioneer.vehicle.jt;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.ourpioneer.vehicle.bean.Vehicle;
import org.springframework.jdbc.core.RowMapper;
public class VehicleRowMapper implements RowMapper<Vehicl