Dao层
package com.bjpowernode.Bank.Dao;
import com.bjpowernode.Bank.Pojo.Account;
import java.util.List;
public interface AccountDao
{
//DAO,Data Access Object数据访问对象
//取名规范取决于处理的表名字
int insert(Account account);
int deleteByActno(Long id);
int update(Account account);
Account selectByActno(String actno);
List<Account> selectAll();
}
Dao实现类
package com.bjpowernode.Bank.Dao.Impl;
import com.bjpowernode.Bank.Dao.AccountDao;
import com.bjpowernode.Bank.Pojo.Account;
import com.bjpowernode.Bank.utils.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AccountDaoImpl implements AccountDao
{
@Override
public int insert(Account account)
{
ResultSet resultSet = null;
PreparedStatement statement = null;
Connection connection = null;
int count = 0;
try
{
connection = DBUtil.getConnection();
String sql = "insert into t_act(id,actno,balance) values(?,?,?)";
statement = connection.prepareStatement(sql);
statement.setString(1,null);
statement.setString(2,account.getActno());
statement.setDouble(3,account.getBalance());
count = statement.executeUpdate();
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
finally
{
DBUtil.close(null,statement,resultSet);
}
return count;
}
@Override
public int deleteByActno(Long id) {
ResultSet resultSet = null;
PreparedStatement statement = null;
Connection connection = null;
int count = 0;
try
{
connection = DBUtil.getConnection();
String sql = "delete from t_act where id = ?";
statement = connection.prepareStatement(sql);
statement.setLong(1,id);
count = statement.executeUpdate();
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
finally
{
DBUtil.close(null,statement,resultSet);
}
return count;
}
@Override
public int update(Account account) {
ResultSet resultSet = null;
PreparedStatement statement = null;
Connection connection = null;
int count = 0;
try
{
connection = DBUtil.getConnection();
String sql = "update t_act set actno = ?,balance = ? where id = ?";
statement = connection.prepareStatement(sql);
statement.setString(1,account.getActno());
statement.setDouble(2,account.getBalance());
statement.setLong(3,account.getId());
count = statement.executeUpdate();
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
finally
{
DBUtil.close(null,statement,resultSet);
}
return count;
}
@Override
public Account selectByActno(String actno) {
ResultSet resultSet = null;
PreparedStatement statement = null;
Connection connection = null;
Account account = new Account();
try
{
connection = DBUtil.getConnection();
String sql = "select * from t_act where actno = ?";
statement = connection.prepareStatement(sql);
statement.setString(1,actno);
resultSet = statement.executeQuery();
if(resultSet.next())
{
account.setActno(actno);
Long id = resultSet.getLong("id");
account.setId(id);
double balance = resultSet.getDouble("balance");
account.setBalance(balance);
}
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
finally
{
DBUtil.close(null,statement,resultSet);
}
return account;
}
@Override
public List<Account> selectAll() {
ResultSet resultSet = null;
PreparedStatement statement = null;
Connection connection = null;
List<Account> list = null;
try
{
connection = DBUtil.getConnection();
String sql = "select * from t_act";
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while(resultSet.next())
{
list = new ArrayList<Account>();
Account account = new Account();
String actno = resultSet.getString("actno");
account.setActno(actno);
Long id = resultSet.getLong("id");
account.setId(id);
double balance = resultSet.getDouble("balance");
account.setBalance(balance);
list.add(account);
}
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
finally
{
DBUtil.close(null,statement,resultSet);
}
return list;
}
}
自定义App异常类
package com.bjpowernode.Bank.exception;
public class AppException extends Exception
{
public AppException(){}
public AppException(String message) {
super(message);
}
}
自定义转账异常类
package com.bjpowernode.Bank.exception;
public class MoneyNotEnoughException extends Exception
{
public MoneyNotEnoughException(){}
public MoneyNotEnoughException(String msg){super(msg);}
}
ORM对象映射类
package com.bjpowernode.Bank.Pojo;
public class Account
{
private Long id;
private String actno;
private Double balance;
@Override
public String toString() {
return "Account{" +
"id=" + id +
", actno='" + actno + '\'' +
", balance=" + balance +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public Account(Long id, String actno, Double balance) {
this.id = id;
this.actno = actno;
this.balance = balance;
}
public Account() {
}
}
Service类
package com.bjpowernode.Bank.service;
import com.bjpowernode.Bank.Dao.AccountDao;
import com.bjpowernode.Bank.exception.MoneyNotEnoughException;
public interface AccountService
{
//业务类,专注于业务处理
//不写别的,只处理业务信息
void transfer(String fromActno,String toActno,double money) throws Exception;
}
Service实现类
package com.bjpowernode.Bank.service.Impl;
import com.bjpowernode.Bank.Dao.AccountDao;
import com.bjpowernode.Bank.Dao.Impl.AccountDaoImpl;
import com.bjpowernode.Bank.Pojo.Account;
import com.bjpowernode.Bank.exception.AppException;
import com.bjpowernode.Bank.exception.MoneyNotEnoughException;
import com.bjpowernode.Bank.service.AccountService;
import com.bjpowernode.Bank.utils.DBUtil;
import java.sql.Connection;
import java.sql.SQLException;
public class AccountServiceImpl implements AccountService
{
private AccountDao accountDao = new AccountDaoImpl();
@Override
public void transfer(String fromActno, String toActno, double money) throws Exception {
//在service层开启事务
try
{
Connection connection = DBUtil.getConnection();
connection.setAutoCommit(false);
Account fromAccount = accountDao.selectByActno(fromActno);
if(fromAccount.getBalance() < money)
{
throw new MoneyNotEnoughException("余额不足");
}
Account toAccount = accountDao.selectByActno(toActno);
fromAccount.setBalance(fromAccount.getBalance() - money);
toAccount.setBalance(toAccount.getBalance() + money);
int count = accountDao.update(fromAccount);
count = count + accountDao.update(toAccount);
if(count != 2)
{
throw new AppException("转账失败");
}
connection.commit();
}
catch(SQLException e)
{
throw new AppException("转账异常,请联系客服");
}
finally
{
DBUtil.close(DBUtil.getConnection(),null,null);
}
}
}
Controller或Servlet
package com.bjpowernode.Bank.servlet;
import com.bjpowernode.Bank.service.AccountService;
import com.bjpowernode.Bank.service.Impl.AccountServiceImpl;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/bank/transfer")
public class AccountServlet extends HttpServlet
{
private AccountService accountService = new AccountServiceImpl();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//接收数据
String fromActno = request.getParameter("fromActno");
String toActno = request.getParameter("toActno");
Double value = Double.valueOf(request.getParameter("Value"));
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try
{
accountService.transfer(fromActno,toActno,value);
out.println("转账成功");
}
catch (Exception e)
{
out.println(e.getMessage());
}
}
}
使用ThreadLocal改造过的工具类
package com.bjpowernode.Bank.utils;
import java.sql.*;
import java.util.ResourceBundle;
public class DBUtil
{
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
private static String driver = bundle.getString("driver");
private static String url = bundle.getString("url");
private static String user = bundle.getString("user");
private static String password = bundle.getString("password");
//JDBC工具类
static
{
//注册驱动
try
{
// Class.forName("com.mysql.jdbc.Driver");//避免写死
Class.forName(driver);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
public static Connection getConnection() throws SQLException {
//获取链接
Connection connection = threadLocal.get();
if(connection == null)
{
connection = DriverManager.getConnection(url,user,password);
threadLocal.set(connection);
}
return connection;
}
//释放资源
public static void close(Connection connection, Statement statement, ResultSet resultSet)
{
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (connection != null) {
try {
connection.close();
//因为Tomcat服务器内置了一个线程池
//线程池内置了很多创建好的线程对象
//存在重复使用的可能,如果没有移除,就会导致另一个分配到这个线程的人
//会导致获取到已经关闭的connection对象
threadLocal.remove();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}