ssm--spring4

1.JdbcTemplate与QueryRunner
1.1 JdbcTemplate常用API
	JdbcTemplate template = new JdbcTemplate(dataSource);
	int template.update(sql,args...);
	T template.queryForObject(sql,new BeanPropertyRowMapper<T>(T.class),args...);
	List<T> template.query(sql,new BeanPropertyRowMapp<T>(T.class),args...);
        
1.2 手动实现RowMapper<T> 接口
本质:BeanPropertyRowMapper implements RowMapper<T>  
public class RowMapperImpl implements RowMapper<User>{
    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
        User user = new User();
        user.setInt(resultSet.getInt("id"));
        user.setString(resultSet.getString("name"));
        return user;
        //无论使用query()或者queryForObject(),底层都是这样的代码
    }
}
当第一次调用mapRow()方法时,游标已经直接指向了第一行,如果在mapRow()中使用while(resultSet.next){ ... }
方法来封装数据,则封装的数据是从第二行开始算起,那么就会漏掉第一行数据。
        
1.3 QueryRunner常用API
     	QueryRunner runner = new QueryRunner(dataSource);
        int runner.update(sql,args...);
        T runner.query(sql,new BeanHandler<T>(T.class),args...);
        List<T> runner.query(sql,new BeanListHandler<T>(T.class),args...);
        
1.4JdbcTemplate对象的配置方式
1.4.1在Dao层直接new
        JdbcTemplate template = new JdbcTemplate(dataSource);
1.4.2在Dao层定义为成员变量,使用IOC和DI完成注入
        private JdbcTemplate Template;
        public void setTemplate(JdbcTemplate Template){ ... }
1.4.3让Dao继承JdbcDaoSupport,利用继承关系完成IOC和DI
        public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao { ... }
	在方法中需要使用JdbcTemplate对象时,调用父类方法super.getJdbcTemplate(),super可以换成this,表示调用当前对象的getJdbcTemplate()方法,没有就向上找,而this可以省略,所以:getJdbcTemplate().query(sql)。
bean.xml中的配置:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property> 
    //AccountDaoImpl不需要提供JdbcTemplate成员变量和set方法,JdbcDaoSupport父类来提供
</bean>
1.4.4使用注解和使用xml配置JdbcTemplate对象的区别?
第一种在 Dao 类中定义 JdbcTemplate 的方式,适用于所有配置方式(xml 和注解都可以)。
第二种让 Dao继承JdbcDaoSupport 的方式,只能用于基于XML的方式,注解用不了(无法在父类加@Repository注解)。
2.spring事务传播特性propagation
	事务的传播特性指两个被事务管理的方法互相调用问题,并且只能在业务层使用,让一组操作被同一个事务管理起来,它与数据库无关,是程序内部维护的问题。事务传播的方法,通常在业务层调用持久层使用

1.常见接口
1.1PlatformTransactionManager  事务管理平台,事务管理器
1.2TransactionDefinition 事务定义对象

当操作dao使用的jdbc、JdbcTemplate、Mybatis(iBatis)时,配置事务管理器: DataSourceTransactionManger
当操作dao使用的Hibernate时,配置事务管理器: HibernateTransactionManager 

2.事务的传播行为propagation的取值
REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。(默认值)增删改 
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务),即有没有事务均可  查找
REQUIRES_NEW:新建事务,如果当前在事务中,把当前事务挂起。
NESTED:嵌套,如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作。 

a方法和b方法都在事务的管理当中,a方法调用b方法
	第一种:a设置为propagation="REQUIRED",b设置为propagation="REQUIRED",a和b在同一个事务里面,a和b要么同时成功,要么同时失败;
	第二种:a设置为propagation="REQUIRED",b设置为propagation="REQUIRES_NEW",a和b不在同一个事务里面,a和b互不影响;
	第三种:a设置为propagation="REQUIRED",b设置为propagation="NESTED",a所在事务嵌套了b事务,a可以影响b,但b不能影响a

3.read-only 只读
true : 只允许DQL
false : 
3.基于XML的事务传播
<!--第一步:配置事务管理器-->
<bean id="transactionManager" 	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--使用set方法注入dataSource属性-->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置DataSource对象,将它交给spring容器来管理-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> ... </bean>

<!--第二步:配置事务管理器的传播行为-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--配置事务通知的传播方法,建立事务传播至少需要两个方法-->
    <tx:attributes>
        <tx:method name="addAccount" propagation="REQUIRED" read-only="false"></tx:method>
        <tx:method name="updateAccount" propagation="REQUIRED" read-only="false"></tx:method>
     </tx:attributes>
</tx:advice>

<!--第三步:配置AOP,建立切入点表达式和事务通知的对应关系-->
<aop:config>
    <!--配置切入点表达式-->
    <aop:pointcut id="pc" expression="execution(* com.baidu.service.impl.*.*(..))">		       </aop:pointcut>
    <!--建立切入点表达式和事务通知的对应关系-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
</aop:config>
4.基于注解的事务传播行为
<!--告知spring容器需要扫描注解配置的包-->
<context:component-scan base-package="com.baidu"></context:component-scan>
<!--开启spring容器对注解事务传播行为的支持-->
<tx:annotation-driver transaction-manager="transactionManager"></tx:annotation-driver>
<!--在需要使用声明式事务的类或者方法上加注解-->
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)
如果设置了readOnly=true,就不能执行DML

如果使用纯注解实现声明式事务,在注解配置类上加@EnableTransactionManagement替代
<tx:annotation-driven transaction-mamager="transactionManager"></tx:annotation-driven>

猜你喜欢

转载自blog.csdn.net/qq_42514129/article/details/84745310