为什么要整合JDBC
使用Spring框架整合JDBC,主要目的是为了简化JDBC编程,将JDBC的复杂细节进行封装。
例如总是要获得连接、获得语句对象以及总是要捕获各种异常等。
Spring框架提供了整合JDBC的API,能够大大简化JDBC编程的烦琐细节,借助IoC容器能够进一步提升应用的扩展性。
Spring JDBC包结构
Spring中的JDBC包主要有四个:
①org.springframework.jdbc.core包
该包是Spring框架JDBC包的核心包,由JdbcTemplate类以及其他回调接口组成,其中JdbcTemplate类是Spring JDBC抽象层的核心类。
②org.springframework.jdbc.datasource包
该包主要是由一些简化DataSource访问的工具类组成的。
③org.springframework.jdbc.object包
该包是由一些封装了查询、更新、存储过程的类组成的,是org.springframework.jdbc.core包的更高层次抽象。
④org.springframework.jdbc.support包
该包提供了一些SQLException转换类以及一些相关的工具类。
JdbcTemplate类
JdbcTemplate类是Spring JDBC抽象层的核心类,该类简化了JDBC的使用,
并避免了一些常见的错误,如忘记关闭数据库连接等。
常用方法:
1、public int update(String sql)
该方法用来执行一条独立的insert、delete或update语句,被执行的sql语句是一个完整的SQL语句,不包含形式参数
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="insert into customer values('marry','marry',24,'yunnan')";
template.update(sql);
2、public int update(String sql,Object[] args)
该方法用来执行一条insert、delete或update语句,该sql语句中可以包含参数,通过update方法中的参数args能够指定sql语句中的形式参数
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="insert into customer values(?,?,?,?)";
template.update(sql, new Object[]{"marry","marry",24,"yunnan"});
3、public int update(String sql,Object[] args,int[] argTypes)
该方法用来执行一条insert、delete或update语句,可以通过方法的args参数指定sql语句中的形式参数
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="insert into customer values(?,?,?,?)";
template.update(sql, new Object[]{"marry","marry",24,"yunnan"},new int[]{Types.VARCHAR,Types.VARCHAR,Types.INTEGER,Types.VARCHAR});
4、public List query(String sql,RowMapper rowMapper)
该方法用来执行一条select语句,并将返回的ResultSet封装成List对象返回。
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="select * from customer";
List<Customer> list=template.query(sql, new CustomerRowMapper());
for(Customer c:list){
System.out.println(c.getCustname()+" "+c.getPwd()+" "+c.getAge()+" "+c.getAddress());
}
上述代码中使用query方法执行查询sql语句,制订了参数new CustomerRowMapper()为结果集与实体对象的映射类。
public class CustomerRowMapper implements RowMapper {
public Object mapRow(ResultSet arg0,int arg1) throws SQLException{
return new Customer(arg0.getString(1),arg0.getString(2),arg0.getInt(3),arg0.getString(4));
}
}
5、public List query(String sql,Object[] args,RowMapper rowMapper)
该方法可以执行一条带参数的select语句,通过方法的args参数指定参数,通过rowMapper进行结果集和实体对象的映射
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="select * from customer where age>?";
List<Customer> list=template.query(sql, new Object[]{25},new CustomerRowMapper());
for(Customer c:list){
System.out.println(c.getCustname()+" "+c.getPwd()+" "+c.getAge()+" "+c.getAddress());
}
6、public Object queryForObject(String sql,Object[] args,int[] argTypes,RowMapperrowMapper)
该方法可以执行一条带参数的select语句,通过方法的args参数指定参数,通过argTypes指定参数类型,通过rowMapper进行结果集和实体对象的映射
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
String sql="select * from customer where age>? and pwd=?";
List<Customer> list=template.query(sql, new Object[]{25,"password"},new int[]{Types.INTEGER,Types.VARCHAR},new CustomerRowMapper());
for(Customer c:list){
System.out.println(c.getCustname()+" "+c.getPwd()+" "+c.getAge()+" "+c.getAddress());
}
7、public int[] batchUpdate(String[] sql)
该方法可以批量执行多条SQL更新语句
String sql1="insert into customer values('xiaogang','xiaogang',24,'shanghai')";
String sql2="delete from customer where age>30";
String sql3="update customer set pwd='dalian' where custname='tom'";
template.batchUpdate(new String[]{sql1,sql2,sql3});
8、public void execute(String sql)
该方法可以执行一条SQL语句,尤其是DDL语句(数据库定义语言)
String sql4="create table test(id int)";
template.execute(sql4);
获得JdbcTemplate实例
要使用JdbcTemplate类中的方法操作数据库,首先必须获得JdbcTemplate类的实例。
要获得一个可用的JdbcTemplate对象,必须为该对象指定对应的DataSource属性。
JdbcTemplate中有如下方法,用来注入DataSource属性:
public void setDataSource(DataSource dataSource):注入对应的DataSource对象。
在配置文件applicationContext.xml中:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" scope="prototype">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/mldn</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>password</value>
</property>
<property name="maxActive">
<value>10</value>
</property>
<property name="initialSize">
<value>2</value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
上述配置中,首先实例化并装配了一个DataSource实例dataSource,然后实例化了一个JdbcTemplate对象,并应用了已经装配好了的dataSource实例。
装配好的JdbcTemplate实例就可以在应用中使用:
ApplicationContext ctxt = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate template=(JdbcTemplate) ctxt.getBean("jdbcTemplate");
JdbcTemplate使用实例
创建新的类CustomerDAOJdbcTemplateImpl,实现CustomerDAO接口,该类中使用JdbcTemplate进行数据库操作。
package dao.Impl;
import java.sql.Types;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import test.CustomerRowMapper;
import vo.Customer;
import dao.CustomerDAO;
public class CustomerDAOJdbcTemplateImpl implements CustomerDAO {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public List<Customer> selectAll() {
String sql="select * from customer";
List<Customer> list=jdbcTemplate.query(sql, new CustomerRowMapper());
return list;
}
@Override
public Customer selectByName(String custname) {
String sql="select * from customer where custname=?";
List<Customer> list=jdbcTemplate.query(sql, new Object[]{custname},new int[]{Types.VARCHAR},new CustomerRowMapper());
if(list.size()>0){
return list.get(0);
}else{
return null;
}
}
@Override
public Customer selectByNamePwd(String custname, String pwd) {
String sql="select * from customer where custname=? and pwd=?";
List<Customer> list=jdbcTemplate.query(sql, new Object[]{custname,pwd},new int[]{Types.VARCHAR,Types.VARCHAR},new CustomerRowMapper());
if(list.size()>0){
return list.get(0);
}else{
return null;
}
}
@Override
public void insert(Customer cust) {
String sql = "insert into customer values(?,?,?,?)";
jdbcTemplate.update(sql, new Object[]{cust.getCustname(),cust.getPwd(),cust.getAge(),cust.getAddress()},new int[]{Types.VARCHAR,Types.VARCHAR,Types.INTEGER,Types.VARCHAR} );
}
}
配置applicationContext.xml
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="dao" class="dao.Impl.CustomerDAOJdbcTemplateImpl">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<bean id="service" class="service.CustomerServiceImpl">
<property name="dao">
<ref bean="dao"/>
</property>
</bean>
通过上述配置,service实例关联的dao实例不再是CustomerDAOImpl类的实例,而是CustomerDAOJdbcTemplateImpl的实例,
而CustomerDAOJdbcTemplateImpl实例关联了jdbcTemplate实例,使用JdbcTemplate实现数据层编程,从而简化了JDBC编程。