javaee学习之路(二十一)JavaWeb项目实战--银行存款业务

银行存款业务
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第1张图片
首先,定义一个工具常量类. Constants.java

package cn.itcast.util;
//常量池
public class Constants {
    /*
     * 与数据库db相关的常量
     */
    public static final String DB_ERROR_GETCONNECTIONERROR="获取连接异常";
    public static final String DB_ERROR_CLOSTRESULTSETERROR="获取结果集异常";
    public static final String DB_ERROR_CLOSESTATEMENTERROR="关闭statement对象异常";
    public static final String DB_ERROR_CLOSECONNECTIONERROR="关闭连接异常";
    public static final String DB_ERROR_STARTERROR="开始事务异常";
    public static final String DB_ERROR_COMMITERROR="提交事务异常";
    public static final String DB_ERROR_ROLLBACKERROR="获取结果集异常";
    public static final String DB_ERROR_SETERROR="设置连接的自动提交方式异常";
    /*与数据操作有关的异常*/
    public static final String DAO_ERROR_QUERYBYID="通过账号查询余额失败";
    public static final String DAO_ERROR_UPDATEBYID="通过账号更新余额失败";
    public static final String DAO_ERROR_INSERTBYID="添加账号失败";
……
}

第0步、index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>
  <body>
    存款页面:<br/>
    <form action="${pageContext.request.contextPath}/servlet/InAccountServlet" method="post">
       <table>
             <tr>
                  <td>账户:td>
                  <td><input type="text" name="accountid"/>td>
             tr>
              <tr>
                  <td>存入金额:td>
                  <td><input type="text" name="inbalance"/>td>
             tr>
             <tr>
                <td><input type="submit" value="存入"/>td>
                  <td>td>
             tr>
       table>
    form>
  body>
html>

第一步、DBManager.java

package cn.itcast.db;
public class DBManager {
    private static DBManager dbManager=new DBManager();
    private BasicDataSource bds=null;
    private DBManager(){
        bds=new BasicDataSource();
        bds.setUsername("root");
        bds.setPassword("root");
        bds.setUrl("jdbc:mysql://localhost:3306/test");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setInitialSize(4);
        bds.setMaxActive(10);
        bds.setMaxIdle(5);
        bds.setMinIdle(3);
        bds.setMaxWait(5000);
    }
    public static DBManager getDBManager(){
        return dbManager;
    }
    public Connection getConnection(){
        Connection conn=null;
        try {
            conn = bds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            //检查型异常---->运行时异常
            throw new DBException(Constants.DB_ERROR_GETCONNECTIONERROR,e);
        }
        return conn;
    }
    public void closeResource(Connection conn,Statement statement,ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException(Constants.DB_ERROR_CLOSTRESULTSETERROR,e);
        }finally{
            try {
                if(statement!=null){
                    statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
                throw new DBException(Constants.DB_ERROR_CLOSESTATEMENTERROR,e);
            }finally{
                try {
                    if(conn!=null){
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new DBException(Constants.DB_ERROR_CLOSECONNECTIONERROR,e);
                }
            }
        }
    }
    //开始事务,重新设置事务的提交方式为非自动提交
    public void beginTransaction(Connection conn) {
        try {
            if(conn!=null){
                conn.setAutoCommit(false);
                //int x=1/0;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new DBException(Constants.DB_ERROR_SETERROR,e);
        }
    }
    public void commitTransaction(Connection conn) {
        try {
            if(conn!=null){
                conn.commit();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(Constants.DB_ERROR_COMMITERROR,e);
        }
    }
    //回滚事务
    public void rollbackTransaction(Connection conn) {
        try {
            if(conn!=null){
                conn.rollback();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new DBException(Constants.DB_ERROR_ROLLBACKERROR,e);
        }
    }
    //重新设置事务的提交方式为自动提交
    public void resetTransaction(Connection conn) {
        try {
            if(conn!=null){
                conn.setAutoCommit(true);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new DBException(Constants.DB_ERROR_SETERROR,e);
        }
    }
}

第二步、InAccountServlet.java

package cn.itcast.web;
public class InAccountServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String path="";
        try {
            //1.获取表单信息
            String accountid=request.getParameter("accountid");
            String sinbalance=request.getParameter("inbalance");
            double inbalance=0;
            if(sinbalance!=null&&!("".equals(sinbalance.trim()))){
                inbalance=Double.parseDouble(sinbalance.trim());
            }
            //2.封装数据到javabean
            InAccount inAccount=new InAccount();
            inAccount.setAccountid(accountid);
            inAccount.setInbalance(inbalance);
            //3.实例化业务层对象
            InAccountService inAccountService=new InAccountService();
            inAccountService.saveInAccount(inAccount);
            path="/success.jsp";
        }catch(NumberFormatException e){
            //e.printStackTrace();
            request.setAttribute("errorInfo", "您输入的金额有误!");
            path="/error.jsp";  
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("errorInfo", e.getMessage());
            path="/error.jsp";  
        }
        request.getRequestDispatcher(path).forward(request, response);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

第三步、InAccount.java

package cn.itcast.bean;

public class InAccount {
    private String accountid;
    private double inbalance;
    ……
}

第四步、InAccountService.java

package cn.itcast.service;
public class InAccountService {
    /*
     * 业务层是项目中处理业务的:
     *    *  开发中应该在业务层处理事务
     *    *  开发中应该在业务层获取数据库的连接Connection,传递到dao层
     * 本例中的业务是:
     *    *  存入金额到inaccount表中
     *    *  查询(account)该账号的余额
     *    *  更新(account)中该账号的余额
     *    以上三步操作,要么全部成功,要么全部失败
     */
    public void saveInAccount(InAccount inAccount) {
        DBManager dbManager=null;
        Connection conn=null;
        DaoInAccount daoInAccount=null;
        DaoAccount daoAccount=null;
        Account account=null;
        try {

            // 1.获取连接
            dbManager=DBManager.getDBManager();
            conn=dbManager.getConnection();
            //1.1设置连接的提交方式为非自动提交
            //conn.setAutoCommit(false);
            //优化
            dbManager.beginTransaction(conn);//到DBManager工具类中书写
/*************************业务**************************************/
            //2.存入金额到inaccount表中
            daoInAccount=DaoFactory.getDaoInAccount();
            daoInAccount.saveInAccount(conn,inAccount);
            //3.查询(account)该账号的余额,通过账号id查询
            daoAccount=DaoFactory.getDaoAccount();
            account=new Account();
            //int x=1/0;
            account.setAccountid(inAccount.getAccountid());
            account= daoAccount.find(conn,account);
            //System.out.println(account.getBalance());
            //计算余额
            double balance=inAccount.getInbalance()+account.getBalance();
            account.setBalance(balance);

            //4.更新(account)中该账号的余额
            daoAccount.updateAccount(conn,account);
/***********************************************************************/
            //提交事务
            //conn.commit();
            dbManager.commitTransaction(conn);
        } catch (Exception e) {
            // 所有的底层的异常全部抛到这里,在这里捕获,实现回滚
            e.printStackTrace();
            //回滚事务
            dbManager.rollbackTransaction(conn);
            throw new ServiceException(e.getMessage(),e);

        }finally{

            if(dbManager!=null){
                dbManager.resetTransaction(conn);//很重要,重置为自动提交
                dbManager.closeResource(conn, null, null);
            }
        }
    }
}

第五步、DaoFactory.java

第六步、interface DaoInAccount.java

第七步、DaoInAccountImpl.java

package cn.itcast.dao.impl;
//存款dao抽象层
public class DaoInAccountImpl extends BaseDao implements DaoInAccount{
    //往inaccount表中插入一条数据(存款)
    public void saveInAccount(Connection conn, InAccount inAccount) {
        //1.组织sql语句
        String sql="insert into inaccount(accountid,inbalance) values(?,?)";
        //2.设置参数的值
        Object[] param=new Object[]{inAccount.getAccountid(),inAccount.getInbalance()};
        String errorMessage="存款信息插入失败!";

        //3.调用父类的方法
        //注意下面的方法有抛出异常,运行时异常可以持续抛出,这一层不捕获
        super.update(conn,sql,param,errorMessage);
    }
}

第八步、DaoAccount.java

package cn.itcast.dao;
//对账号表操作的数据访问抽象层
public interface DaoAccount {
    /*
     * 通过账号查询余额,最终封装到javabean
     */
    Account find(Connection conn, Account account);
    /*
     * 通过账号更新账户的余额
     */
    void updateAccount(Connection conn, Account account);
}

InAccount.java

package cn.itcast.bean;
public class InAccount {
    private String accountid;
    private double inbalance;
    ……
}

第九步、DaoAccountImpl.java

package cn.itcast.dao.impl;
public class DaoAccountImpl extends BaseDao implements DaoAccount {
    public Account find(Connection conn, Account account) {
        //0.设置错误信息
        String errorMsg=Constants.DAO_ERROR_QUERYBYID;
        //1.组织sql语句
        String sql="select accountid,balance from account where accountid=?";
        //2.设置参数
        Object[] param=new Object[]{account.getAccountid()};
        //3.调用父类方法
        Class clazz=Account.class;
        account  = (Account)super.findObjectById(conn,sql,param,clazz,errorMsg);
        return account;
    }
    public void updateAccount(Connection conn, Account account) {
        //0.设置错误信息
        String errorMsg=Constants.DAO_ERROR_UPDATEBYID;
        //1.组织sql语句
        String sql="update account set accountid=?,balance=?";
        //2.设置参数
        Object[] param=new Object[]{account.getAccountid(),account.getBalance()};
        //3.调用父类方法
        super.update(conn, sql, param, errorMsg);
    }
    public void saveAccount(Connection conn, Account account) {
        String errorMsg=Constants.DAO_ERROR_INSERTBYID;
        String sql="insert into account(accountid,balance) values(?,?)";
        Object[] param=new Object[]{account.getAccountid(),account.getBalance()};
        super.update(conn, sql, param, errorMsg);
    }
}

第十步、BaseDao.java

package cn.itcast.dao;
public abstract class BaseDao {
    /*
     * 该方法完成对数据库的insert update delete操作
     */
    public void update(Connection conn, String sql, Object[] param,
            String errorMessage) {      
        try {
            QueryRunner query=new QueryRunner();
            query.update(conn, sql, param);
        } catch (SQLException e) {  
            e.printStackTrace();//这一行要写在前面
            throw new DaoException(errorMessage,e);
        }
    }
   //通过id查询账户余额
    public Object findObjectById(Connection conn, String sql, Object[] param,
            Class clazz, String errorMsg) {
        Object obj=null;
        try {
            QueryRunner query=new QueryRunner();
            obj = query.query(conn, sql,new BeanHandler(clazz), param);
        } catch (SQLException e) {  
            e.printStackTrace();//这一行要写在前面
            throw new DaoException(errorMsg,e);
        }
        return obj;
    }
}

开户
第十二步、account.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%>

<html>
  <head>
    <title>开户title>   
  head>
  <body>
    开户:<form action="${pageContext.request.contextPath}/servlet/AccountServlet" method="post">
      账号ID:<input name="accountid" type="text"/><br/>
      <input type="submit" value="保存"/>
    form> 
  body>
html>

第十三步、

package cn.itcast.web;

import java.io.IOException;
public class AccountServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //获取账号id
        String accountid=request.getParameter("accountid");
        AccountService accountService=new AccountService();
        Account account=new Account();
        account.setAccountid(accountid);
        account.setBalance(0.00);
        accountService.saveAccount(account);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

第十四步

package cn.itcast.service;
//管理账号的业务层
public class AccountService {
    public void saveAccount(Account account) {
        DBManager dbManager=null;
        Connection conn=null;
        DaoAccount daoAccount=null;
        try {
            dbManager=DBManager.getDBManager();
            conn=dbManager.getConnection();
            //待用daoAccount的方法
            daoAccount=DaoFactory.getDaoAccount();
            daoAccount.saveAccount(conn,account);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(dbManager!=null){
                dbManager.closeResource(conn, null, null);
            }
        }
    }
}

第十五步DaoAccount.java
第十六步DaoAccountImpl.java

package cn.itcast.dao.impl;
public class DaoAccountImpl extends BaseDao implements DaoAccount {
……
    public void saveAccount(Connection conn, Account account) {
        String errorMsg="创建新账户失败";
        String sql="insert into account(accountid,balance) values(?,?)";
        Object[] param=new Object[]{account.getAccountid(),account.getBalance()};
        super.update(conn, sql, param, errorMsg);
    }
}

总结:
javaWEB开发环境的搭建:
    * 新建一个web工程day20Unit
    * 引入项目所需要的jar包
    javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第2张图片
    * 包的层次关系
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第3张图片
    * 开发jsp页面
    * 常量类
    * 开发servlet
            * 接收jsp的数据封装到javabean
            * 调用业务层
    * 开发业务层
            * 获取Connection
            * 获取dao层的对象(通过工厂)
            * 控制事务
            * 关闭连接
    * 开发dao层
            * 继承BaseDao
            * 实现dao的接口
            * 执行对数据库的操作(insert update delete select)
            * 提供工厂类,用于业务层获取dao抽象接口实现类的对象
    * 异常处理
异常的处理
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第4张图片
异常的分类:
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第5张图片
第一步、
package cn.itcast.exception;
// dao层异常
public class DaoException extends RuntimeException{
// new DBException(“数据库连接异常!”);
public DaoException(String message){
super(message);
}
public DaoException(String message,Throwable cause){
super(message, cause);
}
}
第二步、

package cn.itcast.exception;
/*
 * 处理数据库的异常
 */
public class DBException extends RuntimeException {
    /*
     * new DBException("数据库连接异常!");
     */
    public DBException(String message){
        super(message);
    }
    public DBException(String message,Throwable cause){
        super(message, cause);
    }
}

第三步、

package cn.itcast.exception;
//业务层异常
public class ServiceException extends RuntimeException {
    public ServiceException(String message) {
        super(message);
    }
    public ServiceException(String message,Throwable cause){
        super(message, cause);
    }
}

第四步、

package cn.itcast.test;
import cn.itcast.exception.DaoException;
public class Dao {
    public void a(){
        if(true){
            throw new DaoException("插入数据失败!");
            //在他的上层用e.getMessage则可以打印出"插入数据失败!"
        }
    }
}

第五步、

package cn.itcast.test;
import cn.itcast.exception.ServiceException;
public class Service {
    public void c(){
        Dao dao=new Dao();
        //try {
            dao.a();
        //} catch (Exception e) {
        //  System.out.println("*****************");
        //  e.printStackTrace();
        //  throw new ServiceException("保存数据失败!");
    //  }
    }
}

第六步、

package cn.itcast.test;
public class Test {
    public static void main(String[] args) {
        Service service=new Service();
            try {
                service.c();
            } catch (Exception e) {
                System.out.println("yyyyyyyy"+e.getMessage());
            }
    }
}

运行Test.java则可以看到运行结果:

yyyyyyyy插入数据失败!

日志log4j
第一步、导包 log4j.jar
第二步、
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第6张图片
第三步、
javaee学习之路(二十一)JavaWeb项目实战--银行存款业务_第7张图片
如何使用日志文件:
            引入jar包 log4j-1.2.11.jar
            在类(src)路径下增加log4j.properties文件(文件名不能改)
            在java类中使用

你可能感兴趣的:(JavaEE学习之路,工具,final,数据库,string,异常)