Jsp+Servlet+JDBC实现ATM机系统

目录

一、数据库

二、实体类(POJO类)

用户类:

PageBean类:

交易明细类:

三、DAO层

四、Servlet层

有问题可以加企鹅一起交流:1169213632~


   

   伴随着课程设计结束,假期也随之来临,嘿嘿,这次我跟我的小伙伴们做的是一个简易版的ATM机系统,虽然相貌平平,可是还是考虑了很多因素在里面,因为我们都是JavaWeb的初学者,所以肯定在性能和安全性等会有很大的缺陷,请大家根据自己的需要选择性观看,本来早就应该写这篇博客了,可是放假太懒玩儿了几天。。前端页面队友没找好,我是负责功能实现的,所以大家不要喷我,主要还是看功能实现,本篇博客仅供参考,也是自己两周课设的总结。

Jsp+Servlet+JDBC实现ATM机系统_第1张图片

直接上效果图,

这是登录界面,包括两种身份的登录。。我知道比较简陋,用户界面和管理员界面放在一起,这样设计很不靠谱,但是没办法,前端给我的就是这样,队友没有会前端的,都是网上copy的模板。。

输入测试用户名和密码,进入登录界面:

Jsp+Servlet+JDBC实现ATM机系统_第2张图片

 

里面得功能先不一一展示了,这里面的功能都有,就是界面有点low。。不过我们也实在搞不到更好看的页面了。。

(管理员界面只有增删改查没什么展示的,所以只给大家看用户界面。这里面最难的功能我感觉是交易明细,因为要实现分页功能,做完感觉很爽)

数据库方面只有两个2表,一个是用户信息表,另外一个是交易明细表,当初设计数据库时想将两个表连起来,就是把卡号作为主键,可是后来嫌麻烦,就没用这种方法,同样实现了所有功能,hiahia~

一、数据库

User表中有卡号、姓名、密码、电话、身份证、账户余额这六个属性:

CREATE TABLE `user` (
  `ICno` varchar(19) NOT NULL COMMENT '银行卡号',
  `name` varchar(20) NOT NULL COMMENT '账户名',
  `pwd` varchar(6) NOT NULL COMMENT '账户密码',
  `mobile` char(11) NOT NULL COMMENT '电话号码',
  `IDcard` varchar(18) NOT NULL COMMENT '身份证号',
  `balance` double NOT NULL COMMENT '账户余额',
  PRIMARY KEY (`ICno`),
  UNIQUE KEY `ICno` (`ICno`),
  KEY `balance` (`balance`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

交易明细表中有账户编号、银行卡号、交易日期、货币类型、交易金额、交易后的账户余额这六个属性

CREATE TABLE `runmessage` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `ICno` varchar(18) DEFAULT NULL,
  `RM_date` varchar(50) DEFAULT NULL,
  `RM_Currency` varchar(15) DEFAULT NULL,
  `RM_Balance` double DEFAULT NULL,
  `RM_Rest` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8;

二、实体类(POJO类)

实体类共有三个,分别是用户类、分页的PageBean类交易明细类

给大家看一下属性,剩下的get、set方法篇幅过长就不展示了:

用户类:

package com.atm.pojo;

public class BeanUserAccount {

	private String ICNo;//卡号
	private String name;//账户名
	private String pwd;//账户密码
	private String mobile;//电话号码
	private String IDCard;//身份证号
	private double balance;//余额
	private double saveNum;//存钱数
	private double fetchNum;//取钱数

}

PageBean类:

package com.atm.pojo;

import java.util.List;

public class PageBean {
	//已知数据
    private int pageNum;    //当前页,从请求那边传过来。
    private int pageSize;    //每页显示的数据条数。
    private int totalRecord;    //总的记录条数。查询数据库得到的数据
    
    //需要计算得来
    private int totalPage;    //总页数,通过totalRecord和pageSize计算可以得来
    //开始索引,也就是我们在数据库中要从第几行数据开始拿,有了startIndex和pageSize,
    //就知道了limit语句的两个数据,就能获得每页需要显示的数据了
    private int startIndex;        
        
    
    //将每页要显示的数据放在list集合中
    private List list;
    
    //分页显示的页数,比如在页面上显示1,2,3,4,5页,start就为1,end就为5,这个也是算过来的
    private int start;
    private int end;
    
    //通过pageNum,pageSize,totalRecord计算得来tatalPage和startIndex
    //构造方法中将pageNum,pageSize,totalRecord获得
    public PageBean(int pageNum,int pageSize,int totalRecord) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        
        //totalPage 总页数
        if(totalRecord%pageSize==0){
            //说明整除,正好每页显示pageSize条数据,没有多余一页要显示少于pageSize条数据的
            this.totalPage = totalRecord / pageSize;
        }else{
            //不整除,就要在加一页,来显示多余的数据。
            this.totalPage = totalRecord / pageSize +1;
        }
        //开始索引
        this.startIndex = (pageNum-1)*pageSize ;
        //显示5页,这里自己可以设置,想显示几页就自己通过下面算法修改
        this.start = 1;
        this.end = 5;
        //显示页数的算法
        if(totalPage <=5){
            //总页数都小于5,那么end就为总页数的值了。
            this.end = this.totalPage;
        }else{
            //总页数大于5,那么就要根据当前是第几页,来判断start和end为多少了,
            this.start = pageNum - 2;
            this.end = pageNum + 2;
            
            if(start <= 0){
                //比如当前页是第1页,或者第2页,那么就不如和这个规则,
                this.start = 1;
                this.end = 5;
            }
            if(end >= this.totalPage){
                //比如当前页是倒数第2页或者最后一页,也同样不符合上面这个规则
                this.end = totalPage;
                this.start = end - 4;
            }
        }
    }
}

分页功能参考了网上一位大佬的代码,我又进行了一些修改,链接是:https://www.cnblogs.com/whgk/p/6474396.html

交易明细类:

package com.atm.pojo;

import java.util.Date;

public class RunMessage {
	private String ICno;//卡号
	private String RM_date;//交易日期
	private String RM_Currency;//货币类型
	private double RM_Balance;//账户余额
	private double RM_Rest;//交易后余额
}

三、DAO层

dao层中 ,我设置了几个状态码,分别是更改密码成功(HANGE_PASSWORD_SUCCESS)、更改密码失败(CHANGE_PASSWORD_FALSE)、修改成功(UPDATE_SUCCESS)、修改失败(UPDATE_FALSE)、登录失败(LOGIN_FALSE)、查询失败(ERCH_FALSE)、余额不足(BALANCE_NOT_ENOUGH)、转账成功(TRANSFER_SUCCESS)

、转账失败(TRANSFER_FALSE)

还有用户拥有的功能,分别是校验用户登录、更改密码、查询余额、存款、取款、转账、查询交易明细、查询密码、获取流水账信息、获取所有数据,代码如下:

package com.atm.dao;

import java.util.List;

import com.atm.pojo.BeanUserAccount;
import com.atm.pojo.PageBean;
import com.atm.pojo.RunMessage;

public interface BeanUserDao {
	/**
	 * 更改密码成功
	 */
	int CHANGE_PASSWORD_SUCCESS = 1;
	/**
	 * 更改密码失败
	 */
	int CHANGE_PASSWORD_FALSE = 2;
	/**
	 * 修改成功
	 */
	int UPDATE_SUCCESS = 3;
	/**
	 * 修改失败
	 */
	int UPDATE_FALSE = -4;
	/**
	 * 登录失败
	 */
	BeanUserAccount LOGIN_FALSE = null;
	/**
	 * 查询失败
	 */
	int SERCH_FALSE = 5;
	/**
	 * 余额不足
	 */
	int BALANCE_NOT_ENOUGH = 6;
	/**
	 * 转账成功
	 */
	int TRANSFER_SUCCESS = 7;
	/**
	 * 转账失败
	 */
	int TRANSFER_FALSE = 8;
	/**
	 * 登录功能
	 * @param ICNo 卡号
	 * @param pwd	密码
	 * @return	返回值为UserAccount类型
	 */
	public BeanUserAccount checkLogin(String ICNo, String pwd);
	/**
	 * 改密码功能
	 * @param ICNo	卡号
	 * @return	
	 */
	public int changePwd(String ICNo,String newPwd);
	/**
	 * 查询余额功能
	 * @param ICNo	卡号
	 * @return
	 */
	public double serchBalance(String ICNo);
	/**
	 * 存钱功能
	 * @param ICNo	卡号
	 * @param MoneyNum	要存多少钱
	 * @return
	 */
	public int saveMoney(String ICNo, int MoneyNum);
	/**
	 * 取钱功能
	 * @param ICNo	卡号
	 * @param MoneyNum	取钱的数字
	 * @return
	 */
	public int fetchMoney(String ICNo, int MoneyNum);
	/**
	 * 转账功能
	 * @param transferOut	转出账号
	 * @param transferIn	转入账号
	 * @param MoneyNum	转多少钱的数字
	 * @return
	 */
	public int transfer(String transferOut, String transferIn, double MoneyNum);
	/**
	 * 明细流入金额功能
	 * @param ICNo	卡号
	 * @return
	 */
	public double DetailIn(String ICNo,double Num);
	/**
	 * 明细流出功能
	 * @param ICNo
	 * @param Num
	 * @return
	 */
	public double DetailOut(String ICNo,double Num);
	/**
	 * 查询明细功能
	 * @param ICNo
	 * @return
	 */
	public BeanUserAccount SerchDetaile(String ICNo);
	/**
	 * 查询密码
	 */
	public BeanUserAccount SerchPwd(String ICNo);
	/**
	 * 退卡功能
	 * @return
	 */
	public int quit();
	/**
	 * 插入流水账信息
	 * @param rm
	 * @return
	 */
	public int RunMessage(RunMessage rm);
	/**
	 * 获取流水账信息
	 * @param ICNo
	 * @return
	 */
	public List SelMessage(String ICNo);
	/**
	 * 查询所有数据
	 * @return
	 */
	public List finAllMessage(String ICno, int pageNum, int pageSize);
}

实现代码:

package com.atm.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.atm.dao.BeanUserDao;
import com.atm.pojo.BeanUserAccount;
import com.atm.pojo.PageBean;
import com.atm.pojo.RunMessage;
import com.atm.utils.DBUtils;

public class BeanUserDaoImpl implements BeanUserDao{

	@Override
	public BeanUserAccount checkLogin(String ICNo, String pwd) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("select * from user where ICNo = ? and pwd = ?");
			ps.setString(1, ICNo);
			ps.setString(2, pwd);
			rs = ps.executeQuery();
			BeanUserAccount ua = null;
			if(rs.next()) {
				ua = new BeanUserAccount();
				ua.setICNo(rs.getString("ICNo"));
				ua.setName(rs.getString("name"));
				ua.setPwd(rs.getString("pwd"));
				ua.setMobile(rs.getString("mobile"));
				ua.setIDCard(rs.getString("IDCard"));
				return ua;
			}
			return LOGIN_FALSE;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, rs);
		return LOGIN_FALSE;
	}

	@Override
	public int changePwd(String ICNo,String newPwd) {
		Connection conn = null;
		PreparedStatement ps = null;
		
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("update user set pwd = ? where ICNo = ?");
			ps.setString(1, newPwd);
			ps.setString(2, ICNo);
			int index = ps.executeUpdate();
			if(index > 0) {
				return CHANGE_PASSWORD_SUCCESS;
			}else {
				return CHANGE_PASSWORD_FALSE;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return CHANGE_PASSWORD_FALSE;
	}

	@Override
	public double serchBalance(String ICNo) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("select balance from user where ICNo = ?");
			ps.setString(1, ICNo);
			rs = ps.executeQuery();
			if(rs.next()) {
				BeanUserAccount ua = new BeanUserAccount();
				ua.setBalance(rs.getDouble("balance"));
				double num = ua.getBalance();
				return num;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, rs);
		return SERCH_FALSE;
	}

	@Override
	public int saveMoney(String ICNo, int MoneyNum) {
		Connection conn = null;
		PreparedStatement ps = null;
		int index = 0;
		try {
			conn = DBUtils.getConn();
			conn.setAutoCommit(false);
			ps = conn.prepareStatement("update user set balance=balance+? where ICNo=?");
			ps.setInt(1, MoneyNum);
			ps.setString(2, ICNo);
			if(MoneyNum<=2000) {
				index = ps.executeUpdate();
			}
			if(index>0) {
				conn.commit();
				return UPDATE_SUCCESS;
			}else {
				conn.rollback();
				return UPDATE_FALSE;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return UPDATE_FALSE;
	}

	@Override
	public int fetchMoney(String ICNo, int MoneyNum) {
		Connection conn = null;
		PreparedStatement ps = null;
		int index = 0;
		try {
			conn = DBUtils.getConn();
			conn.setAutoCommit(false);
			ps = conn.prepareStatement("update user set balance=balance-? where ICNo=?");
			ps.setInt(1, MoneyNum);
			ps.setString(2, ICNo);
			if(serchBalance(ICNo)-MoneyNum>0) {
				index = ps.executeUpdate();
				conn.commit();
			}
			if(index>0) {
				conn.rollback();
				return UPDATE_SUCCESS;
			}else if(MoneyNum>2000) {
				conn.rollback();
				return UPDATE_FALSE;
			}else {
				conn.rollback();
				return UPDATE_FALSE;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return UPDATE_FALSE;
	}
/**
 * 如果
 * ps = conn.prepareStatement("update user set balance=balance+? where ICNo=?");
				ps.setInt(1, MoneyNum);
				ps.setString(2, transferIn);
				ps1 = conn.prepareStatement("update user set balance=balance-? where ICNo=?");
				ps.executeUpdate();
				ps.setInt(1, MoneyNum);
				ps.setString(2, transferOut);
				ps1.executeUpdate();
				应该是ps2.executeUpdate();否则会
导致No value specified for parameter 1,愚蠢的错误。。
 */
	@Override
	public int transfer(String transferOut, String transferIn, double MoneyNum) {
		Connection conn = null;
		PreparedStatement ps = null;
		PreparedStatement ps1 = null;
		try {
			conn = DBUtils.getConn();
			conn.setAutoCommit(false);
			if(serchBalance(transferOut)>=MoneyNum) {
				ps = conn.prepareStatement("update user set balance=balance+? where ICNo=?");
				ps.setDouble(1, MoneyNum);
				ps.setString(2, transferIn);
				ps1 = conn.prepareStatement("update user set balance=balance-? where ICNo=?");
				ps1.setDouble(1, MoneyNum);
				ps1.setString(2, transferOut);
				ps.executeUpdate();
				ps1.executeUpdate();
				conn.commit();
				return TRANSFER_SUCCESS;
			}else {
				conn.rollback();
				return TRANSFER_FALSE;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		try {
			ps1.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return TRANSFER_FALSE;
	}


	@Override
	public int quit() {
		return 0;
	}

	@Override
	/**
	 * 转入交易明细
	 */
	public double DetailIn(String ICNo, double Num) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("update user set saveNum = saveNum+? where icno = ?");
			ps.setObject(1, Num);
			ps.setString(2, ICNo);
			int index = ps.executeUpdate();
			if(index>0) {
				return UPDATE_SUCCESS;
			}else {
				return UPDATE_FALSE;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return 0;
	}
	/**
	 * 转出交易明细
	 */
	@Override
	public double DetailOut(String ICNo, double Num) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("update user set fetchNum = fetchNum+? where icno = ?");
			ps.setObject(1, Num);
			ps.setString(2, ICNo);
			int index = ps.executeUpdate();
			if(index>0) {
				return UPDATE_SUCCESS;
			}else {
				return UPDATE_FALSE;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return 0;
	}
	/**
	 * 查询交易明细
	 */
	@Override
	public BeanUserAccount SerchDetaile(String ICNo) {
		Connection conn = null;
		PreparedStatement ps = null;
		BeanUserAccount dt = new BeanUserAccount();
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("select * from user where ICNo = ?");
			ps.setString(1, ICNo);
			ResultSet rs = ps.executeQuery();
			if(rs.next()) {
				dt.setFetchNum(rs.getDouble("fetchNum"));
				dt.setSaveNum(rs.getDouble("saveNum"));
				return dt;
			}else {
				return null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return null;
	}

	public BeanUserAccount SerchPwd(String ICNo) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("select pwd from user where ICNo = ?");
			ps.setString(1, ICNo);
			rs = ps.executeQuery();
			if(rs.next()) {
				BeanUserAccount bua = new BeanUserAccount();
				bua.setPwd(rs.getString("pwd"));
				return bua;
			}else {
				return null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, rs);
		return null;
	}
/**
 * 流水账信息
 */
	@Override
	public int RunMessage(RunMessage rm) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			RunMessage rms = new RunMessage();
			conn = DBUtils.getConn();
			ps = conn.prepareStatement("insert into runmessage values(default,?,?,?,?,?)");
			 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			ps.setString(1, rm.getICno());
			ps.setString(2, df.format(new Date()));
			ps.setString(3, "人民币");
			ps.setDouble(4, rm.getRM_Balance());
			ps.setDouble(5, rm.getRM_Rest());
			int result = ps.executeUpdate();
			
			if(result>0) {
				return UPDATE_SUCCESS; 
			}else {
				return UPDATE_FALSE;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		DBUtils.close(conn, ps, null);
		return UPDATE_FALSE;
	}
	
	public List SelMessage(String ICNo) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List list = new ArrayList();
		try {
			conn = DBUtils.getConn();
			RunMessage rms = null;
			ps = conn.prepareStatement("select * from runmessage where ICno = ?");
			ps.setString(1, ICNo);
			rs = ps.executeQuery();
			while(rs.next()) {
				rms = new RunMessage();
				rms.setICno(rs.getString("ICno"));
				rms.setRM_date(rs.getString("RM_date"));
				rms.setRM_Currency(rs.getString("RM_Currency"));
				rms.setRM_Balance(rs.getDouble("RM_Balance"));
				rms.setRM_Rest(rs.getDouble("Rm_Rest"));
				
				list.add(rms);
			}
//			for(Object ob: list) {
//				System.out.println(ob);
//			}
			DBUtils.close(conn, ps, rs);
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List finAllMessage(String ICno, int pageNum, int pageSize) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List list = new ArrayList();
		try {
			conn = DBUtils.getConn();
			RunMessage rms = null;
			ps = conn.prepareStatement("select * from runmessage where ICno=? limit ?,?");
			ps.setString(1, ICno);
			ps.setObject(2, (pageNum-1)*pageSize);
			ps.setObject(3, pageSize);
			rs = ps.executeQuery();
			while(rs.next()) {
				rms = new RunMessage();
				rms.setICno(rs.getString("ICno"));
				rms.setRM_date(rs.getString("RM_date"));
				rms.setRM_Currency(rs.getString("RM_Currency"));
				rms.setRM_Balance(rs.getDouble("RM_Balance"));
				rms.setRM_Rest(rs.getDouble("Rm_Rest"));
				list.add(rms);
			}
			DBUtils.close(conn, ps, rs);
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}




	
}

四、Servlet层

这里的代码不一一展示了,总共有Jsp+Servlet+JDBC实现ATM机系统_第3张图片这么多个,包括了管理员部分的。

源码有需要的可以下载:https://download.csdn.net/download/u011679785/10935133

有问题可以加企鹅一起交流:1169213632~

加我QQ

 

 

 

 

 

 

 

你可能感兴趣的