文章目录
JdbcTemplate简介
JdbcTemplate
和DBUtils
一样,是对JDBC的简单封装。
使用JdbcTemplate
将jdbcTemplate注入到dao对象
既然JdbcTemplate是对JDBC的简单封装,那么,它被用于持久化层的Dao对象。所以,第一步要将JdbcTemplate注入Dao对象
<bean id="userDao" class="com.test.dao.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
给jdbcTemplate注入数据源
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
JdbuTemplate提供的方法
用于增、删、改的updata
方法
这个方法和DBUtils中的updata方法及其相似。
int updata(String sql, Objcet... args)
传入一个预编译
的sql语句(使用占位符?
表示可变部分),后面的可边参数列表表示占位符填入的值。
例:
update(insert user(username, password)values(?,?), user.getUsername(), user.getPassword());
用于查询的query
方法
List<T> query(String sql, RowMapper<T> rowmapper, Object... args)
这个方法也和DBUtils中的query方法很相似,不同的地方就是RowMapper<T>
这个参数。
RowMapper<T>
的作用
假设不使用封装的第三方库,而是使用JDBC进行查询,查询的结果为ResultSet
类型,对它的操作类似于一个迭代器,每一次迭代都指向数据库记录中的一行。
对每一行的操作,需要直到取出的每一个值对应对象的哪一个字段,这就是RowMapper
的作用。
自己编写一个RowMapper
private class UserBeanRowMapper implements RowMapper{
@Override
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
User u = new User();
u.setId(resultSet.getInt("id"));
u.setUsername(resultSet.getString("username"));
u.setPassword(resultSet.getString("password"));
return u;
}
}
jdbcTemplate.query
对结果集每一行进行处理时,都会回调这个方法对数据进行封装。
Spring提供的BeanPropertyRowMapper<T>(Class<T>)
官方提供了一个RowMapper
的实现类,不用自己使用者定义。
List<User> list = jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<User>(User.class), null);
解决XML配置下,Dao层代码重复
先来说明一个问题,当时用XML配置时,Dao层的每一个类,都会有以下两句:(使用注解配置,则不存在该问题,注解配置不需要setter方法)
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
造成了重复,所以要将这两句话提取出来。接下来看一下Spring提供的提取这两句代码的方法。
继承JdbcDaoSupport
看一下JdbcDaoSupport
的部分源码
public abstract class JdbcDaoSupport extends DaoSupport {
@Nullable
private JdbcTemplate jdbcTemplate;
public JdbcDaoSupport() {
}
public final void setDataSource(DataSource dataSource) {
if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
this.jdbcTemplate = this.createJdbcTemplate(dataSource);
this.initTemplateConfig();
}
}
protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Nullable
public final JdbcTemplate getJdbcTemplate() {
return this.jdbcTemplate;
}
}
可以看到,将jdbcTemplate
作为一个父类的对象,并且使用setter注入时,可以直接注入数据源,触发setDataSource方法后,会自动创建一个jdbcTemplate
Dao层的类继承了这个类之后,想要使用jdbcTemplate,仅需要调用父类提供的getJdbcTemplate()
方法即可。
请看下面的例子,注入时,直接注入数据源。
<bean id="userDao" class="com.test.dao.UserDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSourceFactory" factory-method="createDataSource">
<constructor-arg name="properties">
<map>
<entry key="username" value="root"></entry>
<entry key="password" value="111111"></entry>
<entry key="driverClassName" value="com.mysql.cj.jdbc.Driver"></entry>
<entry key="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"></entry>
</map>
</constructor-arg>
</bean>
Dao层类继承JdbcDaoSupport类:
public class UserDaoImpl extends JdbcDaoSupport {
//想要使用jdbcTemplate,调用getJdbcTemplate()方法
public List<User> getAll(){
List<User> list = getJdbcTemplate().query("select * from user", new BeanPropertyRowMapper<User>(User.class), null);
return list;
}
}