jdbc如何操作事务

1 . 今天学习了事务,来看一下jdbc是如何操作事务的.(最基本的)
2 . 以转账为例:

  1. 创建数据库和表
  2. 创建一个web工程,连接数据库,添加数据库驱动mysql;
  3. 转账页面 transformAccount.jsp (A转账到B 输入1000元) 按钮:转账 提交表单
  4. 转账servlet(TransformServlet)
    a.获取表单数据
    b.调用service层处理转账业务功能 (转账业务功能需要调用dao层)
    c.根据业务结果决定页面如何显示
    3 . 要清除,jdbc是用connection来进行操作事务的.
    4 .home页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="TransServlet" method="post">
 转账人: <input type="text" name="fromname"/><br>
收账人: <input type="text" name="toname"/><br>
转账金额: <input type="text" name="money"/><br>
<input type="submit" value="转账"/>
</form>
</body>
</html>

5 . servlet层

package com.lm.web.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lm.service.UserService;
import com.lm.service.impl.UserServiceImpl;

/**
 *  分发转向
 */
public class TransServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1 . 获取请求参数
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String fromname = request.getParameter("fromname");
        String toname = request.getParameter("toname");
        String money = request.getParameter("money");
        System.out.println(fromname+"   "+toname+"   "+money);
        // 2 . 处理请求参数
        UserService userService = new UserServiceImpl();
        double money1 = Double.parseDouble(money);
        boolean flag = userService.trans(fromname, toname, money1);
                if(flag) {
            response.sendRedirect("success.jsp");
        }else {
            request.setAttribute("trans_error_msg", "转账失败");
            request.getRequestDispatcher("home.jsp").forward(request,response);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

注意处理请求参数的那块,
UserService userService = new UserServiceImpl();
UserService 这是个接口,里面定义了UserServiceImpl类的方法,就是为了保证数据安全.
6 . service层

package com.lm.service.impl;

import java.sql.Connection;
import java.sql.SQLException;

import com.lm.dao.UserDao;
import com.lm.dao.impl.UserDaoImpl;
import com.lm.service.UserService;
import com.lm.utils.DBUtils;

public class UserServiceImpl implements UserService{

    @Override
    public boolean trans(String fromname, String toname, double money) {
        boolean flag = false;
        Connection connection = DBUtils.getConnection();
        UserDao userDao = new UserDaoImpl(connection);

        try {
            // 1. 开启事务
            connection.setAutoCommit(false);
            double fromMoney = userDao.queryMoneyByUser(fromname);
            double toMoney = userDao.queryMoneyByUser(toname);
            //先设置两个人转账之后的金额
            fromMoney = fromMoney-money;
            toMoney = toMoney + money;
            //更新每个用户的钱 如果更新不成功会抛出异常  之后执行catch
             //向上转型 子类创建的对象赋值给父类
            //这里的userDao是一个对象,给这个对象初始化了connection属性.
            //所以在userDao调用queryMoneyByUser和queryMoneyByUser方法的时候,
            //在dao层的connection.prepareStatement(sql)时是connection时没有定义的,
            //在这实际上是this.connection.prepareStatement(sql),也就是当前对象的connection调用prepareStatement方法
            int row1 = userDao.updateMoneyByUser(fromname, fromMoney);
            int row2 = userDao.updateMoneyByUser(toname, toMoney);
            //判断是不是都更新成功
            if(row1>0 && row2>0) {
                System.out.println("转账成功");
                flag = true;
            }else {
                System.err.println("转账失败");
                flag = false;
            }
            connection.commit();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("错误信息:"+e.getMessage());
            flag = false;
            // 3 . 事务回滚
            try {
                connection.rollback();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }

        return flag;
    }

}

7 . dao层

    package com.lm.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.management.loading.PrivateClassLoader;

import com.lm.dao.UserDao;
import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;

public class UserDaoImpl implements UserDao{
    //connection 属性
    private Connection connection;
    public UserDaoImpl(Connection connection) {
        this.connection = connection;
    }

    @Override
    public double queryMoneyByUser(String Username) throws SQLException {
        String sql="select * from user where name =?";
//下面等号右边相当于this.connection.prepareStatement(sql);

        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1, Username);
        ResultSet resultSet = preparedStatement.executeQuery();
        double money = 0;
        while(resultSet.next()) {
            money = resultSet.getDouble("money");
        }
        return money;

    }

    @Override
    public int updateMoneyByUser(String Username, double money) throws SQLException {
        String sql="update user set money = ? where name = ? ";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(2, Username);
        preparedStatement.setDouble(1, money);
        int row = preparedStatement.executeUpdate();
        return row;
    }

}

注意,dao层是有connection属性的.

这个例子用到了自定义异常,还用到了接口和实现类,为了数据的安全,下面给出UserDao的接口,

package com.lm.dao;

import java.sql.SQLException;

public interface UserDao {
    //查询指定用户金钱
    public double queryMoneyByUser(String Username) throws SQLException;
    //更新指定用户金钱
    public int  updateMoneyByUser(String Username,double money) throws SQLException;

}

UserDaoImpl的方法throws异常的话,service会捕获异常,connection.commit();不会执行到,从而会执行catch进行事务回滚connection.rollback();

总结:通过这个例子,要学会自己在哪抛出异常,在哪捕获异常,还有接口的使用.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值