1.数据库
2。项目架构
3.实体类
package com.pn.entity;
public class Account {
/**
* 账号
*/
private String accountid;
/**
* 密码
*/
private String password;
/**
* 余额
*/
private Double money;
public Account() {
}
public Account(String accountid, String password, Double money) {
this.accountid = accountid;
this.password = password;
this.money = money;
}
public String getAccountid() {
return accountid;
}
public void setAccountid(String accountid) {
this.accountid = accountid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
3.dao层(实现登陆接口,和存取款接口)
package com.pn.dao;
import com.pn.entity.Account;
public interface AccountDao {
/**
* 实现页面的登陆
* @param accoundid
* @param pass
* @return
*/
Account login(String accoundid,String passworld);
/**
* 存款取款接口
* @param account
* @return
*/
int update(Account account);
}
package com.pn.dao.impl;
import com.pn.dao.AccountDao;
import com.pn.entity.Account;
import com.pn.utils.DBUtil;
import java.util.List;
public class AccoundDaoImpl implements AccountDao {
@Override
public Account login(String accoundid, String passworld) {
List<Account> list = DBUtil.executeDQL(Account.class, "select * from t_accounts where accountid=? and password=? ", accoundid, passworld);
if (list.size() > 0) {
/*如果有元素则获取第一个元素*/
return list.get(0);
}
return null;
}
/**
* 这里的money=money+是因为单选框里面的value值是-1和1,取款则加上一个负值,存款则加上一个正值
* 存取款
* @param account
* @return
*/
@Override
public int update(Account account) {
int i = DBUtil.executeDML("update t_accounts set money=money+? where accountid=?", account.getMoney(), account.getAccountid());
return i;
}
}
4.登陆控制器
package com.pn.servlet;
import com.google.gson.Gson;
import com.pn.dao.AccountDao;
import com.pn.dao.impl.AccoundDaoImpl;
import com.pn.entity.Account;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 登陆控制器
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*从页面上接受两个值id和密码*/
/*账号*/
String accountid = request.getParameter("accountid");
/*密码*/
String password = request.getParameter("password");
AccountDao accountDao = new AccoundDaoImpl();
Account ac = accountDao.login(accountid, password);
/*创建JSON对象将对象解析为字符串发送给页面*/
Gson gson = new Gson();
String json = gson.toJson(ac);
/*判断账号密码是否为空*/
if(ac!=null){
response.getWriter().print(json);
}else {
response.getWriter().print("error");
}
}
}
5.简易的登陆页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var xmlhttp;
function createXMLHttp() {
if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
xmlhttp = new XMLHttpRequest();
}
}
function login() {
/*获取输入框中的值账号和密码*/
var accountid = document.getElementById("accountid").value;
var password = document.getElementById("password").value;
createXMLHttp();
xmlhttp.open("POST", "LoginServlet", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
/*将获取到的账号和密码发送给服务器*/
xmlhttp.send("accountid=" + accountid + "&password=" + password);
xmlhttp.onreadystatechange = callback;/*回调函数*/
}
function callback() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
/*接受服务的数据*/
var data = xmlhttp.responseText;
/*对数据进行判断*/
if (data == "error") {
alert("账号或密码错误")
}else{
/*将数据保存传入到下一个页面index.html*/
/*这个data不用转化为字符串,因为登陆服务器已经将数据解析为字符串*/
sessionStorage.setItem("data",data)
/*将数据保存之后跳转到下个页面index.html*/
location.href="index.html";
}
}
}
</script>
</head>
<body>
<h1>自动存款系统</h1>
账号:<input type="text" id="accountid"><br>
密码:<input type="password" id="password">
<input type="button" value="登录" onclick="login()">
</body>
</html>
6.存取数据库
package com.pn.servlet;
import com.google.gson.Gson;
import com.pn.dao.AccountDao;
import com.pn.dao.impl.AccoundDaoImpl;
import com.pn.entity.Account;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*存取款控制器*/
@WebServlet("/SavaServlet")
public class SavaServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*获取页面的json数据*/
String json = request.getParameter("json");
Gson gson = new Gson();
/*将接受的字符串转化为JSON对象*/
Account account = gson.fromJson(json, Account.class);
AccountDao accountDao = new AccoundDaoImpl();
int update = accountDao.update(account);
if(update>0){
response.getWriter().print("success");
}else {
response.getWriter().print("error");
}
}
}
7.首页
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎来到自助存款机系统</h1>
当前账号:<span id="accountid"></span>    
余额:<span id="balance"></span><br>
交易类型:<input type="radio" name="type" value="1" checked>存款
<input type="radio" name="type" value="-1">取款<br/>
金额:<input type="text" id="money">元<br>
<input type="button" value="提交" onclick="save()">
</body>
<script>
/*将脚本写在下面是为了获取到name属性,因为前端js页面执行是从上往下执行的*/
/*现获取登陆页面的数据*/
/*将登陆页面的字符串转化为对象方便操作*/
/*这里的key对应的是login页面保存的setItem的key相对应*/
var ac = JSON.parse(sessionStorage.getItem("data"));
/*将登录的账号和余额显示到当前页面*/
document.getElementById("accountid").innerText = ac.accountid;
document.getElementById("balance").innerText = ac.money;
var xmlhttp;
function createXMLHttp() {
if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
xmlhttp = new XMLHttpRequest();
}
}
function save() {
var type;
/*通过getElementsByName获取input框中的选项,这里拿到的是全部的的选项*/
var radios = document.getElementsByName('type');
if (radios[0].checked) {/*如果选中的下标是0号元素(存款)将1赋值给type,反之(取款)-1*/
type = 1;
} else {
type = -1;
}
/*获取输入框中的金额*/
var money = document.getElementById("money").value;
if (type == -1) {/*取款*/
/*将金额和余额进行对比,金额大于余额则余额不足*/
if (money > ac.money) {
alert("对不起,余额不足");
return;
}
}
/*ajax*/
var account = {
accountid: ac.accountid,
/*这里的type是获取是否存取款的值(1或-1),这里的money是输入框里面你需要存取的金额*/
money: type * money
}
createXMLHttp();
xmlhttp.open("POST", "SavaServlet", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
/*将account对象转化为字符串发送给服务器(控制器)*/
xmlhttp.send("json=" + JSON.stringify(account));
xmlhttp.onreadystatechange = callback;/*回调函数*/
}
function callback() {
var input="";
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
/*接受服务器发送过来的数据*/
var data = xmlhttp.responseText;
if (data == "success") {
alert("交易成功");
/*交易采购或失败清空输入框*/
document.getElementById("money").value=input;
} else {
alert("交易失败");
document.getElementById("money").value=input;
}
}
}
</script>
</html>
8.连接数据库的工具类
package com.pn.utils;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/*定义数据库操作的工具类*/
public class DBUtil {
/*静态代码块加载db.properties文件*/
static Properties properties=null;
static{
//获得db.properties流对象
InputStream is = DBUtil.class.getClassLoader()
.getResourceAsStream("db.properties");
properties=new Properties();
//加载键值对文件
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
}
/*建立数据库连接*/
public static Connection getConn(){
try{
Class.forName(properties.getProperty("jdbc.driver"));
Connection conn = DriverManager.getConnection(
properties.getProperty("jdbc.url"),
properties.getProperty("jdbc.user"),
properties.getProperty("jdbc.pwd")
);
return conn;
}catch(Exception ex){
ex.printStackTrace();
}
return null;
}
/*执行DML语句
* sql 需要执行的sql语句
* params 需要给sql语句占位符赋的值
* 返回值:int 受影响的行数
* */
public static int executeDML(String sql,Object ... params){
//调用方法连接数据库
Connection conn=null;
PreparedStatement pstat=null;
try{
conn = getConn();
if(conn!=null){
//创建PreparedStatement对象
pstat = conn.prepareStatement(sql);
//给预编译的sql语句?号赋值
if(params!=null && params.length!=0){
//变量保存占位符参数的数组
for(int x=0;x<params.length;x++){
pstat.setObject(x+1,params[x]);
}
}
//执行sql
int row = pstat.executeUpdate();
return row;
}
}catch(Exception ex){
ex.printStackTrace();
}finally {
try{
pstat.close();
conn.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
return 0;
}
/*执行DQL语句*/
public static <T> List<T> executeDQL(Class<T> clz,String sql,Object ... params){
List<T> result=new ArrayList<>();
//调用方法连接数据库
Connection conn=null;
PreparedStatement pstat=null;
ResultSet res=null;
try {
conn = getConn();
if (conn != null) {
//创建PreparedStatement对象
pstat = conn.prepareStatement(sql);
//给预编译的sql语句?号赋值
if (params != null && params.length != 0) {
//变量保存占位符参数的数组
for (int x = 0; x < params.length; x++) {
pstat.setObject(x + 1, params[x]);
}
}
//执行sql,返回ResultSet结果集
res = pstat.executeQuery();
//获得res封装的虚拟表结构,rsmd对象中封装了虚拟表结构
//(1 有几列 2 每列的名字 3 每类的数据类型)
ResultSetMetaData rsmd = res.getMetaData();
//获得表中列的个数
int count = rsmd.getColumnCount();
//System.out.println("count="+count);
//遍历res结果
while(res.next()){
//1 创建对象(某个实体类的对象)
T o = clz.getConstructor().newInstance();
//2 对象属性赋值
//2.1 给几个属性赋值,由select语句产生虚拟表中的列的个数确定
for(int x=1;x<=count;x++){//循环给count个属性赋值
//2.2 给名字为什么的属性赋值,由select语句产生的虚拟表中的列名确定
//获得某个列的名字和数据类型(java中的数据类型的完全限定名)
String columnName = rsmd.getColumnName(x);
String columnType = rsmd.getColumnClassName(x);
//rsmd.getColumnTypeName()
//System.out.println(columnName+"\t"+columnType);
//通过列明拼接属性的setXxx方法名字
String setXxx="set"+columnName.substring(0,1).toUpperCase()+
columnName.substring(1);
//通过反射获得setXxx对应Method对象
Method method = clz.getMethod(setXxx, Class.forName(columnType));
//调用method方法,完成属性赋值
method.invoke(o,res.getObject(x));
}
//3 对象添加到list集合
result.add(o);
}
}
}catch(Exception ex){
ex.printStackTrace();
}finally {
try{
res.close();
pstat.close();
conn.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
return result;
}
}
9.前端页面之间传递数据使用的是:
(1.)简单的参数可以通过“?”进行传递
a页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var name="zhangsan";
function send() {
location.href="b.html?name="+name;
}
</script>
</head>
<body>
<h1>简单的参数可以通过?进行传递</h1>
<a href="javascript:send()">通过?实现两个前端页面之间的传参</a>
</body>
</html>
b页面:location.search作用:获取当前访问页面URL地址中“?”后面的参数
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function show() {
/*用=进行分割获取下标为1的元素值*/
/*window.location.search的作用为:获取当前访问页面的 URL地址中 " ?" 后边的参数数据*/
var name=location.search.split("=")[1];
/*将a页面获取到的值传入到b的div中*/
document.getElementById("show").innerText=name
}
</script>
</head>
<body onload="show()">
<div id="show">
</div>
</body>
</html>
(2.)sessionStorage用于前端页面的数据共享,适合传递JSON
k和v都是字符串形式
存:sessionStorage.setItem(k,v)
取:sessionStorage.setItem(k,v)
将存好的数据使用location.href进行跳转
c页面传数据到d页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var stu={
sname:'小米',
age:26,
birth:'2000-1-1'
};
function send() {
/*setItem里面的两个值都是字符串形式的*/
sessionStorage.setItem("stu",JSON.stringify(stu));
/*将数据传入到d页面*/
location.href="d.html";
}
</script>
</head>
<body>
<h2>key和value都是String类型</h2>
<h2>sessionStorage.setItem(key,value)存数据</h2>
<h2>sessionStorage.getItem(key,value)取数据</h2>
<h1>sessionStorage用于在前端页面直接共享数据,适合传递JSON对象</h1>
<a href="javascript:send()">超链接传入到d页面</a>
</body>
</html>
d页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function show() {
/*接受将c中存入的数据,通过json将字符串转化为对象*/
var stu=JSON.parse(sessionStorage.getItem("stu"));
document.getElementById("show").innerText=stu.sname;
}
</script>
</head>
<body onload="show()">
<div id="show"></div>
</body>
</html>