Spring jdbcTemplate RowMapper绑定任意对象
RowMapper可以将数据中的每一行封装成用户定义的类,在数据库查询中,如果返回的类型是用户自定义的类型则需要包装,如果是Java自定义的类型,如:String则不需要,Spring最新的类SimpleJdbcTemplate使用更加简单了。
下面这个实例说明了如何使用RowMapp,从网上下载的代码,还行能说明问题。在使用过程中我们可以将内部类做成POJO的外部类,只要实现RowMapper接口即可。如果用户想让ApplicationContext进行定义还是要谨慎。毕竟实现RowMapper接口需要给一个类增加一个mapRow方法,让类承受的功能较多,不利于分析系统。请高手多多指教。
实现一、在内部建立内联类实现RowMapper接口
package hysteria.contact.dao.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import hysteria.contact.dao.ItemDAO;
import hysteria.contact.domain.Item;
public class ItemDAOImpl implements ItemDAO {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public Item insert(Item item) {
String sql = "INSERT INTO items(user_id,name,phone,email) VALUES(?,?,?,?)";
Object[] params = new Object[]{item.getUserId(),item.getName(),item.getPhone(),item.getEmail()};
int[] types = new int[]{Types.INTEGER,Types.VARCHAR,Types.CHAR,Types.VARCHAR};
jdbcTemplate.update(sql,params,types);
return item;
}
public Item update(Item item) {
String sql = "UPDATE items SET name = ?, phone = ?, email = ? WHERE id = ?";
Object[] params = new Object[] {item.getName(),item.getPhone(),item.getEmail(),item.getId()};
int[] types = new int[] {Types.VARCHAR,Types.CHAR,Types.VARCHAR,Types.VARCHAR,Types.INTEGER};
jdbcTemplate.update(sql,params,types);
return item;
}
public void delete(Item item) {
String sql = "DELETE FROM items WHERE id = ?";
Object[] params = new Object[] {item.getId()};
int[] types = new int[]{Types.INTEGER};
jdbcTemplate.update(sql,params,types);
}
public Item findById(int id) {
String sql = "SELECT * FROM items WHERE id = ?";
Object[] params = new Object[] {id};
int[] types = new int[] {Types.INTEGER};
List items = jdbcTemplate.query(sql,params,types,new ItemMapper());
if(items.isEmpty()){
return null;
}
return (Item)items.get(0);
}
public List<Item> findAll() {
String sql = "SELECT * FROM items";
return jdbcTemplate.query(sql,new ItemMapper());
}
public List<Item> findAllByUser(int user_id) {
String sql = "SELECT * FROM items WHERE user_id = ?";
Object[] params = new Object[]{user_id};
int[] types = new int[]{Types.INTEGER};
List items = jdbcTemplate.query(sql,params,types,new ItemMapper());
return items;
}
protected class ItemMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Item item = new Item();
item.setId(rs.getInt("id"));
item.setUserId(rs.getInt("user_id"));
item.setName(rs.getString("name"));
item.setPhone(rs.getString("phone"));
item.setEmail(rs.getString("email"));
return item;
}
}
}
<span style="font-size:18px;">JdbcTemplate 、NamedParameterJdbcTemplate、SimpleJdbcTemplate的区别 一、JdbcTemplate 首先在配置文件中设置数据源 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property> <property name="username" value="scott"></property> <property name="password" value="123"></property> </bean> 然后用我在另一篇博客中提到的配置JdbcTemplate的集中方式,任选一种进行JdbcTemplate的配置,下面我选其中的一种 方式 配置如下信息: <bean id=”jdbcTemplate” class=”org.springframework.jdbc.core.JdbcTemplate”> <property name=”dataSource” ref=”dataSource” /> </bean> 为了能够使用该模板,需要将该类型作为DAO实现类的属性,定义如下形式: public class UserDAOImpl implements UserDAO{ private JdbcTemplate jdbcTemplate public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } } 该DAO实现类配置如下: <bean id="userDAO" class="com.spring.jdbcDAOImpl.UserDAOImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> 做好如上配置后,就可以在DAO实现类中使用模板 二、NamedParameterJdbcTemplate使用 与JdbcTemplate唯一不同的地方是,在给问号赋值的时候,是按照名字对应的。 对NamedParameterJdbcTemplate的配置与上述JdbcTemplate的配置类似 最大的变化在于,sql语句中不使用?来最为参数替代符。而是使用:加变量名的方式作为参数替代符。 然后在通过Map将变量名与实际值绑定起来,传递给update方法。使用这种方式最大的好处就是,如果参数比较多,并且参数位 置或顺序可能变化的情况下, 使用NamedParameterJdbcTemplate是非常方便的! 下面是我从网上找的例子: private static final String MOTORIST_INSERT = ”insert into motorist (id, email, password, ” + “firstName, lastName) values (null, :email, :password, :firstName, :lastName)”; 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()); jdbcTemplate.update(MOTORIST_INSERT, parameters); } 三、SimpleJdbcTemplate使用 SimpleJdbcTemplate加入了Java5的特性支持,例如可变参数、自动拆包封包、泛型等支持。 下面是用SimpleJdbcTemplate实现的findUserByIdSimple(int id) public User findUserByIdSimple(int id) { String sql="select id,user_name,password from td where id=?"; ParameterizedRowMapper mapper=new ParameterizedRowMapper(){ @Override public Object mapRow(ResultSet rs, int rowNum) throws SQLException { User u=new User(); u.setId(rs.getInt("id")); u.setPassword(rs.getString("password")); u.setUser_name(rs.getString("user_name")); return u; } }; //这里的第三个参数 arguments to bind to the query return this.simpleJdbcTemplate.queryForObject(sql,mapper, id); } 这里的ParameterizedRowMapper和RowMapper的最大区别是ParameterizedRowMapper支持泛型 这里的query的方法使用与JdbcTemplate中的query方法使用是有区别的。 第一:JdbcTemplate中的query方法使用Object数组来传递参数,而SimpleJdbcTemplate中的query方法使用的是可变参数, 因为是可变参数,所以需要将可变参数放在参数列表的最后部分。 第二:使用了自动封包机制传递id数据。 第三:进行结果集与对象映射时,使用了ParameterizedRowMapper类型而不是RowMapper类型,其主要区别就是Parameteri -zedRowMapper类型支持泛型。 同样是调用update方法,但是该update方法使用了可变参数,这样就不需要Object数组来进行数据封装, 所有需要赋值问号的参数将直接作为update参数传递。同样是按照index顺序的! 四、使用Spring中的JDBC支持类 这一类型我还没有动手实现,下面是别人写的 通过以上的实现,可以使用各种不同的JDBC模板类进行JDBC访问,但是,如果有很多DAO实现类的定义,我们需要定义很多 重复的代码部分, 如,我们需要在DAO实现类中定义 JdbcTemplate属性,并且定义其get、set方法。另外,需要将其声明在配置文件中。等 等。这些部分是重复的。 spring提供了一种简化的实现方式,它定义了JdbcDaoSupport父类(针对于JdbcTemplate方式的实现),在该类中完成了 重复的代码,我们定义的DAO实现类只需要继承它既可,关系如下图: 通过这种实现,DAO实现类的定义可以简化如下: public class JdbcRantDao extends JdbcDaoSupport implements RantDao { public void saveMotorist(Motorist motorist) { getJdbcTemplate().update(MOTORIST_INSERT, new Object[] { motorist.getEmail(), motorist.getPassword(), motorist.getFirstName(), motorist.getLastName() }); } 中间没有任何JdbcTemplate属性的相关定义。而通过调用getJdbcTemplate()方法获得JdbcTemplate属性。 另外,在配置文件中需要定义如下内容: <bean id=”rantDao” class=”com.roadrantz.dao.jdbc.JdbcRantDao”> <property name=”jdbcTemplate” ref=”jdbcTemplate” /> </bean> 从定义中可看出,与不使用支持类是有相同的定义方式。但是如果我们的DAO实现类继承了JdbcDaoSupport 父类。则其配 置可以省略掉jdbcTemplate内容的定义,直接做如下配置: <bean id=”rantDao” class=”com.roadrantz.dao.jdbc.JdbcRantDao”> <property name=”dataSource” ref=”dataSource” /> </bean> 省略的jdbcTemplate定义和声明过程! 在上面的介绍中,Spring提供了三种不同的模板类,如果我们想使用NamedParameterJdbcTemplate或SimpleJdbcTemplate,则 需要继承不同的模板支持类型,分别是: NamedParameterJdbcDaoSupport与SimpleJdbcDaoSupport </span>