我们需要通过spring来操作jdbc的时候,由于jdbc框架属于模板编程:固定的写法,传入datasource,获取连接,得到statement,然后执行。但是它们所执行的sql语句是不一样的,对于这种情况,称之为模板编程。
我们先来看一下jdbcDaoSupport:
这里的方法只是这个类的一部分,首先我们可以看到,jdbcDaoSupport是一个抽象类,并且把jdbcTemplate当作引用,但是给datasource赋值的时候,却调用了new JdbcTemplate(dataSource)来赋值。那我们就来看一下jdbcTemplate:
从图中我们可以看到,这里面封装了很多jdbc框架的操作,并且它的构造函数还可以把datasource传进来。
我们看一下构造函数:
*注:这里只是一部分方法
然后我们查找setDataSource(dataSource);
的源代码,点进去
我们看到,它引用的是父类:JdbcAccessor的setDataSource方法。
那么由上面的部分源代码我们可以看出,
spring与jdbc结合的方式有:
1、创建一个Dao并继承jdbcDaoSupport。
2、创建一个Dao并继承jdbcTemplate
3、创建一个Dao并把jdbcTemplate作为一个属性
注意:
创建一个Dao并把jdbcDaoSupport作为一个属性为什么不可以?
因为jdbcDaoSupport是一个抽象类,要想把它作为类的一个属性,首先要配置到spring容器中,然后spring容器会为这个类创建对象然后再赋值,可是这个类是抽象类,所以不可以使用这种方法
首先搭建开发环境:
创建一个Dao并继承jdbcDaoSupport。
下面是代码实现:
/**
* 创建一个Dao,并继承JdbcDaoSupport(抽象类)
*
*/
public class PersonDao extends JdbcDaoSupport {
public void update(){
//执行特定的sql语句
this.getJdbcTemplate().execute("update person set pname='a' where pid=1");
}
}
/**
* 测试类
*/
public class personTest {
@Test
public void testPerson(){
//开启spring容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("cn/ansel/spring_jdbc/applicationContext.xml");
//得到相应的类
PersonDao3 dao=(PersonDao3) applicationContext.getBean("personDao3");
//执行sql语句
dao.update();
}
}
再来看一下配置文件,因为我们要用到jdbc,所以肯定要与数据库连接。
首先,我们把数据库的uri还有我们使用的驱动以及连接数据库的帐号密码放在一个jdbc.properties中。这个文件放在classpath下
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://localhost\:3306/hibernate1
jdbc.username=root
jdbc.password=root
然后就是spring的配置(在这里把三种方式都配置上来,后面就不用配置了):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:读取配置文件的类
locations value:指示配置文件的位置
这里的代码都是固定写法,只有locations的value,位置可能会不同,只要做相应的修改即可。
-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!--
配置dataSource到spring容器中
这里的property都是用来读取jdbc.properties的key值,
在value中也可以直接把值写上去,也可以用下面的写法获取key值。
-->
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!--
方式一的配置:
因为在personDao中,我们继承的是JdbcDaoSupport,这个类是一个抽象类,但是
这个类有dataSource的引用,并且有对应的setter方法,所以可以通过property
方式赋值
-->
<bean id="personDao" class="cn.ansel.spring_jdbc.PersonDao">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--方式一终结线 //-->
<!-- 方式二的配置:
因为在personDao继承的是JdbcTemplate,这个类调用父类来给datasource复制
所以在创建这个类的对象的时候,以构造函数的形式对dataSource赋值
所以这里使用的是constructor-arg
-->
<bean id="personDao2" class="cn.ansel.spring_jdbc.PersonDao2">
<constructor-arg index="0" ref="dataSource" ></constructor-arg>
</bean>
<!--方式二终结线 //-->
<!--
方式三的配置:
因为这里是让jdbcTemplate作为一个属性,要想让Dao能操作jdbc,那么就要先把jdbcTemplate
放入到spring容器中,然后把dataSource也一起放入,配置完了属性,就配置Dao
把属性利用property形式放到dao中
-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
<bean id="personDao3" class="cn.ansel.spring_jdbc.PersonDao3">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<!--方式三终结线 //-->
</beans>
数据库中原来的值:
运行测试类:
控制台并没有输出数据。我们看一下数据库:
创建一个Dao并继承JdbcTemplate
/**
* 创建一个Dao并继承JdbcTemplate
* @author andy
*
*/
public class PersonDao2 extends JdbcTemplate {
/**
* 在构造函数中把dataSource传入,然后调用其父类方法赋值
* @param dataSource
*/
public PersonDao2(DataSource dataSource) {
super(dataSource);
}
public void update(){
//执行相关的sql语句
this.execute("update person set pname='aa' where pid=2");
}
}
测试类只需要把getBean的personDao改成personDao2, 然后调用新对象的update方法即可。。
然后运行测试类:
控制台还是没有输出任何数据,我们直接看数据库变化
3、创建一个Dao并把jdbcTemplate作为一个属性
/**
* 3、创建一个Dao并把jdbcTemplate作为一个属性
*
*/
public class PersonDao3 {
//把jdbcTemplate作为一个属性
private JdbcTemplate jdbcTemplate;
//相应的getter&setter方法
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//相应的sql语句
public void update(){
this.jdbcTemplate.execute("update person set pname='aaa' where pid=3");
}
}
测试类只需要把applicationContext.getBean("personDao2")
改成applicationContext.getBean("personDao3")
然后调用新对象的update方法即可。
运行测试类后数据库的变化:
小结:
编写dao的方式有很多种,但是最终的目的还是把dataSource注入到jdbcTemplate中。