在前面我们学习了JDBC Template,尽管此时可以直接利用JDBCTemplate进行数据库的操作,但是在大部分的DAO的实现子类中,却很少有人会这样做,大家往往会让DAO的实现子类既实现了DAO同时又继承一个JdbcDaoSupport的抽象类。为什么会这样呢?先来看之前学习的JDBC Template。
我们为获得JDBCTemplate对象,需要在xml文件中进行配置:
1 2 3 4 <!--配置JDBC工具类--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>
然后在使用的地方使用下面的代码进行注入:
1 2 @Autowired private JdbcTemplate jdbcTemplate;
这其实就是让Spring容器来管理JdbcTemplate,如果你继承了JdbcDaoSupport,那么这些过程都可以不需要了。
JdbcDaoSupport JdbcDaoSupport
是Spring内置的一个Dao层的基类,来自spring-jdbc-4.2.4.RELEASE.jar
这个包。其内部定义了JdbcTemplate的set方法,也就是说dao类只需继承JdbcDaoSupport类,就可以省略JdbcTemplate的set方法的书写,通过查看源码你会发现,该方法是final修饰的:
1 2 3 4 5 6 7 8 /** * Set the JdbcTemplate for this DAO explicitly, * as an alternative to specifying a DataSource. */ public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; initTemplateConfig(); }
被final修饰的方法意味着该方法无法被子类重写,同时它还提供了注入数据库连接池的set方法:
1 2 3 4 5 6 7 8 9 /** * Set the JDBC DataSource to be used by this DAO. */ public final void setDataSource(DataSource dataSource) { if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) { this.jdbcTemplate = createJdbcTemplate(dataSource); initTemplateConfig(); } }
从该方法中可以知道,如果Spring配置文件中没有配置jdbcTemplate ,那么它是可以通过注入dataSource的时候自动创建jdbcTemplate,因此它可以省略JdbcTemplate类的注册工作。
说白了就是JdbcDaoSupport
可以简化dao类有关JdbcTemplate
注入的相关工作,如果需要使用JdbcTemplate
,只需要调用JdbcDaoSupport
的getJdbcTemplate
方法即可获取,再也不需要在Spring文件中进行配置了。
银行转账案例 我们以银行转账为例进行介绍,这个案例很经典,后续会以这个例子介绍Spring事务管理相关的知识。
第一步,新建数据库spring_money和表account:
1 2 3 4 5 6 7 8 9 10 11 12 drop database if exists spring_money; create database spring_money; use spring_money; create table account ( id bigint auto_increment primary key, name varchar(32) not null, money bigint not null, constraint account_name_uindex unique (name) ); insert into account (name, money) values('小明', 2000),('小白', 2000);
第二步,新建Maven项目spring_money: 其中pom.xml配置信息为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.envy</groupId> <artifactId>Spring_money</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring.version>4.2.7.RELEASE</spring.version> </properties> <dependencies> <!--Spring核心组件--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${spring.version}</version> </dependency> <!--Spring AOP组件--> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <!--AspectJ AOP开发需要引入的两个包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!--MySql驱动,注意版本号--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!--JDBC Template--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <!-- druid数据源--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.25</version> </dependency> <!-- 测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project>
第三步,创建一个实体包com.envy.entity,接着在里面新建Account实体类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.envy.entity; public class Account { private int id; private String name; private Long money; public int getId(){ return id; } public void setId(int id){ this.id=id; } public String getName(){ return name; } public void setName(String name){ this.name=name; } public Long getMoney(){ return money; } public void setMoney(Long money){ this.money = money; } public String toString(){ return "Account:id is"+id+";name is"+ name+ ";money is"+money; } }
第四步,创建一个Dao包com.envy.dao,接着在里面新建AccountDao接口:
1 2 3 4 5 6 7 8 package com.envy.dao; import com.envy.entity.Account; public interface AccountDao { void save(Account account); }
然后在com.envy.dao
中新建一个Impl包,在Impl中新建AccountDao接口的实现类AccountDaoImpl
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.envy.dao.Impl; import com.envy.dao.AccountDao; import com.envy.entity.Account; import org.springframework.jdbc.core.support.JdbcDaoSupport; //dao层,继承JdbcDaoSupport public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { public void save(Account account) { String sql = "insert into account(name,money)values(?,?)"; getJdbcTemplate().update(sql,"小红",1000L); // 从父类JdbcDaoSupport中获取jdbcTemplate } }
第六步,创建一个db.properties配置文件:
1 2 3 4 5 6 7 8 #加载驱动 druid.driverClassName=com.mysql.jdbc.Driver #加载数据库 druid.url=jdbc:mysql://localhost:3306/spring_money?useUnicode=true&characterEncoding=UTF-8 #用户名 druid.username=root #密码 druid.password=root
第七步,创建一个applicationContext.xml配置文件: (XML配置方式管理Bean,注释掉的内容表示多余,但是便于理解这里依旧贴出代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!--读取外部db.properties配置信息--> <context:property-placeholder location="classpath:db.properties"/> <!--开启包扫描--> <context:component-scan base-package="com.envy.service.Impl"/> <!--配置数据源--> <bean id = "dataSource" class = "com.alibaba.druid.pool.DruidDataSource" destroy-method = "close"> <!--数据库基本信息配置--> <property name="url" value="${druid.url}"/> <property name="username" value="${druid.username}"/> <property name="password" value="${druid.password}"/> <property name="driverClassName" value="${druid.driverClassName}"/> </bean> <!--注册AccountDaoImpl--> <bean id="accountDao" class="com.envy.dao.Impl.AccountDaoImpl"> <!--注入属性:dataSource属性来自jdbcDaoSupport类,只需要继承即可拥有--> <property name="dataSource" ref="dataSource"/> <!--dataSource属性对应的setDataSource方法内部会自动创建jdbcTemplate因此,这里无需再注入jdbcTemplate属性--> <!--<property name="jdbcTemplate" ref="jdbcTemplate"/>--> </bean> <!-- 继承JdbcDaoSupport后,不需要注册JdbcTemplate类--> <!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">--> <!--<property name="dataSource" ref="dataSource"/>--> <!--</bean>-->
第八步,开始测试,新建JdbcDaoSupportAccountTest.java
测试文件 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import com.envy.dao.AccountDao; import com.envy.entity.Account; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class JdbcDaoSupportAccountTest { @Autowired private AccountDao accountDao; @Test public void testOne(){ Account account = new Account(); account.setName("小红"); account.setMoney(888L); accountDao.save(account); } }
运行测试代码发现没有问题,因此建议大家在Spring中使用JdbcDaoSupport。