Spring的数据库开发+事务处理(分xml方式和注解方式)

流程图:
在这里插入图片描述

项目结构:
在这里插入图片描述
代码:

package com.csdn3.SpringJDBC;

public class Account {

	private Integer id;
	private String username;
	private Double balance;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getBalance() {
		return balance;
	}
	public void setBalance(Double balance) {
		this.balance = balance;
	}
	@Override
	public String toString() {
		return "Account [id=" + id + ", username=" + username + ", balance=" + balance + "]";
	}
	
}

package com.csdn3.SpringJDBC;

import java.util.List;

public interface AccountDao {
	public int addAccount(Account account);
	public int updateAccount(Account account);
	public int deleteAccount(int id);
	
	public Account findAccountById(int id);
	public List<Account> findAllAccount();
}

package com.csdn3.SpringJDBC;

import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class AccountDaoImplement implements AccountDao{

	private JdbcTemplate jdbcTemplate;
	
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	@Override
	public int addAccount(Account account) {
		// TODO Auto-generated method stub
		String sql="insert into account(username,balance) value (?,?)";
		Object[] objects=new Object[] {
				account.getUsername(),
				account.getBalance()
		};
		//执行添加操作,返回的是受影响的记录条数
		int num=this.jdbcTemplate.update(sql,objects);
		return num;
	}

	@Override
	public int updateAccount(Account account) {
		// TODO Auto-generated method stub
		String sql="update account set username=?,balance=? where id=?";
		Object[] objects=new Object[] {
				account.getUsername(),
				account.getBalance(),
				account.getId()
		};
		int num=this.jdbcTemplate.update(sql,objects);
		return num;
	}

	@Override
	public int deleteAccount(int id) {
		// TODO Auto-generated method stub
		String sql="delete from account where id=?";
		int num=this.jdbcTemplate.update(sql,id);
		return num;
	}

	@Override
	public Account findAccountById(int id) {
		// TODO Auto-generated method stub
		String sql="select  * from account where id=?";
		RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);
		return this.jdbcTemplate.queryForObject(sql,rowMapper,id);
	}

	@Override
	public List<Account> findAllAccount() {
		// TODO Auto-generated method stub
		String sql="select * from account ";
		RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);
		return this.jdbcTemplate.query(sql, rowMapper);
	}

}

说明:BeanPropertyRowMapper是RowMapper接口的实现类,它可以自动地将数据表中的数据映射到用户自定义的类中(前提是用户自定义类中的字段要与数据表的字段对应),创建完BeanPropertyRowMapper对象之后,在findXXX()方法中通过queryForObject()方法返回一个Object类型的单行记录;通过query()方法返回一个结果集合。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		
		<property name="url" value="jdbc:mysql://localhost:3306/javaee"/>
		
		<property name="username" value="root"/>
		
		<property name="password" value=""/>
	
	</bean>
	
	
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	
		<property name="dataSource" ref="dataSource"/>
	
	</bean>
	
	
	<bean id="accountDao" class="com.csdn3.SpringJDBC.AccountDaoImplement">
		
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	
	</bean>
    <!-- more bean definitions go here -->

</beans>

package com.csdn3.SpringJDBC;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
	@Test
	public void addAccountTest() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/csdn3/SpringJDBC/ac.xml");
		AccountDao accountdao=(AccountDao)applicationContext.getBean("accountDao");
		Account account=new Account();
		account.setUsername("xumaoyan");
		account.setBalance(10000.00);
		int num=accountdao.addAccount(account);
		if(num>0)System.out.println("成功插入了"+num+"条数据");
		else System.out.println("插入操作有误!");
	}
	@Test
	public void findAccountTest() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/csdn3/SpringJDBC/ac.xml");
		AccountDao accountdao=(AccountDao)applicationContext.getBean("accountDao");
		Account account=accountdao.findAccountById(15);
		System.out.println(account);
	}
	@Test
	public void findAllAccountTest() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/csdn3/SpringJDBC/ac.xml");
		AccountDao accountdao=(AccountDao)applicationContext.getBean("accountDao");
		List<Account> account=accountdao.findAllAccount();
		for(Account act:account) {
			System.out.println(act);
		}
		
	}
}

最后一个Test下的的运行效果图:
在这里插入图片描述
我的数据库:
在这里插入图片描述

Spring的事务管理:

本章将在上面代码的基础上进行讲解:

基于xml方式的声明式事务:

流程图:
在这里插入图片描述

在AcountDao接口中增加一个转账方法:

public void transfer(String outUser,String inUser,Double money);

在AccountDaoImplement实现类中编辑转账方法

public void transfer(String outUser, String inUser, Double money) {
		
		this.jdbcTemplate.update("update account set balance=balance+? where username=?",money,inUser);
		//模拟系统执行转账过程中的突发情况
		int i=1/0;
		this.jdbcTemplate.update("update account set balance=balance-? where username=?",money,outUser);
		// TODO Auto-generated method stub
		
	}

说明这里故意模拟系统执行转账过程中的突发情况,当这个方法执行的时候,事务管理将撤销上一步操作

将ac.xml文件改为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop"
              xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd">
        
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		
		<property name="url" value="jdbc:mysql://localhost:3306/javaee"/>
		
		<property name="username" value="root"/>
		
		<property name="password" value=""/>
	
	</bean>
	
	
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	
		<property name="dataSource" ref="dataSource"/>
	
	</bean>
	
	
	<bean id="accountDao" class="com.csdn3.SpringJDBC.AccountDaoImplement">
		
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	
	</bean>
    <!-- more bean definitions go here -->
	<!--注册事务管理器-->
	<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
	<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!--事务的属性配置-->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	<!--切点的织入-->
	<aop:config>
		<aop:pointcut id="txPoint" expression="execution(* com.csdn3.SpringJDBC.*.*(..))"/>
		<aop:advisor pointcut-ref="txPoint" advice-ref="txAdvice"/>
	</aop:config>

	
</beans>

在test类中写单元测试类:

@Test
	public void Transfer() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/csdn3/SpringJDBC/ac.xml");
		AccountDao accountdao=(AccountDao)applicationContext.getBean("accountDao");
		accountdao.transfer("xumaoyan", "hq", 2000.00);
		System.out.println("转账成功");
	}

运行测试:
在这里插入图片描述
单元测试确实报了:/by zero错误。检查数据库,数据没有改变。
撤销错误,转账操作执行,转账成功。
在这里插入图片描述
在这里插入图片描述
基于Annotation方式的声明式事务:
只需要将切点的织入部分更改为以下配置即可,然后在需要使用事务的方法上使用@Transaction注解

<tx:annotation-driven transaction-manager="txManager"/>

需要注意的是,当项目中需要实例化的bean过多的时候,要开启注解处理器。这里因为配置了实现类的bean,而事务的注解也正好配置在该bean中,所以直接生效了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值