JDBC部要求我们掌握其他框架的查询语言,它是基于SQL这种数据访问语言的。JDBC很多便捷的功能是很多框架不能比的,但是JDBC也不是十全十美的,它具有强大的功能、灵活性和其他一些优点,但也有缺点。
传统的JDBC对数据库的操作,有很多重复的代码,这样给程序员带来了很多额外的工作量,Spring提供了JDBC模板很好的解决了这个问题,由于传统的方法比较简单,在这里不介绍了,直接说模板吧。
使用JDBC模板:
Spring的JDBC框架能够承担资源管理和异常处理的工作。对于JDBC来说,Spring提供了3个模板类
JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。
NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。
SimpleJdbcTemplate:利用Java 5 的特性,比如自动装箱、通用(generic)和可变参数类表来简化JDBC模板的使用。
使用JdbcTemplate来访问数据
只需要配置DataSource就能够让JdbcTemplate工作,如下配置:
现在我们可以把JdbcTemplate装配到DAO,使用它来访问数据库
public class JdbcRantDao{
//配置JdbcTemplate
private jdbcTemplate jdbcTemplate;
public void setJdbcTempalte(JdbcTemplate jdbcTempalte) {
this.jdbcTempalte = jdbcTempalte;
}
//写入Motorist的SQL语句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//获取所有Motorist的SQL语句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//获取某一个Motorist的SQL语句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
/**
* 利用JDBC模板往数据库里添加一行数据
* @param motorist
*/
public void saveMotorist(Motorist motorist){
jdbcTemplate.update(MOTORIST_INSERT, new Object[] {motorist.getEmail(),motorist.getPassword(),motorist.getFirstName(),motorist.getLastName()});
}
/**
* 利用JDBC模板从数据库中读取一个数据
* @param id
* @return
*/
public Motorist getMotoristById(int id){
List matches = jdbcTemplate.query(MOTORIST_BY_ID_SELECT,
new Object[] {Integer.valueOf(id)},
new RowMapper(){
public Object mapRow(ResultSet rs,int rowNum)
throws SQLException,DataAccessException{
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
});
return matches.size() > 0 ? (Motorist) matches.get(0) : null;
}
}
使用命名参数:使用了索引参数以为着把参数传递给update()方法时,我们必须注意参数在查询里的次数,并且以正确的次序列出相应的值。为了避免这种情况,我们可以使用命名参数。
public void saveMotorist(Motorist motorist){
Map parameters = new HashMap();
parameters.put("email", motorist.getEmail());
parameters.put("password", motorist.getPassword());
parameters.put("firstName", motorist.getFirstName());
parameters.put("lastName", motorist.getLastName());
namedParameterJdbcTemplate.update(MOTORIST_INSERT, parameters);
}
在Java5里简化JDBC:之前传递给update()方法的参数是Object数组,但是使用java5的新特性,可以不必构造Object数组就可以传递参数。
SimpleJdbcTemplate不仅能支持可变参数来绑定参数值,在映射结果集时还利用了Java 5 对自动装箱的支持。再看一下下列程序里的getMotoristById(),应该注意两件事:
id参数必须转化为一个包裹类型(java.lang.Long)才能在Object数组里进行传递。
RowMapper的mapRow()方法的返回类型是java.lang.Object。这是因为RowMapper的通用性要求它支持任何类型的对象,所以返回的结果的类型是最通用的类型:Object。
package org.spring.source.jdbc.template;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
public class SimpleJdbcRantDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
//写入Motorist的SQL语句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//获取所有Motorist的SQL语句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//获取某一个Motorist的SQL语句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
public void setSimpleJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
this.simpleJdbcTemplate = simpleJdbcTemplate;
}
public SimpleJdbcTemplate getSimpleJdbcTemplate() {
return simpleJdbcTemplate;
}
public void saveMotorist(Motorist motorist){
simpleJdbcTemplate.update(MOTORIST_INSERT, motorist.getEmail(), motorist.getPassword(), motorist.getFirstName(), motorist.getLastName());
}
public Motorist getMotoristById(int id){
List matches = getSimpleJdbcTemplate().query(
MOTORIST_BY_ID_SELECT,
new ParameterizedRowMapper(){
public Motorist mapRow(ResultSet rs, int rowNum)
throws SQLException {
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
},
id //显示id没有被包裹
);
return matches.size() > 0 ? matches.get(0) : null;
}
}
使用Spring对JDBC的DAO支持类:Spring的JdbcDaoSupport用于编写基于JDBC的DAO类的基类,我们只需让自己的DAO类继承它即可。
package org.spring.source.jdbc.template;
import java.sql.SQLException;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.sql.ResultSet;
public class JdbcRantDao extends JdbcDaoSupport{
//写入Motorist的SQL语句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//获取所有Motorist的SQL语句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//获取某一个Motorist的SQL语句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
/**
* 利用JDBC模板往数据库里添加一行数据
* @param motorist
*/
public void saveMotorist(Motorist motorist){
getJdbcTemplate().update(MOTORIST_INSERT, new Object[] {motorist.getEmail(),motorist.getPassword(),motorist.getFirstName(),motorist.getLastName()});
}
/**
* 利用JDBC模板从数据库中读取一个数据
* @param id
* @return
*/
public Motorist getMotoristById(int id){
List matches = getJdbcTemplate().query(MOTORIST_BY_ID_SELECT,
new Object[] {Integer.valueOf(id)},
new RowMapper(){
public Object mapRow(ResultSet rs,int rowNum)
throws SQLException,DataAccessException{
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
});
return matches.size() > 0 ? (Motorist) matches.get(0) : null;
}
}