1.Template
Template是Spring为我们提供的操作关系型数据库的一个对象。
(1)JdbcTemplate对象的创建:(源码)
public JdbcTemplate() {
}
public JdbcTemplate(DataSource dataSource) {
setDataSource(dataSource);
afterPropertiesSet();
}
public JdbcTemplate(DataSource dataSource, boolean lazyInit) {
setDataSource(dataSource);
setLazyInit(lazyInit);
afterPropertiesSet();
}
我们可以通过源码看出,JDBCtemplate对象的创建需要提供一个datasource数据源,都有setDatadource方法,因此可以在配置文件中配置datasource。
所以想要使用JdbcTemplate就需要给它set一个数据源,再创建一个JdbcTemplate对象即可使用
(2)JdbcDaoSupport
Spring里面有一个
JdbcDaoSupport,它的作用就是为我们
抽取了一部分持久层Dao中的重复代码。
具体分析:
实际应用情况是:如果你有好多个持久层,好多个Dao,每一个Dao,你都需要一个JdbcTemplate,帮你操作数据库。还会有一个SetTemplate函数,以便于后面spring容器帮我们注入JdbcTemplate。
基于以上分析,每一个Dao中都会有JdbcTemplate和SetTemplate,这样就造成了代码的重复问题。
所以spring就为我们提供了JdbcDaoSupport,它的作用是提供一个JdbcTemplate,SetTemplate。
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public JdbcTemplate getJdbcTemplate() {
//持久层dao中直接get取到template
return jdbcTemplate;
}
public void setDataSource(DataSource dataSource) {
//一旦设置好Datasource就会自动执行此段代码,为我们创造好template,后面在持久层中直接取用就可。
if(jdbcTemplate == null){
jdbcTemplate = createJdbcTemplate(dataSource);
}
}
private JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);//你注入datasource和注入template最后都会给你返回一个template(所以配置文件中不配置template也是可以的)
}
}
2.Spring的事务控制
(1)spring中基于XML的声明式事务控制步骤
①配置事务管理器
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
②配置事务通知(什么时候执行什么操作)【注意:要导入事务约束,导入tx名称空间和约束,同时也需要aop的】(里面有提交和回滚方法)
-
此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的
-
使用 tx:advice标签配置事务通知
-
属性:
-
id:给事务通知起一个唯一标识
-
transaction-manager:给事务通知提供一个事务管理器引用
<!-- 配置事务的通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
③配置AOP的通用切入点表达式
<!-- 配置aop-->
<aop:config>
<!-- 配置切入点表达式-->
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
</aop:config>
④建立事务通知和切入点表达式的对应关系
<!-- 配置aop-->
<aop:config>
<!-- 配置切入点表达式-->
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
<!--建立切入点表达式和事务通知的对应关系 -->//把通知放到切入点里来
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
//批注:事务通知和AOP的关系是:事务通知相当于就是我们控制事务的那些增强方法:事务开启、提交、回滚、释放(动态代理),而AOP这个切入点是正常service执行的方法。//我们配置切入点表达式和事务通知的对应关系,相当于就是完成整个动态代理的过程,只不过是spring帮我们完成,我们只需要配置好,在哪里(AOP)切入增强方法(通知)
⑤配置事务属性
配置位置:tx:advice标签内部
<!-- 配置事务的通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 配置事务的属性
isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。(查询方法不需要配置事务)
read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
-->
<tx:attributes>//name就是我们业务层中的一些方法,表示它要有一些属性。
<tx:method name="*" propagation="REQUIRED" read-only="false"/>//全通配。所有方法的匹配
<tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>//所有遵循find命名方法的都满足该配置
</tx:attributes>
</tx:advice>
(2)spring中基于注解的声明式事务控制步骤
①配置事务管理器
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
②开启spring对注解事务的支持
<!-- 开启spring对注解事务的支持-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
③在需要事务支持的地方开启@Transactional注解
注意:这里使用注解有个麻烦事,比如在一个类里面有十个方法,五个只需要读,五个需要读写,那么10个方法前面都需要分别加属性,这时候使用注解就会麻烦。
@ComponentScan("com.itheima")指定要扫描的类