用到的技术:
前端:
jquery=$ 【点击事件、获取父标签的第n个子标签中 文本内容】
bootstrap
ajax的post【each方法遍历json数组取 属性值】
字符串拼接展现table
el表达式
输入弹框
后端:
template查询数据库
servlet返回数据给ajax原页面
servlet中用JSONArray的方法转json数组
pom.xml 需要的依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 导入spring依赖 此处没有用spring框架没有bean.xml注入
但依旧需要template等 需要其中依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
<!-- 实体类中@entity @table-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<!-- 实体类中@getter @setter @tostring -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 使DataSource可以seturl等 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- jquery-->
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<!--JSONArray.fromObject(..)-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
</dependencies>
一.我的目录结构
二.前端页面
1、top.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--此标题用来加在多个页面顶部--%>
<div style="margin-top: 160px">
<h1 style="text-align: center">Mini Shop(๑′ᴗ‵๑)❤</h1>
</div>
</body>
</html>
2、index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<style>
a{
text-decoration: none;
color: white;
}
</style>
</head>
<body>
<%--引入顶部页面--%>
<jsp:include page="top.jsp"></jsp:include>
<%--验证 用户登录 --%>
<%--此处省略验证 直接跳转到功能页--%>
<form style="text-align: center;margin-top: 20px" action="userPage.jsp">
账户<input type="text" name="loginname" placeholder="输入用户名or手机号"><br/>
密码<input type="password" name="pwd"><br/>
<a href="userregist.jsp" style="color: darkorchid">点击注册</a>
<input style="margin-top: 20px" type="submit" value="go!">
</form>
<div style="text-align: center;margin-top: 50px">
<button type="button" class="btn btn-info" style="margin-right: 50px"><a href="maPage.jsp">我是管理员</a></button>
<button type="button" class="btn btn-warning"><a href="">我是商家</a></button>
</div>
</body>
</html>
3、maPage.jsp
此中的$.each 用法详解:
(可用于
被JSONArray的List<实体类>、
List<马普>常见于自制多表rowmapper)
/**
var arr2=[['aaa','bbb'],['ccc','ddd'],['eee','fff']];
$.each(arr2,function(i,item){
//两个参数,第一个参数表示下标,第二个参数表示一维数组中的每一个数组
console.log(i+'````'+item);
输出的结果为:
0````aaa,bbb
1````ccc,ddd
2````eee,fff
*/
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<html lang="zh-CN">
<head>
<%-- 引入maven中的 jquery--%>
<script src="webjars/jquery/3.4.1/dist/jquery.min.js" charset="UTF-8"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script>
//页面加载完成后执行
$(function() {
/* 关于$的一些坑:
jQuery on()方法是官方推荐的绑定事件的一个方法。
使用 on() 方法可以给将来动态创建的动态元素绑定指定的事件,例如append等。
$(".btn").on("click",function () {...}
以上代码执行时,点击.btn时,alert一直没反应,
因为:
on前面的元素也必须在页面加载的时候就存在于dom里面,
动态的元素 或者 样式 等,可以放在on的第2个参数里面。
*/
$("body").on("click","input",function () {//为每1个input按钮标签 绑定此触发函数
var thisbtn = $(this).attr("value");
console.log(thisbtn);
//功能1返回值是List<Map> 功能2、3是List<对象> 都遍历1次后靠键 取值
if(thisbtn=="用户管理"){
showUsers();
}
else if(thisbtn=="商家管理"){
showsupers();
}
else if(thisbtn=="订单管理"){
//略
}
})
/*
用户管理功能
1.用ajax的post 向后端Maserv请求
2.是哪个功能在service层判断
*/
function showUsers() {
console.log("进入showusers方法");
$.post("maserv","btnname=users",callback,"JSON");//指定返回值为 json、响应的在后端也要转为json字符串
function callback(jsonlist) {
//功能1返回值 原本是List<Map> 后已被转为 json数组 [{对象属性:对象数组},...]
// 用$.each 遍历二维数组的形式 实现:
//加入到页面 表格中 拼接
var mytable="";
mytable+="<table class='table table-condensed'><tr><td>顾客姓名</td><td>电话</td><td>密码</td><td>超市卡余额</td><td>年龄</td><td>性别</td><td>住址</td></tr>";
$.each(jsonlist,function (index,amap) {//此时amap已被后端转为 json对象{属性:属性值}
mytable+="<tr>";
mytable+="<td>"+amap.personname+"</td>";
mytable+="<td>"+amap.tel+"</td>";
mytable+="<td>"+amap.password+"</td>";
mytable+="<td>"+amap.money+"</td>";
mytable+="<td>"+amap.age+"</td>";
mytable+="<td>"+amap.sex+"</td>";
mytable+="<td>"+amap.address+"</td>";
mytable+="</tr>";
});
mytable+="</table>";
$(".showtable").html(mytable);
}
}
/**功能2
* 商家管理 遍历1遍即可
*/
function showsupers() {
$.post("maserv","btnname=supers",callback,"JSON");
function callback(jsonlist) {
var mytable="";
mytable+="<table class='table table-condensed'><tr><td>超市id</td><td>超市名字</td><td>超市电话</td><td>超市密码</td><td>超市余额</td><td>角色</td></tr>";
$.each(jsonlist,function (index,asuper) {//此时amap已被后端转为 json对象{属性:属性值}
mytable+="<tr>";
mytable+="<td>"+asuper.personId+"</td>";
mytable+="<td>"+asuper.personName+"</td>";
mytable+="<td>"+asuper.tel+"</td>";
mytable+="<td>"+asuper.password+"</td>";
mytable+="<td>"+asuper.money+"</td>";
mytable+="<td>"+asuper.role+"</td>";
mytable+="</tr>";
});
mytable+="</table>";
$(".showtable").html(mytable);
}
}
});
</script>
<title>管理员页面</title>
<style>
<%--消除默认白边 并没有消坨--%>
/**{*/
/* margin: 0;*/
/* padding: 0;*/
/*}*/
.big{
width: 80%;
height: 100%;
background-color: aliceblue;
<%--实现此div水平居中--%>
text-align: center;
margin:0 auto;
}
</style>
</head>
<body>
<div class="big">
<div>
<h1>mini shop 管理系统</h1>
</div>
<div style="margin-top: 20px">
<%--每个功能 触发ajax 显示在此页--%>
<input class="btn btn-default" id="ccc" type="button" value="用户管理" >
<input class="btn btn-default" type="submit" value="商家管理">
<input class="btn btn-default" type="button" value="订单管理">
</div>
<div class="showtable">
<%--等待ajax 生成表格--%>
</div>
</div>
</body>
</html>
4、userPage
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<html lang="zh-CN">
<head>
<%-- 引入maven中的 jquery--%>
<script src="webjars/jquery/3.4.1/dist/jquery.min.js" charset="UTF-8"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<title>用户功能页</title>
<script>
$(function() {
$("body").on("click", "tr", function () {
//获取tr中 第2个子标签0 1 =price标签中的值
var price = $(this).children("td:eq(1)").text();
var num= window.prompt("单价为"+price+",请输入您要购买的数量");
//获取存货数量
var mynum =$(this).children("td:eq(2)").text();
while(num>mynum){
num = window.prompt("存货不足!当前商品数量为"+mynum+",请重新输入购买数量");
}
var total= num*price;
var pwd=window.prompt("总共需付款"+total+"元,请输入支付密码");
//密码及用户名 传给servlet
//比对密码是否正确
//校验 卡余额 与 商品价格
//均OK———update商品数量-1 当数量为0时————update状态改为下架
//订单 insert1
});
});
</script>
</head>
<body>
<jsp:include page="top.jsp"></jsp:include>
<div style="text-align: center;margin-top: 20px">
<a href="userServ">浏览商品</a><br/>
点击商品栏可进行购买<br/>
<a href="#">查询订单</a><br/>
</div>
<%--用el表达式 显示servlet响应过来的数据--%>
<table class="table table-hover">
<tr>
<td>商品名</td>
<td>价格</td>
<td>数量</td>
<td>上架时间</td>
<td>下架时间</td>
<td>状态</td>
</tr>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.productName}</td> <%--需要get和set方法--%>
<td>${product.price}</td>
<td>${product.number}</td>
<td>${product.addTime}</td>
<td>
<c:if test="${product.delTime != null}">
${product.delTime}
</c:if>
<c:if test="${product.delTime == null}">
未下架
</c:if>
</td>
<td>
<c:if test="${product.status == 1}">
有货
</c:if>
<c:if test="${product.status != 1}">
下架,可收藏等待商家补货
</c:if>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
三、controller层
1、MaServ
package controller;
/**
* 管理员 控制层
* 3功能 都向此处发请求
*/
@WebServlet("/maserv")
public class Maserv extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String btnname = req.getParameter("btnname");
System.out.println(btnname);
ManagerServiceImpl managerService = new ManagerServiceImpl();
List datalist=new ArrayList();
if(btnname.equals("users")){
datalist = managerService.findUserAll();
}
else if(btnname.equals("supers")){
datalist = managerService.findPersonByRole(1);
}
else if(btnname.equals("orders")){
datalist = managerService.findOrderAll();
}
//将list转为JsonArray 便于前端用each遍历 2维数组 支持json
JSONArray jsonlist = JSONArray.fromObject(datalist);
System.out.println(jsonlist);
//第1个 List<Map>转为:
//[{"password":"222","address":"阿尔卑斯山","money":"500.0","sex":"女","tel":"1730","age":"12","personname":"海蒂"},{"password":"333","address":"香榭尔街","money":"600.0","sex":"女","tel":"1878","age":"23","personname":"苏珊"}]
//第2个 List<Person>转为:
//[{"money":50000,"password":"666","personId":2,"personName":"Ole超市","role":1,"tel":"8820"},{"money":10000,"password":"234","personId":5,"personName":"远东百货","role":1,"tel":"9999"}]
//用resp响应给前端ajax的post的回调函数
resp.setCharacterEncoding("utf-8");//否则前端拿到的属性值 乱码
resp.getWriter().print(jsonlist);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
2、UserServ
package controller;
@WebServlet("/userServ")
public class UserServ extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入");
//省略service
List<Product> products = new UserDaoImpl().findProducts();
req.setAttribute("products",products);
//转回 原页面
req.getRequestDispatcher("/userPage.jsp").forward(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
四、service层(略,没有业务需要)
五、dao层
1、ManagerDaoImpl
注意:
1.多表查询 如果不用视图 那sql语句先在Navicat查询中运行
2.查询时避免*
原因:
1,不需要的字段会增加数据传输的时间,
即使mysql服务器和客户端是在同一台机器上,
使用的协议还是tcp,通信也需要额外的时间。
2,select * 可能会获取到自己不需要的列,
如果以后表结构修改了,同样也可能会对代码产生影响。
比如表增加了一个字段,而我代码与其对接的对象属性里没有这个字段,
select * 就会导致报错。
3.创建test类对不确定的dao类方法进行边写完1个边测试
4.当id不加入实体类属性,加入1行时,
直接value不说属性名那种可不行,要用那个sql语句挨个字段对应insert
package dao;
/**
* 管理员 持久层实现类
*/
public class ManagerDaoImpl {
//1.创建JdbcTemplate对象
private static JdbcTemplate jt = new JdbcTemplate();
static {
//准备数据源:spring的内置数据源
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/eesy?useUnicode=true&characterEncoding=utf8&useSSL=false");
ds.setUsername("root");
ds.setPassword("007");
//2.给jt设置数据源
jt.setDataSource(ds);
}
/**功能1 查询所有用户:用户的所有信息包括t_user_info
* 查询顾客2表 t_person顾客role2 t_user_info
* 这次尝试不用视图,
* 由于JdbcTemplate查询后固定返回是List
* 则List<map> Map每个对象每行<属性名列名,属性值> 属性值统一强转为String类型
* 便于前端取数据
* @return
*/
public List<Map<String,String>> findUserAll(){
String sql="SELECT p.person_name,p.tel,p.password,p.money,u.age,u.sex,u.address FROM t_person p RIGHT JOIN t_user_info u ON p.person_id=u.person_id;";
List<Map<String, String>> list = jt.query(sql, new RowMapper<Map<String, String>>() {
@Override
public Map<String, String> mapRow(ResultSet rs, int index) throws SQLException {
Map<String, String> mp = new HashMap<String, String>();
mp.put("personname", rs.getString("person_name"));
mp.put("tel", rs.getString("tel"));
mp.put("password", rs.getString("password"));
mp.put("money", rs.getDouble("money")+"");
mp.put("age",rs.getInt("age")+"");
mp.put("sex",rs.getString("sex"));
mp.put("address",rs.getString("address"));
return mp;
}
});
return list;
}
/**功能2 查询所有商家
* 根据role查 all管理员、all商家、 ...
* @param role 管理员0 商家1 顾客2
* @return
*/
public List<Person> findPersonByRole(int role){
List<Person> persons = jt.query("select * from t_person where role=?", new BeanPropertyRowMapper<Person>(Person.class), role);
return persons.isEmpty()?null:persons;
}
/**功能3 查询所有订单:订单号,购买用户名,购买用户电话,单价,数量,总价,用户地址,购买时间。
* Navicat视图连4表
* @return
*/
public List<Mathree> findOrderAll(){
//此处懒得写列了 工作中可不能写*
List<Mathree> list = jt.query("select * from mathree", new BeanPropertyRowMapper<Mathree>(Mathree.class));
return list.isEmpty()?null:list;
}
}
2、UserDaoImpl(略,方法和以上差不多)