Spring的Jdbc事务-零配置


一、拷贝必要的jar包到工程的lib目录

二、准备数据库表和实体类


创建数据库:
create database spring;
use spring;
创建表:
create table account(
    id int primary key auto_increment,
    name varchar(40),
    money float
)character set utf8 collate utf8_general_ci;
package com.yiidian.domain;

import java.io.Serializable;
/**
 * @author http://www.yiidian.com
 * 
 */
public class Account implements Serializable{
	private Integer id;
	private String name;
	private Float money;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Float getMoney() {
		return money;
	}
	public void setMoney(Float money) {
		this.money = money;
	}
	@Override
	public String toString() {
		return "Account [id=" + id + ", name=" + name + ", money=" + money
				+ "]";
	}

	
}


三、编写业务层接口和实现类

AccountService:

package com.yiidian.service;

import com.yiidian.domain.Account;
/**
 * @author http://www.yiidian.com
 * 
 */
public interface AccountService {
	/**
	 * 根据id查询账户信息
	 * @param id
	 * @return
	 */
	Account findAccountById(Integer id);//查
	
	/**
	 * 转账
	 * @param sourceName	转出账户名称
	 * @param targeName		转入账户名称
	 * @param money			转账金额
	 */
	void transfer(String sourceName,String targeName,Float money);//增删改
}

AccountServiceImpl:

package com.yiidian.service.impl;

import org.springframework.transaction.annotation.Transactional;

import com.yiidian.dao.AccountDao;
import com.yiidian.domain.Account;
import com.yiidian.service.AccountService;
/**
 * @author http://www.yiidian.com
 * 
 */
@Transactional
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;

	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}

	@Override
	public Account findAccountById(Integer id) {
		return accountDao.findAccountById(id);
	}

	@Override
	public void transfer(String sourceName, String targeName, Float money) {
		// 1.根据名称查询两个账户
		Account source = accountDao.findAccountByName(sourceName);
		Account target = accountDao.findAccountByName(targeName);
		// 2.修改两个账户的金额
		source.setMoney(source.getMoney() - money);// 转出账户减钱
		target.setMoney(target.getMoney() + money);// 转入账户加钱
		// 3.更新两个账户
		accountDao.updateAccount(source);
		//模拟异常
		//int i = 1 / 0;
		accountDao.updateAccount(target);
	}
}

注意:CustomerServiceImpl类上面有@Transactional注解,这就是注解事务的关键用法。

四、编写Dao接口和实现类

AccountDao:

package com.yiidian.dao;

import com.yiidian.domain.Account;

/**
 * 
 * @author http://www.yiidian.com
 * 
 */
public interface AccountDao {

	/**
	 * 根据id查询账户信息
	 * @param id
	 * @return
	 */
	Account findAccountById(Integer id);

	/**
	 * 根据名称查询账户信息
	 * @return
	 */
	Account findAccountByName(String name);
	
	/**
	 * 更新账户信息
	 * @param account
	 */
	void updateAccount(Account account);
}

AccountDaoImpl:

package com.yiidian.dao.impl;

import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import com.yiidian.dao.AccountDao;
import com.yiidian.domain.Account;
/**
 * 
 * @author http://www.yiidian.com
 * 
 */
@Repository("accountDao")
public class AccountDaoImpl extends JdbcDaoSupport  implements AccountDao{
	
	@Resource
	public void setMyDataSource(DataSource ds){
		super.setDataSource(ds);
	}
	
	
	@Override
	public Account findAccountById(Integer id) {
		List<Account> list = getJdbcTemplate().query("select * from account where id = ? ",new AccountRowMapper(),id);
		return list.isEmpty()?null:list.get(0);
	}

	@Override
	public Account findAccountByName(String name) {
		List<Account> list =  getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);
		if(list.isEmpty()){
			return null;
		}
		if(list.size()>1){
			throw new RuntimeException("结果集不唯一,不是只有一个账户对象");
		}
		return list.get(0);
	}

	@Override
	public void updateAccount(Account account) {
		getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
	}
}

注意:该类用了@Repository注解。

AccountRowMapper:

package com.yiidian.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import com.yiidian.domain.Account;
/**
 * 账户的封装类RowMapper的实现类
 * @author http://www.yiidian.com
 *
 */
public class AccountRowMapper 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.getFloat("money"));
		return account;
	}
}

五、编写Spring配置类

JdbcConfig:

package com.yiidian.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
 * 
 * @author http://www.yiidian.com
 * 
 */
@PropertySource(value="classpath:jdbc.properties")
@EnableTransactionManagement  //开启Spring注解事务
public class JdbcConfig {
	@Value("${jdbc.driverClass}")
	private String driverClass;
	@Value("${jdbc.url}")
	private String url;
	@Value("${jdbc.username}")
	private String username;
	@Value("${jdbc.password}")
	private String password;
	

	@Bean(name="dataSource")
	public DataSource getDataSource(){
		DriverManagerDataSource ds = new DriverManagerDataSource();
		ds.setDriverClassName(driverClass);
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		return ds;
	}
	
	@Bean(name="jdbcTemplate")
	public JdbcTemplate getJdbcTemplate(@Qualifier("dataSource")DataSource ds){
		JdbcTemplate jt = new JdbcTemplate();
		jt.setDataSource(ds);
		return jt;
	}
	
	@Bean(name="transactionManager")
	public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("dataSource")DataSource ds){
		DataSourceTransactionManager manager = new DataSourceTransactionManager();
		manager.setDataSource(ds);
		return manager;
	}
}

注意:该类用到了@EnableTransactionManagement这个关键的事务注解。

SpringConfig:

package com.yiidian.config;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Spring配置类
 * @author http://www.yiidian.com
 *
 */
@Configurable
@ComponentScan(basePackages="com.yiidian") //扫描注解类
@Import(value=JdbcConfig.class)  //导入其他配置类
public class SpringConfig {

}

六、编写测试类

package com.yiidian.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.yiidian.config.SpringConfig;
import com.yiidian.service.AccountService;

/**
 * @author http://www.yiidian.com
 * 
 */
public class JdbcTemplateDemo {

	@Test
	public void test1() {
		ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
		AccountService accountService = (AccountService)ac.getBean("accountService");
		accountService.transfer("小苍", "小泽", 300f);
	}


}

 

源码下载:http://pan.baidu.com/s/1slJTVzf