spring_day04

1.JdbcTemplate

a. JdbcTemplate是spring提供给我们的持久层操作工具类,tempalt是模板的意思。

b. maven依赖:spring-jdbc

c.依赖于DataSource,这里讲了个spring提供给我们的内置的DriverManagerDataSource(),但这个不是连接池,因为是new出来的,好的,通过spring容器创建就好

d. 使用JdbcTemplate进行CRUD操作:编不下去了,自己看吧,查询都用query方法,用BeanPropertyRowMapper<>()封装,返回的是list集合,

如果查询的是id,结果只能是有一个或者没有,就:

	return accounts == null? null:accounts.get(0);

如果查询的是name,因为结果可能有多个,就:

	 if (accounts == null){

			return null;

	}else if (accounts.size() > 1){

			throw new RuntimeException("查询结果不止一个");

	}

e. 问题,每个dao层的类都要获取一遍jdbcTemplate,代码重复,我们考虑抽取出来定义一个类,然后让dao层的类都继承这个类,具体执行sql时,用super.getJdbcTemplate()获取。

其实,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 DataSource getDataSource() {
            return this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null;
        }
    
        public final void setJdbcTemplate(@Nullable JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
            this.initTemplateConfig();
        }
    
        @Nullable
        public final JdbcTemplate getJdbcTemplate() {
            return this.jdbcTemplate;
        }

大概是这个样子的:因为源码中我们不能标注注解,所以只能通过xml方式,配置accountService,为其注入dataSource,因为其继承了JdbcDaoSupport类,有dataSource的set方法,注入dataSource时,会判断JdbcTemplate是否为null,若为null,则走这行代码:

	this.jdbcTemplate = this.createJdbcTemplate(dataSource);

调用createJdbcTemplate()方法,为jdbcTemplate初始化,我们在子类就可以直接通过super.getJdbctemplate(DataSource dataSource)方法获取到jdbcTemplate对象,综上,我们只需在xml配置文件中配置accountService,为其注入dataSource就ok了。

2.spring事务控制

引入:昨天的转账案例,我们是自定义一个事务管理类:TransactionManager,然后用创建了一个工厂类利用动态代理创建了代理对象,现在我们学了spring的aop之后,可以利用aop的方式取代工厂类,让spring帮我们实现动态代理。

回顾一下我们学的aop配置方式:

编写业务代码:service

编写增强代码:transactionManager

配置aop

	<aop:config
		<!--共性抽取配置切入点表达式-->
		<aop:pointcut id="pt" 	value="execution(* cn.itcast.spring.service.impl.*.*(..))"></aop:pointcut>		
		<!--配置切面-->
		<aop:aspect id="txManager" ref="transactionManager">
			<aop:before method="begin" pointcut-ref="pt"></aop:before>
		       <aop:after-returning method="commit" pointcut-ref="pt"></aop:after-returning>
			<aop:after-throwing method="rollback" pointcut-ref="pt"></aop:after-throwing>
			<aop:after method="close" pointcut-ref="pt"></aop:after>
		</aop:aspect>
	</aop:config>

现在我们学习spring的事务控制,就不需要自己定义事务管理类了。

spring的事务控制:

a. PlatformTransactionManager平台事务管理器,用来管理事务的核心api,接口类型,其常用实现类是DataSourceTransactionManager。

b. TransactionDefinition 事务的定义对象,定义了事务的相关属性
-String getName() 获取事务对象名称
-int getIsolationLevel 获取事务隔离级别
-int getPropagationBehavior 获取事务传播行为
-int getTimeOut 获取事务超时时间
-boolean isReadOnly 获取事务是否只读
c. TransactionStatus 事务的状态描述对象(了解,我们暂时涉及不到)

spring的声明式事务控制之xml配置方式

<!--这里的id或者name建议按照规范写,因为我们是有经验的开发人员-->
a. 声明事务管理类
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
    	<properties name="dataSource" ref="dataSource"></properties>
    	
    </bean>

b.配置事务通知
    <tx:advice id="txManager" transactionManager="transactionManager">

    	<tx:attribute>

    		<!--给每一需要绑顶事务的方法配置,我们使用*通配的方式,所以要求我们方法名要规范-->

    		<!--增删改操作配置,一定绑定事务,可进行读写-->

    		<tx:method name="*" propagation="REQUIRED" read-only="false">

    		<!--查询操作配置,不一定绑定事务,只能刻度-->

    		<tx:method name="find*" propagation="REQUIRED" read-only="false">

    	</tx:attribute>

    </tx:advice>

 xxxxxxxxxx 事务的属性配置:这段我拷贝过来,常用的就是propagation和read-only<tx:attributes>    <!-- 指定方法名称:是业务核心方法
   	read-only:是否是只读事务。默认 false,不只读。
 		isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。propagation:指定事务的传播行为。
 		timeout:指定超时时间。默认值为:-1。永不超时。
 		rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。没有默认值,任何异常都回滚。
 		no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回滚。没有默认值,任何异常都回滚。
	-->
 
 <tx:method name="*" read-only="false" propagation="REQUIRED"/>
 		<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
 </tx:attributes>
c. 配置切面

<aop:config>
	<!--配置切入点表达式-->
	<aop:pointcut id="pt" expression="excution(* cn.itcast.spring.service.impl.*.*(..)">
	<!--建立切入点表达式和事务通知的关系-->
	<aop:advisor advice-ref="txManager" pointcut-ref="pt">	
</aop:config>

spring的声明式事务控制之注解配置方式

a. 声明事务管理器
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    	<properties name="dataSource" ref="dataSource"></properties>

    </bean>

b.开启spring是事务控制的注解支持
	<tx:annotation-driver transaction-manager="transactionManager"/>

c.在要使用注解的类或方法上使用@Transaction注解
    	@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)

    	注意这里事务属性会对该类的所有方法生效,如果是增删改方法,需要在单独配置:

    	@Transactional(peopagation = Propagation.REQUIRED,readOnly = false)

spring的声明式事务控制之注解配置方式简单但不灵活,xml配置方式稍微复杂,但一劳永逸。

spring的全注解事务控制方式:

如何取代xml配置文件这个读取容器入口,前面我们学过定义一个配置类,传递给AnnotionConfigApplicationContext这个容器类,使用到的标签有@Configuration,@ComponentScan,@Import,@PropertySource,@Bean,@Value等

今天在学一个开启spring对事务注解方式的支持,@EnableTransactionManagement
使用在主配置类上即可。

spring暂时告一段落,主要学习了IoC,DI,AOP,事务控制,JdbcTemplate,有点啥都不会的感觉,也许以后写项目会一直用到,使用起来会好点,但是具体的原理要知道一点,比如:
IoC: 控制反转,原理:反射
DI: 依赖注入,为容器中对象的属性赋值
AOP: 面向切面编程,对已有功能进行无代码侵入增强
事务控制:依赖于AOP
JdbcTemplate:依赖于DataSource

配置文件多写应该会熟练吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值