(三) spring-Jdbc&spring-Transaction

一、spring-Jdbc

JdbcTemplate

JdbcTemplate主要提供以下五类方法:

execute方法:
可以用于执行任何SQL语句,一般用于执行DDL语句;

update方法及batchUpdate方法:
update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;

query方法及queryForXXX方法:
用于执行查询相关语句;

call方法:
用于执行存储过程、函数相关语句。

LobHandler和LobCreator

使用:
将LobHandler 加入到ioc容器当中

@Bean("lobHandler")
    public LobHandler createLobHandler(){
        return new DefaultLobHandler();
    }
jdbcTemplate.execute("insert into userinfo(id,image,description)values(?,?,?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
            @Override
            protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
                ps.setInt(1,3);
                //保存图片的二进制数组数据
                lobCreator.setBlobAsBytes(ps, 2,userinfo.getImages() );
                //保存描述的字符串数据
            	lobCreator.setClobAsString(ps,3,userinfo.getDescription());

            }
        });

NamedParameterJdbcTemplate

在原本JdbcTemplate的基础上把使用?当作占位符改为使用具名参数替代。

具名参数:
( SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名
参数由框架类在运行时用占位符取代)

在NamedParameterJdbcTemplate里面封装了一个JdbcTemplate对象,只不过把它看成了接口类型JdbcOperations。所以NamedParameterJdbcTemplate可以使
用全部jdbcTemplate方法。

使用:
将NamedParameterJdbcTemplate 加入到ioc容器当中

@Bean
public NamedParameterJdbcTemplate createNamedJdbcTemplate(JdbcTemplate
jdbcTemplate){
return new NamedParameterJdbcTemplate(jdbcTemplate);
}
@Test
public void testMethod(){
	Map<String,Object> map=new HashMap<>();
	map.put("id",1);
	map.put("username","szu");
	map.put("passwoed","niuBi");
	jdbcTemplate.execute("insert into sys_user values(:id,:username,:password) ",map);
}

把原来的占位符?改为冒号(:)加上字段名字。
由于赋值是按照字段名来找的,所以顺序是可以随意的。

使用BeanMap

@Test
public void testMethod(){
	BeanMap beanMap=BeanMap.create(user)
	jdbcTemplate.execute("insert into sys_user values(:id,:username,:password) ",beanMap);
}

二、spring-Transaction

1、spring事务当中重要接口

PlatformTransactionManager

作用:
此接口是Spring的事务管理器核心接口。Spring本身并不支持事务实现,只是负责提供标准,应用底层支持什么样的事务,需要提供具体实现类。此处也是策略模式的具体应用。在Spring框架中,也为我们内置了一些具体策略,例如:DataSourceTransactionManager,HibernateTransactionManager,
JpaTransactionManager,JtaTransactionManager等等。
(JpaTransactionManager和HibernateTransactionManager事务管理器在spring-orm包中)
源码:

public interface PlatformTransactionManager {
	//事务状态信息
    TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
	//提交
    void commit(TransactionStatus var1) throws TransactionException;
	//回滚
    void rollback(TransactionStatus var1) throws TransactionException;
}

TransactionDefinition

此接口是Spring中事务可控属性的顶层接口,里面定义了事务的一些属性以及获取属性的方法。例如:
事务的传播行为,事务的隔离级别,事务的只读,事务的超时等等。通常情况下,我们在开发中都可以配置这些属性,以求达到最佳效果。配置的方式支持xml和注解。
源码:

public interface TransactionDefinition {
	/*如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。
	一般的选择(默认值)
	*/
    int PROPAGATION_REQUIRED = 0;

	//支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
    int PROPAGATION_SUPPORTS = 1;
    
    //使用当前的事务,如果当前没有事务,就抛出异常
    int PROPAGATION_MANDATORY = 2;
    
    //新建事务,如果当前在事务中,把当前事务挂起。
    int PROPAGATION_REQUIRES_NEW = 3;
    
    //以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
    int PROPAGATION_NOT_SUPPORTED = 4;
    
    //以非事务方式运行,如果当前存在事务,抛出异常
    int PROPAGATION_NEVER = 5;
    
    //如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作
    int PROPAGATION_NESTED = 6;

	//事务的隔离级别默认值,当取值-1时,会采用下面的4个值其中一个。
    int ISOLATION_DEFAULT = -1;
    
    /**
	* 事务隔离级别为:读未提交
	* 执行效率最高,但什么错误情况也无法避免
	*/
    int ISOLATION_READ_UNCOMMITTED = 1;

	/**
	* 事务隔离级别为:读已提交
	* 可以防止脏读的发生,但是无法防住不可重复读和幻读的发生
	*/
    int ISOLATION_READ_COMMITTED = 2;

	/**
	* 事务隔离级别为:可重复读
	* 可以防止脏读和不可重复读的发生,但是无法防住幻读的发生
	*/
    int ISOLATION_REPEATABLE_READ = 4;
    
	/**
	* 事务隔离级别为:串行化
	* 此时所有错误情况均可防住,但是由于事务变成了独占模式(排他模式),因此效率最低
	*/
    int ISOLATION_SERIALIZABLE = 8;


	//超时限制。默认值是-1,没有超时限制。如果有,以秒为单位进行设置。
    int TIMEOUT_DEFAULT = -1;

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();

    boolean isReadOnly();

    @Nullable
    String getName();
}

TransactionStatus

此接口是事务运行状态表示的顶层接口,里面定义着获取事务运行状态的一些方法。

public interface TransactionStatus extends SavepointManager, Flushable {
boolean isNewTransaction();//是否一个新的事务
boolean hasSavepoint();//是否包含存储点
void setRollbackOnly();//设置事务回滚
boolean isRollbackOnly();//是否是只回滚事务
@Override
void flush();//刷新事务
boolean isCompleted();//事务是否已经完成(标识就是提交或者回滚了)
}

2、声明事务控制

@EnableTransactionManagement

作用:
此注解是Spring支持注解事务配置的标志。表明Spring开启注解事务配置的支持。是注解驱动开发事务配置的必备注解。

源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* true:基于目标类代理。(第三方cglib)
* false:基于接口代理。(jdk官方Proxy)
*/
boolean proxyTargetClass() default false;

/**
* 指定事务通知是如何执行的。
* AdviceMode.PROXY:类运行期代理
* AdviceMode.ASPECTJ:类加载时代理
*/
AdviceMode mode() default AdviceMode.PROXY;

/**
* 指示在切面类中有多个通知时事务处理的执行顺序。
* 效果同@Order
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}

@Transactional

此注解是Spring注解配置事务的核心注解,无论是注解驱动开发还是注解和XML混合开发,只有涉及配置事务采用注解的方式,都需要使用此注解。
通过源码我们看到,该注解可以出现在接口上,类上和方法上。

分别表明:
接口上:当前接口的所有实现类中重写接口的方法有事务支持。

类上:当前类中所有方法有事务支持。

方法上:当前方法有事务的支持。

优先级:
方法上>类上>接口上。

源码:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
	/**
	*指定事务管理器的唯一标识,也就是指定id
	*/
    @AliasFor("transactionManager")
    String value() default "";
	//同value
    @AliasFor("value")
    String transactionManager() default "";
	
	// 指定事务的传播行为
    Propagation propagation() default Propagation.REQUIRED;

	//事务的隔离级别
    Isolation isolation() default Isolation.DEFAULT;

	//事务的超时时间
    int timeout() default -1;
	
	//事务是否只读
    boolean readOnly() default false;

	// 通过指定异常类的字节码,限定事务在特定情况下回滚
    Class<? extends Throwable>[] rollbackFor() default {};

	//通过指定异常类的全限定类名,限定事务在特定情况下回滚
    String[] rollbackForClassName() default {};
	
	// 通过指定异常类的字节码,限定事务在特定情况下不回滚
    Class<? extends Throwable>[] noRollbackFor() default {};

	// 通过指定异常类的全限定类名,限定事务在特定情况下不回滚
    String[] noRollbackForClassName() default {};
}

注解驱动事务控制

1.配置TransactionManagement实现类

public class TransactionConfig(){
	@Bean
	public PlatformTransactionManager createTransactionManagement(DataSource dataSource){
		return new DataSourceTransactionManager();
	}
}

2.开启事务控制并导入配置类

@Configuration
@Import(TransactionConfig.class)
@EnableTransactionManagement//开启事务控制
public class SpringConfiguration {
}

3.业务层接口添加@Transactional注解
注意:事务控制一般声明在业务层,一方面是业务层接口一般会出现多次请求调用持久层中的方法,更容易发生错误,而持久层当中方法一般只会请求一次数据库。
另一方面是一般当我们使用持久层框架开发(如mybatis)的时候,持久层的方法实现都是通过动态代理实现的,无法通过编码添加事务。

@Service("userService")
//@Transactional  注解添加在类上时,表明这个类上所有的方法都添加事务控制
public class UserServiceImpl implements UserService {

	@Transactional
	public void save(User user){}

}

3.配置TransactionManagement实现类

public class TransactionConfig(){
	public PlatformTransactionManager createTransactionManagement(DataSource dataSource){
		return new DataSourceTransactionManager();
	}
}

3、编程式事务控制-TransactionTemplate

1.将TransactionTemplate 加入ioc容器

public class TransactionConfig(){
	@Bean
	public PlatformTransactionManager createTransactionManagement(DataSource dataSource){
		return new DataSourceTransactionManager();
	}
	@Bean
	public TransactionTemplate createTransactionTemplate(PlatformTransactionManager pTM){
		return TransactionTemplate(pTM) ;
	}
}
@Service("userService")
//@Transactional  注解添加在类上时,表明这个类上所有的方法都添加事务控制
public class UserServiceImpl implements UserService {
	@AutoWired
	privated TransactionTemplate transactionTemplate;
	
	public void save(User user){
	transactionTemplate.execute(new TransactionCallBack<Object>(){

	@override
	public Object doTransaction(TransactionStatus status){
			//TODO---
			
			return null;
		}
	
	})
	}

}

@TransactionEventListener

用于配置一个事务的事件监听器。使我们在事务提交和回滚前
后可以做一些额外的功能。例如:对事务执行监控,执行中同步做一些操作等等。

源码:

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
	/**
	* 指定事务监听器的执行是在何时。
	* 取值有:
	* 事务提交之前
	* 事务提交之后 默认值
	* 事务回滚之后
	* 事务执行完成之后
	*/
    TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;

	// 若没有事务的时候,对应的event是否已经执行 默认值为false表示 没事务就不执行了
    boolean fallbackExecution() default false;

 	//指定事件类的字节码
    @AliasFor(
        annotation = EventListener.class,
        attribute = "classes"
    )
    Class<?>[] value() default {};

    @AliasFor(
        annotation = EventListener.class,
        attribute = "classes"
    )
    Class<?>[] classes() default {};
	// 用于指定执行事件处理器的条件。取值是基于Spring的el表达式编写的。
    String condition() default "";
}

使用:

1.定义事件类,继承ApplicationEvent类并实现一个MyApplicationEvent(Object source )构造方法。

public class MyApplicationEvent extends ApplicationEvent {
//TODO---
public MyApplicationEvent(Object source ) {
super(source);
//TODO---
}
}

2.定义监听器类

@Component//将该类加入ioc容器
public class MyTransactionEventListener {
//事务提交之后执行下面方法
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void doSomething(MyApplicationEvent event){
	}
}

3.定义事件发布类,确定事件发布的具体位置及操作

@Service("userService")
@Transactional
public class UserServiceImpl implements userService {
@Autowired//事件发布类,也就是事件源,该类在解析注解时已加入到ioc容器当中
private ApplicationEventPublisher applicationEventPublisher;

public void save(){
try{
	try{
		//TODO
		applicationEventPublisher.publishEvent(obj);
		//TODO
	
	}finally{
		//TODO
		//applicationEventPublisher.publishEvent(obj);
		//TODO
	}
}catch(Exception e){
		//TODO
		//applicationEventPublisher.publishEvent(obj);
		//TODO
	}
}

}

TransactionSynchronizationManager*

事务的同步管理器类,实现连接和线程绑定从而控制事务的核心类
它是个抽象类,但是没有任何子类 因为它所有的方法都是静态的

DataSourceUtils*

spring中数据源的工具类。
里面定义着获取连接的方法

实现连接与线程绑定:

@Bean("connection")
public Connection getConnection(DataSource dataSource){
	TransactionSynchronizationManager.initSynchronization() ;
	Connect connect=DataSourceUtils.getConnect(dataSource);
	return connect;
}

要求理解源码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值