目录

​一、数据库​

​二、实体类(POJO类)​

​用户类:​

​PageBean类:​

​交易明细类:​

​三、DAO层​

​四、Servlet层​

 ​



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

Jsp+Servlet+JDBC实现ATM机系统_JavaWeb

直接上效果图,

Jsp+Servlet+JDBC实现ATM机系统_JavaWeb_02

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

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

Jsp+Servlet+JDBC实现ATM机系统_Servlet_03


里面得功能先不一一展示了,这里面的功能都有,就是界面有点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<T> {
//已知数据
private int pageNum; //当前页,从请求那边传过来。
private int pageSize; //每页显示的数据条数。
private int totalRecord; //总的记录条数。查询数据库得到的数据

//需要计算得来
private int totalPage; //总页数,通过totalRecord和pageSize计算可以得来
//开始索引,也就是我们在数据库中要从第几行数据开始拿,有了startIndex和pageSize,
//就知道了limit语句的两个数据,就能获得每页需要显示的数据了
private int startIndex;


//将每页要显示的数据放在list集合中
private List<T> 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;
}
}
}
}


 ​


交易明细类:

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<RunMessage> SelMessage(String ICNo);
/**
* 查询所有数据
* @return
*/
public List<RunMessage> 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<RunMessage> SelMessage(String ICNo) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<RunMessage> list = new ArrayList<RunMessage>();
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<com.atm.pojo.RunMessage> finAllMessage(String ICno, int pageNum, int pageSize) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<RunMessage> list = new ArrayList<RunMessage>();
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机系统_JavaWeb_04这么多个,包括了管理员部分的。