spring学习笔记(三)
spring jdbc
spring tx
1、spring的jdbc模板
Spring提供了很多持久层技术的模板类简化编程:
1.1、jdbc模板的基本使用
@Test // JDBC模板的基本使用: public void demo1(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring_day03"); dataSource.setUsername("root"); dataSource.setPassword("123"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into account values (null,?,?)", "会希",10000d); }
2、spring整合连接池
【配置内置连接池】
<!-- 配置Spring的内置连接池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring_day02"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean>
【将模板配置到Spring中】
<!-- 配置JDBC模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>
【编写测试类】
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test public void demo1(){ jdbcTemplate.update("insert into account values (null,?,?)", "凤姐",10000d); } }
2.1、 Spring中配置DBCP连接池:
【引入dbcp连接池的jar包】
【配置连接池】
<!-- 配置DBCP连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring_day02"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean>
2.2、配置c3p0连接池:
【引入相应的jar包】
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
【配置连接池】
<!-- 配置C3P0连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql:///spring_day02"/> <property name="user" value="root"/> <property name="password" value="123"/> </bean>
3、JDBC模板的CRUD的操作
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo3 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test // 插入操作 public void demo1(){ jdbcTemplate.update("insert into account values (null,?,?)", "冠希",10000d); } @Test // 修改操作 public void demo2(){ jdbcTemplate.update("update account set name=?,money =? where id = ?", "思雨",10000d,5); } @Test // 删除操作 public void demo3(){ jdbcTemplate.update("delete from account where id = ?", 5); } @Test // 查询一条记录 public void demo4(){ Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 1); System.out.println(account); } @Test // 查询所有记录 public void demo5(){ List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper()); for (Account account : list) { System.out.println(account); } } class MyRowMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } } }
4、事务
事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.
4.1、 事务特性:
原子性 :强调事务的不可分割.
一致性 :事务的执行的前后数据的完整性保持一致.
隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
持久性 :事务一旦结束,数据就持久到数据库
4.2、如果不考虑隔离性引发安全性问题:
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的update的数据导致多次查询结果不一致.
虚读 :一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致.
4.3、 解决读问题:设置事务隔离级别
未提交读 :脏读,不可重复读,虚读都有可能发生
已提交读 :避免脏读。但是不可重复读和虚读有可能发生
可重复读 :避免脏读和不可重复读.但是虚读有可能发生.
串行化的 :避免以上所有读问题.
5、Spring进行事务管理API
5.1、 PlatformTransactionManager:平台事务管理器.
***** 真正管理事务的对象
org.springframework.jdbc.datasource.DataSourceTransactionManager 使用Spring JDBC或iBatis 进行持久化数据时使用
org.springframework.orm.hibernate3.HibernateTransactionManager 使用Hibernate版本进行持久化数据时使用
5.2、TransactionDefinition:事务定义信息
事务定义信息:
* 隔离级别
* 传播行为
* 超时信息
* 是否只读
5.2.1、TransactionStatus:事务的状态
记录事务的状态
Spring的这组接口是如何进行事务管理:
平台事务管理根据事务定义的信息进行事务的管理,事务管理的过程中产生一些状态,将这些状态记录到TransactionStatus里面
5.2.3、事务的传播行为
PROPAGION_XXX :事务的传播行为
* 保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
* 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
5.3、Spring的编程式事务(了解)
5.3.1、配置事务管理器
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
5.3.2、配置事务管理器的模板
<!-- 配置事务管理模板 --> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean>
5.3.3、需要在业务层注入事务管理模板
<!-- 配置业务层的类 --> <bean id="accountService" class="cn.xxxxx.transaction.demo1.AccountServiceImpl"> <property name="accountDao" ref="accountDao"/> <!-- 注入事务管理模板 --> <property name="transactionTemplate" ref="transactionTemplate"/> </bean>
5.3.4、手动编写代码实现事务管理
public void transfer(final String from, final String to, final Double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { accountDao.outMoney(from, money); int d = 1 / 0; accountDao.inMoney(to, money); } }); }
5.4、Spring的声明式事务管理XML方式(*****):
思想就是AOP.
不需要进行手动编写代码,通过一段配置完成事务管理
aop联盟.jar
Spring-aop.jar
aspectJ.jar
spring-aspects.jar
5.4.1、配置事务管理器
<!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
5.4.2、 配置事务的通知
<!-- 配置事务的增强 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- isolation="DEFAULT" 隔离级别 propagation="REQUIRED" 传播行为 read-only="false" 只读 timeout="-1" 过期时间 rollback-for="" -Exception no-rollback-for="" +Exception --> <tx:method name="transfer" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
5.4.3、 配置aop事务
<aop:config> <aop:pointcut expression="execution(* cn.xxxxx.transaction.demo2.AccountServiceImpl.transfer(..))" id="pointcut1"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> </aop:config>
5.5、Spring的声明式事务的注解方式: (*****)
5.5.1、 配置事务管理器:
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
5.5.2、 开启事务管理的注解:
<!-- 开启注解事务管理 --> <tx:annotation-driven transaction-manager="transactionManager"/>
5.5.3、 在使用事务的类上添加一个注解:@Transactional