Spring学习笔记(四) --- Spring ORM模板和事务

2021-04-13 14:55:36 浏览数 (1)

1、Spring的支持的持久层技术的模板类

2、Spring JDBC内置连接池的基本使用

步骤一:引入相关开发包

步骤二:创建一个测试类:

代码语言:javascript复制
    @Test
	// JDBC模板的基本使用:
	public void demo1(){
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql:///spring");
		dataSource.setUsername("root");
		dataSource.setPassword("123");
		
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update("insert into account values (null,?,?)", "哇哈哈",10000d);
	}

3、将连接池的配置交给Spring管理

Ⅰ、Spring内置的连接池的配置

代码语言:javascript复制
代码语言:javascript复制

注入DataSource的原理解析图解:

编写测试类:

代码语言:javascript复制
@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);
	}

}

Ⅱ、Spring中配置DBCP连接池

步骤一:引入dbcp连接池的jar包

步骤二:配置连接池

代码语言:javascript复制

Ⅲ、配置c3p0连接池

步骤一:引入相应jar包

步骤二:配置连接池

代码语言:javascript复制

Ⅳ、JDBC模板的CRUD的操作

代码语言:javascript复制
@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 list = jdbcTemplate.query("select * from account", new MyRowMapper());
		for (Account account : list) {
			System.out.println(account);
		}
	}
	
	class MyRowMapper implements RowMapper{

		@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、事务

Ⅰ、什么是事务?

事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.

Ⅱ、事务特性

原子性    :强调事务的不可分割.

一致性    :事务的执行的前后数据的完整性保持一致.

隔离性    :一个事务执行的过程中,不应该受到其他事务的干扰

持久性    :事务一旦结束,数据就持久到数据库

如果不考虑隔离性引发安全性问题?

代码语言:javascript复制
        脏读              :一个事务读到了另一个事务的未提交的数据
    
        不可重复读        :一个事务读到了另一个事务已经提交的update的数据导致多次查询结果不一致.

        虚读              :一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致.

如何解决读问题?

设置事务隔离级别:

代码语言:javascript复制
    未提交读	:脏读,不可重复读,虚读都有可能发生
    已提交读	:避免脏读。但是不可重复读和虚读有可能发生
    可重复读	:避免脏读和不可重复读.但是虚读有可能发生.
    串行化的	:避免以上所有读问题.

5、使用Spring进行事务管理

Ⅰ、PlatformTransactionManager:平台事务管理器

代码语言:javascript复制
//真正管理事务的对象

org.springframework.jdbc.datasource.DataSourceTransactionManager	使用Spring JDBC或iBatis进行持久化数据时使用 

org.springframework.orm.hibernate3.HibernateTransactionManager		使用Hibernate版本进行持久化数据时使用

Ⅱ、TransactionDefinition:事务定义信息

代码语言:javascript复制
事务定义信息:
    * 隔离级别
    * 传播行为
    * 超时信息
    * 是否只读

Ⅲ、TransactionStatus:事务的状态

记录事务的状态

Ⅳ、Spring的这组接口是如何进行事务管理的?

平台事务管理根据事务定义的信息进行事务的管理,事务管理的过程中产生一些状态,将这些状态记录到TransactionStatus里面。

Ⅴ、事务的传播行为

代码语言:javascript复制
PROPAGION_XXX		:事务的传播行为

* 保证同一个事务中
PROPAGATION_REQUIRED		支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS		支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY       支持当前事务,如果不存在,抛出异常

* 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW	如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED	以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 	        以非事务方式运行,如果有事务存在,抛出异常

PROPAGATION_NESTED	        如果当前事务存在,则嵌套事务执行

6、搭建转账环境代码

步骤一:创建业务层和DAO的类

代码语言:javascript复制
public interface AccountService {

	public void transfer(String from,String to,Double money);
}

public class AccountServiceImpl implements AccountService {

	// 业务层注入DAO:
	private AccountDao accountDao;
	
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}

	@Override
	/**
	 * from:转出的账号
	 * to:转入的账号
	 * money:转账金额
	 */
	public void transfer(String from, String to, Double money) {
		accountDao.outMoney(from, money);
		accountDao.inMoney(to, money);
	}

}

public interface AccountDao {

	public void outMoney(String from,Double money);
	
	public void inMoney(String to,Double money);
}

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

	@Override
	public void outMoney(String from, Double money) {
		this.getJdbcTemplate().update("update account set money = money - ? where name = ?", money,from);
	}

	@Override
	public void inMoney(String to, Double money) {
		this.getJdbcTemplate().update("update account set money = money   ? where name = ?", money,to);  
	}
          
}

步骤二:配置业务层和DAO

代码语言:javascript复制

步骤三:编写测试类

代码语言:javascript复制
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class SpringDemo4 {
	
	@Resource(name="accountService")
	private AccountService accountService;
	
	@Test
	// 转账的测试:
	public void demo1(){
		accountService.transfer("会希", "凤姐", 1000d);
	}
}

7、手动编程实现Spring事务管理

步骤一:配置事务管理器

代码语言:javascript复制

步骤二:配置事务管理的模板

代码语言:javascript复制

步骤三:在业务层注入事务管理模板

代码语言:javascript复制

步骤四:手动编写代码实现事务管理

代码语言:javascript复制
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);		
			}
		});
			
	}

8、Spring的声明式事务管理XML方式(思想就是AOP)

不需要进行手动编写代码,通过一段配置完成事务管理。

步骤一:引入AOP开发的包

代码语言:javascript复制
    Spring-aop.jar
    aspectJ.jar
    spring-aspects.jar

步骤二:配置事务管理器

代码语言:javascript复制

步骤三:配置事务的通知

代码语言:javascript复制

步骤四:配置AOP事务

代码语言:javascript复制

9、Spring的声明式事务的注解方式

步骤一:引入jar包

步骤二:配置事务管理器

代码语言:javascript复制

步骤三:开启事务管理注解

代码语言:javascript复制

步骤四:在使用事务的类上添加一个注解:@Transactional

0 人点赞