一、这是书中第八章有关事物处理的一个例子。例子用有两个表,一个存储的是用户信息,另外一个存储的是图书信息。下面简要介绍这个程序的思路。
1.获取request请求中的用户信息--用户id和用户账户余额。
2.判断用户id和用户账户余额是否为空。如果为空则打印出错误信息。
3.如果用户id和用户账户余额不为空,将AutoComit设置为false。并从数据库中查询图书库存和单价。
4.将从request中得到的购买数量转化为整数。
5.判断购买数量是否大于库存数量,如果大于库存数量,则更新数据库,如果小于库存数量则打印出错误信息。
6.获取用户金额。
7.判断用户金额是否大于图书总价,如果大于则更新用户剩余金额,如果小于则打印出错误信息。
8.将上述操作提交到数据库。
二、书中的代码如下
package com.test.wayne;
import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;
import java.sql.*;
public class TradeServlet extends HttpServlet
{
private String url;
private String user;
private String password;
public void init() throws ServletException
{
ServletContext sc=getServletContext();
String driverClass=sc.getInitParameter("driverClass");
url=sc.getInitParameter("url");
user=sc.getInitParameter("user");
password=sc.getInitParameter("password");
try
{
Class.forName(driverClass);
}
catch(ClassNotFoundException ce)
{
throw new UnavailableException("加载数据库驱动失败!");
}
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException,IOException
{
Connection conn=null;
Statement stmt=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
resp.setContentType("text/html;charset=gb2312");
PrintWriter out=resp.getWriter();
req.setCharacterEncoding("gb2312");
String userid=req.getParameter("userid");//获取用户名id
String quantity=req.getParameter("quantity");//用户的余额
if(null==userid || userid.equals("") || //判断用户id和余额是否为空
null==quantity || quantity.equals(""))
{
out.println("错误的请求参数");
out.close();
}
else
{
try
{
conn=DriverManager.getConnection(url,user,password);
conn.setAutoCommit(false);//将自动提交设置为false
stmt=conn.createStatement();
rs=stmt.executeQuery("select price,amount from bookinfo where id=3");
rs.next();
float price=rs.getFloat(1);//获取图书价格
int amount=rs.getInt(2);//获取图书数量
int num=Integer.parseInt(quantity);//将从request中得到的购买数量转化为整数。
if(amount>=num)//判断购买数量是否大于库存数量
{
pstmt=conn.prepareStatement("update bookinfo set amount = ? where id = 3");
pstmt.setInt(1,amount-num);//更新库存数量
pstmt.executeUpdate();
}
else
{
out.println("您所购买的图书库存数量不足。");
out.close();
return;
}
pstmt=conn.prepareStatement("select balance from account where userid = ?");//获取用户金额
pstmt.setString(1,userid);
rs=pstmt.executeQuery();
rs.next();
float balance=rs.getFloat(1);
float totalPrice=price*num;//计算图书总价
if(balance>=totalPrice)//判断用户金额是否大于图书总价
{
pstmt=conn.prepareStatement("update account set balance = ? where userid = ?");//更新用户剩余金额
pstmt.setFloat(1,balance-totalPrice);
pstmt.setString(2,userid);
pstmt.executeUpdate();
}
else
{
conn.rollback();
out.println("您的余额不足。");
out.close();
return;
}
conn.commit();
out.println("交易成功!");
out.close();
}
catch(SQLException se)
{
if(conn!=null)
{
try
{
conn.rollback();
}
catch(SQLException sex)
{
sex.printStackTrace();
}
}
se.printStackTrace();
}
finally
{
if(rs!=null)
{
try
{
rs.close();
}
catch(SQLException se)
{
se.printStackTrace();
}
rs=null;
}
if(stmt!=null)
{
try
{
stmt.close();
}
catch(SQLException se)
{
se.printStackTrace();
}
stmt=null;
}
if(pstmt!=null)
{
try
{
pstmt.close();
}
catch(SQLException se)
{
se.printStackTrace();
}
pstmt=null;
}
if(conn!=null)
{
try
{
conn.close();
}
catch(SQLException se)
{
se.printStackTrace();
}
conn=null;
}
}
}
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException,IOException
{
doGet(req,resp);
}
}
三、总结:
写程序就像是写作文,思路很重要,在写之前脑子里应该有个关于这个程序运行的大概过程,在程序执行的过程中要分几部分,每一部分下面又包含几个情况,从整天上对程序有个了解,然后再从细节上对程序进行完善,最后进行测试。本来想把思路部分弄成一个思维导图的,但是忘了图怎么画了,等查完资料再弄图吧。