垃圾版代码,只提供一个思路
第一个版本
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP ‘index.jsp‘ starting page</title> </head> <body> <form action="${pageContext.request.contextPath}/account" method="post"> 转款人<input type="text" name="outuser"> 收款人<input type="text" name="inuser"> 金额<input type="text" name="money"> <input type="submit" value="转账"> </form> </body> </html>
servlet
public class AccountServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); // 1.收集数据 String outuser = request.getParameter("outuser"); String inuser = request.getParameter("inuser"); String money = request.getParameter("money"); // 2.调用AccountService中的account方法 AccountService service = new AccountService(); try { service.account(outuser, inuser, money); response.getWriter().write("汇款成功"); } catch (AccountException e) { e.printStackTrace(); response.getWriter().write(e.getMessage()); } } }
service
public class AccountService { // 原始转账方法 public void _account(String outuser, String inuser, String money) throws AccountException { AccountDao dao = new AccountDao(); // 获取连接对象,并开启事务 Connection con = null; try { con = JdbcUtils.getConnection(); con.setAutoCommit(false); // 开启事务 // 调用AccountDao中两个方法 // 转出 dao.accountOut(con, outuser, money); // 转入 dao.accountIn(con, inuser, money); } catch (SQLException e) { e.printStackTrace(); // 事务回滚 try { con.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } throw new AccountException("转账失败"); } catch (AccountException e) { e.printStackTrace(); // 事务回滚 try { con.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } throw e; } finally { try { con.commit(); // 提交事务 con.close(); // 关闭资源 } catch (SQLException e) { e.printStackTrace(); } } } // 转账方法 public void account(String outuser, String inuser, String money) throws AccountException { AccountDao dao = new AccountDao(); try { // 开启事务 JdbcUtils.startTransaction(); // 转出 dao.accountOut(outuser, money); // 转入 dao.accountIn(inuser, money); } catch (SQLException e) { e.printStackTrace(); // 事务回滚 try { JdbcUtils.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } throw new AccountException("转账失败"); } catch (AccountException e) { e.printStackTrace(); // 事务回滚 try { JdbcUtils.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } throw e; } finally { try { JdbcUtils.commit();// 提交事务 JdbcUtils.closeConnection(); // 关闭资源 } catch (SQLException e) { e.printStackTrace(); } } } }
dao
public class AccountDao { // 转入 public void accountIn(Connection con, String inuser, String money) throws SQLException, AccountException { String sql = "update account set money=money+? where username=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, money); pst.setString(2, inuser); int row = pst.executeUpdate(); if (row == 0) { throw new AccountException("转入失败"); } pst.close(); } // 转出 public void accountOut(Connection con, String outuser, String money) throws SQLException, AccountException { String sql = "update account set money=money-? where username=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, money); pst.setString(2, outuser); int row = pst.executeUpdate(); if (row == 0) { throw new AccountException("转出失败"); } pst.close(); } // 转入--使用ThreadLocal获取连接 public void accountIn(String inuser, String money) throws SQLException, AccountException { Connection con = JdbcUtils.getConnection(); String sql = "update account set money=money+? where username=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, money); pst.setString(2, inuser); int row = pst.executeUpdate(); if (row == 0) { throw new AccountException("转入失败"); } pst.close(); } // 转出 public void accountOut(String outuser, String money) throws SQLException, AccountException { Connection con = JdbcUtils.getConnection(); String sql = "update account set money=money-? where username=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, money); pst.setString(2, outuser); int row = pst.executeUpdate(); if (row == 0) { throw new AccountException("转出失败"); } pst.close(); } }
exception
public class AccountException extends Exception { public AccountException() { super(); } public AccountException(String message, Throwable cause) { super(message, cause); } public AccountException(String message) { super(message); } public AccountException(Throwable cause) { super(cause); } }
//高级的,使用ThreadLocal public class JdbcUtils { private static final String DRIVERCLASSNAME; private static final String URL; private static final String USER; private static final String PASSWORD; static { ResourceBundle bundle = ResourceBundle.getBundle("jdbc"); DRIVERCLASSNAME = bundle.getString("DRIVERCLASSNAME"); URL = bundle.getString("URL"); USER = bundle.getString("USER"); PASSWORD = bundle.getString("PASSWORD"); } static { try { Class.forName(DRIVERCLASSNAME); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); // 它就相当于是一个Map集合。 public static Connection getConnection() throws SQLException { // Connection con = tl.get(); // 从ThreadLocal中获取,第一次一得到的一定是null. // if (con == null) { Connection con = DriverManager.getConnection(URL, USER, PASSWORD); // tl.set(con);// 将con装入到ThreadLocal中。 // } return con; } // 封装事务操作. // 开启事务 public static void startTransaction() throws SQLException { Connection con = getConnection(); con.setAutoCommit(false); } public static void rollback() throws SQLException { Connection con = getConnection(); con.rollback(); } // 事务提交 public static void commit() throws SQLException { Connection con = getConnection(); con.commit(); } public static void closeStatement(Statement st) throws SQLException { if (st != null) st.close(); } public static void closeResultSet(ResultSet rs) throws SQLException { if (rs != null) rs.close(); }
ThreadLocal
它的底层是使用了一个Map集合
Map<Thread,Object>
它的key就是当前的线程对象.
set(Object obj) 它就相当于 map.put(Thread.currentThread(),obj);
get()它就相当于 map.get(Thread.currentThread()));
时间: 2024-10-25 23:24:24