ssm(2-3) Spring对JDBC 的支持与事务
1.JDBC 的支持
1.1 配置JdbcTemplate
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="driverClass" value="${driverClass}"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="datasource"></property> </bean>
1.2 使用JdbcTemplate查询数据库的方法
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;
batchUpdate方法用于执行批处理相关语句;
query方法及queryforobject方法:用于执行查询相关语句;
queryforobject:单行查询
String sql2="select * from users where id=1";
//需要注入的bean
RowMapper<Users> rm=new BeanPropertyRowMapper<>(Users.class);
Users users = jdbcTemplate.queryForObject(sql2, rm);
query:多行查询 返回list集合
String sql3="select * from users where id>?";
RowMapper<Users> rm1 = new BeanPropertyRowMapper<>(Users.class);
List<Users> query = jdbcTemplate.query(sql3, rm1,0);
call方法:用于执行存储过程、函数相关语句。
备注:注意jdbcTemplate尽量只执行查询操作,莫要进行更新,否则很容易破坏Hibernate的二级缓存体系,但在一般与hibernate等使用时一般不会用到spring的JdbcTemplate,经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示
1.3 NamedParameterJdbcTemplate
a) 具名参数(:name)只在 NamedParameterJdbcTemplate 中得到支持
b) 配置NamedParameterJdbcTemplate
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="driverClass" value="${driverClass}"></property> </bean> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"><constructor-arg ref="datasource"></constructor-arg> </bean>
c)使用
NamedParameterJdbcTemplate namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class); //使用别名:user,:password String sql="insert into users(user,pwd) values(:user,:password)"; Map<String ,Object> paramMap=new HashMap<>(); paramMap.put("user", "12qwe"); paramMap.put("pwd", "weq"); namedParameterJdbcTemplate.update(sql, paramMap);
2 配置型事务
2.1事务管理的原理
a)无论使用 Spring 的哪种事务管理策略(编程式或声明式), 事务管理器都是必须的,使用hibernate是管理事物的是session(session.transaction),spring策略是通过platformtransactionmanager接口实现,其中有三个方法gettransaction 获事务的方法,commit提交事务的方法,rollback回滚事物的方法,这个是没有与任何事务资源捆绑在一起,可以适应于任何的事务策略,spring没有任何的事物支持,只是包装了底层事务
b)Gettransaction方法根据transactiondefinition参数,返回一个transactionstatus对象表示一个事务,transactionstatus被关联在当前的线程上
c)Transactiondefinition接口定义一个事务规则,必须指定事务的隔离,事务的传播,事务的超时,只读状态
2.2事务管理的方式
a)编程式事务管理
通过上述的三个方法实现,较为麻烦
b)声明式事务管理
Aop实现:在目标方法执行之前,切入开始事务,在目标方法执行之后,切入结束事务
2.3 配置
<!-- 配置事务管理器 使用datasource.DataSourceTransactionManager 该类实现了platformtransactionmananger接口--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--配置platformtransactionmananger接口,针对采用数据库连接的特定实现 --> <property name="dataSource" ref="datasource"></property> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 根据方法名指定事务的属性 --> <tx:method name="purchase" propagation="REQUIRES_NEW"/> <!--所有以get开头的方法 read-only 只读模式--> <tx:method name="get*" read-only="true"/> <!--所有以find开头的方法 --> <tx:method name="find*" read-only="true"/> <!--所有方法 --> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- aop 配置在那些元素上 --> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* spring2.*.*(int, int))"/> <!--与aop绑定在一起,当切入点切入时,txAdvice 定义的处理也被切入,advisor 是从spring1.x中保留的,作用是将advice和切入点绑定在一起,然后一起切入 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
备注:
tx:method的属性如下
Name:必选属性 配置关联的方法名,支持通配符 例如get* handle* on*event等
Propagation:事务的传播(一个事务中使用另一个事务的传播行为),该属性为Propagation的枚举值,默认值为PROPAGATION_REQUIRED支持当前事务(在事务中,就不新建事务),如果当前没有事务,就新建一个事务,PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
Isolation:隔离级别isolation枚举的值,默认值是ISOLATION_DEFAULT,ISOLATION_READ_UNCOMMITTED读未提交,ISOLATION_READ_COMMITTED读已提交,ISOLATION_REPEATABLE_READ可重复读,ISOLATION_SERIALIZABLE序列化
Timeout:指定事务的超时时间
Read-only 是否只读
Rollback-for 事务回滚的异常类,需要使用全类名,多个用逗号隔开
No-rollback-for:指定不触发事务回滚的异常类,其余同上
说明:在默认的情况下,只有在运行时异常和unchecked异常时,spring事务才会回滚,如果抛出checked异常时,则事务不会回滚,假如需要回滚需要设置rollback-for属性,如果希望抛出指定的异常不回滚,那么需要设置no-rollback-for
3半配置半注解的事务
@transactional配置事务管理//在方法上指定@transactional,表示在这个方法上具有事务性
@transactional可指定的方法,同上,意义同上
在xml中配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean> <!-- 启动事务注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
4.基于注解的事务
将上述3的xml中的配置改为
@EnableTransactionManagement()//开启事务,相当于<tx:annotation-driven transaction-manager="transactionManager"/>当transaction-manager="transactionManager"可以默认不写 @Configuration @PropertySource(value = "classpath:student.properties",encoding = "gbk") public class IOCConfig { }
待续