spring--(24)事務準備

###需求:有以下三張表
1.書名錶spring

CREATE TABLE `t_book` (
  `book_id` int(4) NOT NULL AUTO_INCREMENT,
  `book_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `book_price` decimal(4,2) DEFAULT NULL,
  PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1003 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2.庫存表sql

CREATE TABLE `t_stock` (
  `stock_id` int(4) NOT NULL AUTO_INCREMENT,
  `stock_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `stock_num` int(4) DEFAULT NULL,
  PRIMARY KEY (`stock_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

3.用戶餘額表app

CREATE TABLE `t_user` (
  `user_id` int(4) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `balance` decimal(6,2) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

業務需求:
1.先從書名錶中獲取該書的價格
2.買一本書,即更新庫存表該書的數量
3.更新用戶餘額表的餘額
###接口層設計ide

public interface BookShopDao {
	
	//根據書號獲取書的價格
	public double getBookPriceByBookId(int bookId);
	
	//更新書的庫存,減一
	public void updateBookStock(int bookId);
	
	//更新用戶帳戶餘額
	public void updateUserBalance(int userId,double price);
}

###接口實現層設計測試

package com.test.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 獲取書的價格
	 */
	@Override
	public double getBookPriceByBookId(int bookId) {
		
		String sql = "SELECT tb.book_price FROM t_book tb WHERE tb.book_id=?";
		return jdbcTemplate.queryForObject(sql, Double.class,bookId);
	}
	
	/**
	 * 更新庫存
	 */
	@Override
	public void updateBookStock(int bookId) {
		
		//檢查庫存是否足夠,若不夠,則拋出異常
		String sqlCheck = "SELECT ts.stock_num FROM t_stock ts WHERE ts.stock_id=?";
		int stockNum = jdbcTemplate.queryForObject(sqlCheck, Integer.class,bookId);
		if (stockNum <= 0) {
			throw new BookStockException("庫存不足");
		}
		String sql = "UPDATE t_stock SET stock_num=stock_num-1 WHERE stock_id = ?";
		jdbcTemplate.update(sql, bookId);
	}

	/**
	 * 更新帳戶餘額
	 */
	@Override
	public void updateUserBalance(int userId, double price) {
		//驗證餘額是否足夠,若不夠,則拋出異常
		String sql2 ="SELECT tu.balance FROM t_user tu WHERE tu.user_id= ?";
		double balance = jdbcTemplate.queryForObject(sql2, Double.class,userId);
		if (balance < price) {
			throw new UserBalanceException("餘額不足");
		}
		
		String sql = "UPDATE t_user SET balance=balance-? WHERE user_id= ?";
		jdbcTemplate.update(sql, price, userId);
	}

}

###測試代碼spa

package com.test.spring.tx;


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;

public class TestTx {
	
	private ApplicationContext ctx;
	private BookShopDao bookShopDao;
	private BookShopService bookShopService;
	
	{
		ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		bookShopDao = ctx.getBean(BookShopDao.class);
		bookShopService = ctx.getBean(BookShopService.class);
	}
	/**
	 * 獲取書的單價
	 */
	@Test
	public void testgetBookPrice() {
		System.out.println(bookShopDao.getBookPriceByBookId(1000));
	}
	
	/**
	 * 更新書的庫存
	 */
	@Test
	public void testUpdateBookStock(){
		bookShopDao.updateBookStock(1001);
	}
	
	/**
	 * 更新用戶金額
	 */
	@Test
	public void testUpdateUserBalance(){
		bookShopDao.updateUserBalance(1000, 20);
	}

}

###庫存不足異常類設計

package com.test.spring.tx;

@SuppressWarnings("serial")
public class BookStockException extends RuntimeException{

	public BookStockException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

}

###用戶餘額不足異常類code

package com.test.spring.tx;

@SuppressWarnings("serial")
public class UserBalanceException extends RuntimeException{

	public UserBalanceException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public UserBalanceException(String message, Throwable cause, boolean enableSuppression,
			boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public UserBalanceException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public UserBalanceException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public UserBalanceException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	
}

###xml文件配置component

<context:component-scan base-package="com.test.spring.tx"></context:component-scan>
	
	<context:property-placeholder location="classpath:db.properties"/>
	
			<!-- 配置數據源 -->
		<bean id="dataSources" class="com.mchange.v2.c3p0.ComboPooledDataSource">
			<property name="user" value="${jdbc.user}"></property>
			<property name="password" value="${jdbc.password}"></property>
			<property name="driverClass" value="${jdbc.driverClass}"></property>
			<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
			
			<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
			<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
		</bean>
		

		<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
			<property name="dataSource" ref="dataSources"></property>
		</bean>
相關文章
相關標籤/搜索