课设小结——商品信息管理系统(JavaWeb+layui+sql)
- 假期课设实现了商品信息管理系统,主要运用了数据库、后端JavaWeb、前端layui框架技术,下面分享一下他们实现过程。
1.数据库的建立
1.题目要求
在该项目中,应按照实际需求分析过程建立关系,并实现增删改查及其他功能
- 商店信息:商店编号、商店名称、区域名、经理姓名、总金额
- 销售信息:商店编号、商品编号、销售日期、销售数量;
- 商品信息:商品编号、商品名称、类别(家电﹑食品﹑日用百货﹑其它)、进价、售价。
2.数据库和基本表的建立
#建立shangpin数据库
create database shangpin;
use shangpin;
#建立用户表
Create table userTable(
id int(11) primary key auto_increment,#自然增长,后续添加商品时不需要手动添加序号
Username varchar(20),
Password varchar(20)
)
#建立商店表
Create table shopTable(
shopid int(3) primary key auto_increment,
shopname varchar(20),
area varchar(20),
manager varchar(20),
total int(10)
);
#建立商品表
Create table goodsTable(
goodsid int(10) primary key auto_increment,
goodsname varchar(20),
type varchar(20),
purchase int(10),
sell int(10)
);
#建立销售表
Create table saleTable(
saleid int(10) primary key auto_increment,
shopid int(3) references shopTable(shopid),
goodsid int(10) references goodsTable(goodsid),
saledate varchar(20),
salenum int(10)
);
3.触发器的设计
触发程序的优点如下:
- 触发程序的执行是自动的,当对触发程序相关表的数据做出相应的修改后立即执行。
- 触发程序可以通过数据库中相关的表数据变动,修改其他表的数据。
- 触发程序可以实施比 FOREIGN KEY 约束、CHECK 约束更为复杂的检查和操作。
在这里我们主要利用它的第二条优点,由于saletable的增加、删除和更改都会影响shoptable中total的数据,因此我们需要对saletable设计三个触发器。下面以INSERT触发器为例
#INSERT触发器
CREATE TRIGGER `add_saletable` AFTER INSERT ON `saletable` FOR EACH ROW begin
declare nshopid int(3);
declare ngoodsid int(10);
declare nsalenum int(10);
declare nsaleid int(10);
declare npurchase int(10);
declare nsell int(10);
declare ntotal int(10);
set nsaleid=(select max(saleid) from saletable);#set nsaleid=new.saleid
set nshopid=(select shopid from saletable where saleid=nsaleid);
set ngoodsid=(select goodsid from saletable where saleid=nsaleid);
set nsalenum=(select salenum from saletable where saleid=nsaleid);
if exists (select goodsid from goodstable where goodsid=ngoodsid) then
set npurchase=(select purchase from goodstable where goodsid=ngoodsid);
set nsell=(select sell from goodstable where goodsid=ngoodsid);
if exists (select shopid from shoptable where shopid=nshopid) then
set ntotal=(select total from shoptable where shopid=nshopid);
update shoptable set total=ntotal+(nsell-npurchase)*nsalenum where shopid=nshopid;
end if;
end if;
end;
3.触发器补充
补充内容部分来源于:小白不再菜
1) INSERT 触发器
在 INSERT 语句执行之前或之后响应的触发器。
使用 INSERT 触发器需要注意以下几点:
- 在 INSERT 触发器代码内,可引用一个名为 NEW(不区分大小写)的虚拟表来访问被插入的行。
- 在 BEFORE INSERT 触发器中,NEW 中的值也可以被更新,即允许更改被插入的值(只要具有对应的操作权限)。
- 对于 AUTO_INCREMENT 列,NEW 在 INSERT 执行之前包含的值是 0,在 INSERT 执行之后将包含新的自动生成值。
本项目设计的数据库用到了第三条,INSERT触发器中set nsaleid=(select max(saleid) from saletable);就是基于这个前提才成立的,也可以用set nsaleid=new.saleid代替
2) UPDATE 触发器
在 UPDATE 语句执行之前或之后响应的触发器。
使用 UPDATE 触发器需要注意以下几点:
- 在 UPDATE 触发器代码内,可引用一个名为 NEW(不区分大小写)的虚拟表来访问更新的值。
- 在 UPDATE 触发器代码内,可引用一个名为 OLD(不区分大小写)的虚拟表来访问 UPDATE 语句执行前的值。
- 在 BEFORE UPDATE 触发器中,NEW 中的值可能也被更新,即允许更改将要用于 UPDATE 语句中的值(只要具有对应的操作权限)。
- OLD 中的值全部是只读的,不能被更新。
注意:当触发器设计对触发表自身的更新操作时,只能使用 BEFORE 类型的触发器,AFTER 类型的触发器将不被允许。
3) DELETE 触发器
在 DELETE 语句执行之前或之后响应的触发器。
使用 DELETE 触发器需要注意以下几点:
- 在 DELETE 触发器代码内,可以引用一个名为 OLD(不区分大小写)的虚拟表来访问被删除的行。
- OLD 中的值全部是只读的,不能被更新。
2.后端JavaWeb的设计
1.DB设计
-
数据库的连接
//连接数据库 public DB(){ url= "jdbc:mysql://localhost:3306/shangpin?characterEncoding=UTF-8"+"&serverTimezone=UTC"; user ="root"; 密码 ="xxx"; try{ Class.forName("com.mysql.jdbc.Driver"); ct=DriverManager.getConnection(url,user,密码); }catch(Exception e){ e.printStackTrace(); } }
-
增删改查功能的实现(以saletable为例)
-
查看saleTable所有信息
public ArrayList findSaleInfo(){ try{ pstmt=ct.prepareStatement("select * from saleTable"); ArrayList al=new ArrayList(); ResultSet rs=pstmt.executeQuery(); while(rs.next()){ Sale sale=new Sale(); sale.setSaleid(rs.getInt(1)); sale.setShopid(rs.getInt(2)); sale.setGoodsid(rs.getInt(3)); sale.setSaledate(rs.getString(4)); sale.setSalenum(rs.getInt(5)); al.add(sale); } return al; }catch(Exception e){ e.printStackTrace(); return null; } }
-
向saleTable增加信息
public boolean addSaleInfo(Sale sale){ try{ pstmt=ct.prepareStatement("insert into saleTable (shopid, goodsid, saledate, salenum) values(?,?,?,?)"); pstmt.setInt(1, sale.getShopid()); pstmt.setInt(2, sale.getGoodsid()); pstmt.setString(3, sale.getSaledate()); pstmt.setInt(4, sale.getSalenum()); pstmt.executeUpdate(); return true; }catch(Exception e){ e.printStackTrace(); return false; } }
-
在saleTable删除信息
public boolean deleteSaleInfo(int saleid){ try{ pstmt=ct.prepareStatement("delete from saleTable where saleid=?"); pstmt.setInt(1,saleid); pstmt.executeUpdate(); return true; }catch (Exception e){ e.printStackTrace(); return false; } }
-
在saleTable修改信息
public boolean updateSaleInfo(Sale sale){ try{ pstmt=ct.prepareStatement("update saleTable set shopid=?, goodsid=?, saledate=?, salenum=? where saleid=?"); pstmt.setInt(1, sale.getShopid()); pstmt.setInt(2, sale.getGoodsid()); pstmt.setString(3, sale.getSaledate()); pstmt.setInt(4, sale.getSalenum()); pstmt.setInt(5,sale.getSaleid()); pstmt.executeUpdate(); return true; }catch (Exception e){ e.printStackTrace(); return false; } }
-
在saleTable查找信息saleid查找
public ArrayList findSaleInfoBySaleid(int saleid){ try { pstmt=ct.prepareStatement("select * from saleTable where saleid=?"); pstmt.setInt(1,saleid); ArrayList al=new ArrayList(); ResultSet rs=pstmt.executeQuery(); while(rs.next()){ Sale sale=new Sale(); sale.setSaleid(rs.getInt(1)); sale.setShopid(rs.getInt(2)); sale.setGoodsid(rs.getInt(3)); sale.setSaledate(rs.getString(4)); sale.setSalenum(rs.getInt(5)); al.add(sale); } return al; } catch(Exception e){ e.printStackTrace(); return null; } }
-
2.model设计
-
这个文件主要用于设计商店表、商品表、销售表、用户表相应的基本操作
-
以销售表为例
public class Sale implements Serializable{ private int shopid; private int goodsid; private String saledate; private int salenum; private int saleid; public int getShopid(){ return shopid; } public void setShopid(int shopid){ this.shopid=shopid; } public int getGoodsid(){ return goodsid; } public void setGoodsid(int goodsid){ this.goodsid=goodsid; } public String getSaledate(){ return saledate; } public void setSaledate(String saledate){ this.saledate=saledate; } public int getSalenum(){ return salenum; } public void setSalenum(int salenum){ this.salenum=salenum; } public int getSaleid(){ return saleid; } public void setSaleid(int saleid){ this.saleid=saleid; } }
3.Servelet设计
-
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
-
以AddGoodsServlet为例
public class AddGoodsServlet extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ request.setCharacterEncoding("utf-8"); response.setContentType("utf-8"); String goodsname=request.getParameter("goodsname"); String type=request.getParameter("type"); int purchase=Integer.parseInt(request.getParameter("purchase")); int sell=Integer.parseInt(request.getParameter("sell")); Goods goods=new Goods(); goods.setGoodsname(goodsname); goods.setType(type); goods.setPurchase(purchase); goods.setSell(sell); if(new DB().addGoodsInfo(goods)){ response.sendRedirect("success.jsp"); } } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ doGet(request,response); } }
4.web.xml和pom.xml文件的配置
1.web.xml的配置
-
web.xml主要用来配置Filter,Listener,Servlet等。
-
web容器的加载顺序ServletContext -> context-param -> listener -> filter -> servlet。并且这些元素可以配置在文件中的任意位置,不会因为filter在web.xml文件中写在listener前面就先加载filter。
-
由于本项目运用了servlet,所以需要对其进行配置(以AddGoodsServlet为例)
<servlet> <servlet-name>addGoodsServlet</servlet-name> <servlet-class>servlet.AddGoodsServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>addGoodsServlet</servlet-name> <url-pattern>/addGoodsServlet</url-pattern> </servlet-mapping>
2.pom.xml的配置
-
pom.xml主要保存当前组件的版本,如sql、servlet、tomcat、junit等,只需改成对应版本,一般放在dependencies里
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies>
3.前端文件的设置及其亮点
由于我主要设置前端,所以会对其功能进行详细说明
1.layui文件的下载
-
前端系统主要使用技术:layui框架,需要到官网下载相关包并导入相关的jsp
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="layui_right.css"> <link rel="stylesheet" href="layui/css/layui.css" media="all"> <script src="layui/layui.js" charset="utf-8"></script> <script src="js/jquery.js" charset="utf-8"></script>
在文件中的位置:
2.登录注册界面的设置
- 这部分并没有调用layui框架,而是调用另外的css、js文件
- 由于javaweb初始时自动调用index.jsp,所以把其设置为登录界面
下面是登录界面的渲染效果:
-
动态动画效果的实现:
其主要原理是通过在js文件设置相关函数,生成随机点并将最近的几个随机点相连
-
随着鼠标位置移动:
function mouseMove(e) { var posx = posy = 0; if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } target.x = posx; target.y = posy; }
-
设置随机点
points = []; for(var x = 0; x < width; x = x + width/20) { for(var y = 0; y < height; y = y + height/20) { var px = x + Math.random()*width/20; var py = y + Math.random()*height/20; var p = {x: px, originX: px, y: py, originY: py }; points.push(p); } }
-
-
登录和注册不同的页面跳转方式:
-
登录按钮的跳转:通过form action中loginServlet跳转,将相关值传递过去
-
注册按钮的跳转:由于注册按钮不需要传递任何参数,所以设置了一个onclick事件进行跳转
<p class="act-but"> <input type="button" class="btn btn-primary" value="注册"onclick="regist()"> </p><!--注册按钮-->
-
跳转函数设置:
<script type="text/javascript"> function regist() { // 如果需要在新窗口打开注册界面; // window.open('Untitled-2.html'); // 如果需要在当前窗口打开登录界面 window.location.href = 'register.jsp'; } </script>
jsp文件中函数需要放在中才能实现
-
-
密码的显隐性设置:
-
密码显隐性设置,也是通过onclick事件实现,并通过js文件分析解析
//显示隐藏对应的密码方法: function show_hide_pwd(id) { let type = $("#"+id).attr('type') if (type === "password") { $("#"+id+"eye").attr('src', "img/eye_close.svg"); $("#"+id).attr("type", "text"); } else { $("#"+id+"eye").attr('src', "img/eye_open.svg"); $("#"+id).attr("type", "password"); } }
-
-
注意事项:
- loginServlet中request.setCharacterEncoding需要设置为gb2312,否则会乱码
- loginServlet中不能写
User user=(User)session.getAttribute("user"),
因为他可以追踪你已经登录的用户,从而导致二次登录会发生异常。应该为User user=null;
- register.jsp和index.jsp的pageEncoding的设置需相同,否则会导致乱码
3.主界面的设置
-
通过相应的div class分别设置页面的头部、顶部logo、右边栏目、页面侧边栏、页面主体内容和页面底端,下面是主界面的渲染效果:
- 下拉框的实现:通过
<dd><dl>
实现,注意图片和文字需要放在一个<li>
中,才能实现其中任何一个都能出现下拉框,同时<a href="javascript:;">
表示跳转到任何界面,而是直接出现下拉框 - 页面侧边栏中layui-this属性保证了当前选中的查询表现为高亮
4.表格的实现与设计
1.数据表格的构造
-
静态表格参数说明:
<table height="600" lay-filter="parse-table-demo" lay-data="{id: 'idTest'}" style="margin: 0 auto;">
-
lay-filter是区分不同表格的标志,相当于选择器
-
lay-data用于表格的自动渲染
<table class="layui-table" lay-data="{ height: 500, id:'test', url:'${ctx}/servlet/StaffServlet?type=tabStaff', //请求路径 page: true,//是否显示分页工具条 limit: 10,//每页默认显示的数量 method: 'post', //提交方式 }" lay-filter="test">
-
-
通过循环枚举数据库的数据,先形成静态表格,如下图:
再通过layui.use中table.init方法转化成数据表格,如下图:
如果有数据的json文件,也可以通过table.render方法形成数据表格
-
table.init详解
<script>
table.init('parse-table-demo', { //转化静态表格
height: '350'
,toolbar: '#toolbarDemo'
,defaultToolbar: ['filter', 'exports', 'print', { //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可
title: '提示'
,layEvent: 'LAYTABLE_TIPS'
,icon: 'layui-icon-tips'
}]
,even:true
,page:true
console.log(data);
,totalRow: true
});
</script>
- 'parse-table-demo’为表格的id,也可以通过elem:‘xxx’来实现
- toolbar: ‘xxx’ 用于开启头部工具栏,其功能需要我们自己去实现,xxx为对应的script的id
- defaultToolbar:也是自定义头部工具栏,只不过固定在右侧,同时提供筛选、导出和打印功能
- even:使单双行颜色不一样,page:开启分页,totalRow:开启总和行
- 当然init中还有其他参数比如done、limit等,有需要的可以自行查阅
2.数据表格的渲染
-
数据表格的颜色、背景、高度、宽度、排序、求和、加粗、斜体、居中、拉伸、左右固定都是通过设置渲染出来的
<thead> <tr> <th lay-data="{field:'',type:'checkbox'}"></th> <th lay-data="{field:'shopid', width:140, sort: true,totalRowText: '合计', templet: '#idTpl',align:'center'}">商店编号</th> <th lay-data="{field:'shopname', width:150, sort: true,style:'background-color: #eee;',align:'center'}">商店名称</th> <th lay-data="{field:'area', width:150,sort:true, align:'center',templet: function(res){return '<em>'+ res.area +'</em>'}}">区域名</th> <th lay-data="{field:'manager', width:150, sort: true,align:'center',templet: function(res){return '<strong>'+ res.manager +'</strong>'}}">经理姓名</th> <th lay-data="{field:'total', width:150,sort:true,totalRow: true,templet: '#totalTpl',align:'center'}">总金额</th> <th lay-data="{field:'operation', toolbar: '#barDemo', align:'center'}">操作</th> </tr> </thead>
field 每一项的标志 width 表格宽度,如果不设置会自动调整 align 设置对其方式 sort 该列列是否排序 totalRowText 该列是否求和 backgroundcolor 背景颜色 templet 通过函数自定义样式 -
templet功能实现
-
像加粗、倾斜简单功能,可以直接在建表时候实现,res.xxx,其中xxx为对应表格的field
templet: function(res){return '<strong>'+ res.manager +'</strong>'}}">经理姓名</th>
-
设置颜色等复杂功能
-
首先建表时,表头需要引用对应script的id,如
templet: '#idTpl'
-
script设置函数功能
<script type="text/html" id="idTpl"> {{# if(d.shopid %2==0){ }} <span style="color: #F581B1;">{{ d.shopid }}</span> {{# } else { }} <span style="color: #00BFFF;">{{ d.shopid }}</span> {{# } }} </script>
奇偶编号颜色不一样,注意其书写方式,只能写一个if-else
-
-
3.头工具栏的实现
-
首先要将工具栏的按键放在一个script中,其中id是识别这组工具栏的标识,调用方法是放在table.init的toolbar或者defaultToolbar中
<script type="text/html" id="toolbarDemo"> <div class="layui-btn-container"> <button class="layui-btn layui-btn-sm layui-btn-warm" lay-event="getCheckData">获取选中商店数据</button> <button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="getCheckLength">获取选中商店数目</button> <button class="layui-btn layui-btn-sm" lay-event="isAll">验证是否全选</button> <button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="addShop"><i class="layui-icon layui-icon-add-circle-fine" style="font-size:20px;font-weight:bold"></i>新增商店</button> </div> </script>
-
lay-event在这里相当于每一个button的标识
-
table.on详解
<script> table.on('toolbar(parse-table-demo)', function(obj){ var checkStatus = table.checkStatus(obj.config.id); switch(obj.event){ case 'getCheckData': var temp=""; var data = checkStatus.data; for(var i=0;i<data.length;i++){ //循环筛选出id temp=temp+data[i].shopid+' '+data[i].shopname+' '+data[i].area+' '+data[i].manager+' '+data[i].total+'</br>'; } layer.msg(temp, {icon: 1}); // layer.alert(JSON.stringify(data)); break; </script>
- table.on(‘toolbar(xxx)’),其中xxx为表格id
- table.checkStatus(xxx)。打他,xxx为表格id,用于获得表格选中字段数据
- 这里obj.event对应之前的lay-event
- data[i].xxx,这里xxx是表格每一项的field
4.表格数据的获取
- 方法一:将数据存储在一个json文件中,之后通过table.render的data或url中设置
<script>
table.render({
elem: '#test-table-toolbar'
,url:"http://localhost:8090/program-web/api/magic_change/oj/problem/page_list?userId=youcongtech"
,toolbar: '#test-table-toolbar-toolbarDemo'
,title: '程序设计题绑定'
,cols: [[//设置表头
{type: 'checkbox', fixed: 'left'},
{field:'problemId', width:300, title: 'ID', sort: true}
,{field:'title', width:400, title: '题目'}
,{width:215, align:'center', fixed: 'right', toolbar: '#test-table-toolbar-barDemo'}
]]
,page: true
});
</script>
-
方法二:静态表格转化为数据表格
前文已经讲过如何转化,下面说一下数据如何实时保存与更新
<% DB db=new DB(); ArrayList<Shop> list=db.findShopInfo(); if(list!=null&&list.size()>0){ for(int i=0;i<list.size();i++){ Shop shop=list.get(i); %> <tbody> <tr><td></td> <td><%=shop.getShopid()%></td> <td><%=shop.getShopname()%></td> <td><%=shop.getArea()%></td> <td><%=shop.getManager()%></td> <td><%=shop.getTotal()%></td> </tr> </tbody> <% } } %>
通过循环,将数据存储在表格中,不管增删改,只要更新界面数据就会跟着变
5.增删改功能的实现
-
增删改都用到了layer相关函数,先将layer常用函数总结一下
layer.use 后面可以接([‘table’,’form’],function)等要渲染的工具 layer.msg 弹出提示消息,可设置time和icon等 layer.alert 弹出提示框 layer.open 跳出弹窗 layer.confirm 跳出确认框 layer.prompt 跳出要更改的信息框 layer.close 关闭消息框和弹窗 layer.msg和layer.alert换行要用
<br>
1.添加功能
<script type="text/html" id="toolbarDemo"> <button class="layui-btn" lay-event="addShop"></i>新增商店</button> </script>
-
首先找出其script的id和其button的lay-event,将id放到table.init的toolbar中。
toolbar=‘#toolbarDemo’
-
通过layer.open跳出弹窗
case 'addShop': layer.open({ title:'新增商店', type: 2, skin: 'layui-layer-rim', //加上边框 area: ['800px', '480px'], //宽高 content: 'addShop.jsp', //btn:['确认','取消'] maxmin: true, shadeClose: true, //点击遮罩关闭层 });
-
type: Layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
-
content:支持jsp、html以及获取DOM元素等,这里选用的是jsp页面(注意jsp文件名区分大小写)
最开始选择的是type:1,将jsp内容直接写入content(需要加单引号),但因为其本质是字符串,识别不了onclick函数功能,所以改用直接跳jsp
-
btn是其自带的两个可以调用的按钮,其用法:
yes: function(index){//layer.msg('yes'); //点击确定回调 }, btn2: function(){//layer.alert('aaa',{title:'msg title'}); 点击取消回调 }
我们这不需要,因为直接在add.jsp设置了按钮
-
-
addshops.jsp设置
其渲染效果如下:
下面是部分代码:
<form action="addShopServlet" method="post"> <div style="padding: 15px"> <div class="layui-form-item"><label class="layui-form-label">商店名称</label><div class="layui-input-block"><input id="shopname" name="shopname" class="layui-input" placeholder="请输入商店名称" /></div></div> <div class="layui-btn-container" style="margin-top: 45px;"> <button style="float: right" class="layui-btn layui-btn-normal" lay-filter="login_button" lay-submit="">新增商店</button> <button style="float: right" class="layui-btn layui-btn-primary" type="reset">重置</button> </div> </div> </form>
- placeholder:描述输入的预期值信息
- 注意button中lay submit=“”不要忘记写,这样form action才能识别
- form action中的值区分大小写
-
success.jsp的设置
-
运行成功会弹出消息:操作成功
-
之后会刷新返回原来界面
<script> // showMessage('添加成功') layer.msg("操作成功!", { icon: 6, time: 2000 }, function () { parent.window.location.reload(); var index = parent.layer.getFrameIndex(window.name); //获取窗口索引 parent.layer.close(index); }); </script>
-
2.删除功能
if(obj.event === 'del'){ layer.confirm('真的删除行么', function(index){ obj.del(); layer.open({ title:'提示', type: 2, skin: 'layui-layer-rim', //加上边框 area: ['400px', '240px'], //宽高 content: 'deleteShop.jsp?shopid='+id, maxmin: true, shadeClose: true, //点击遮罩关闭层 }); layer.close(index); });
-
前期准备和添加功能相同,删除功能这里先有一个layer.confirm用于提示是否真的删除,只有确定才能执行里面layer.open的功能,从而跳转到deleteshop.jsp界面
-
content中jsp后面有一个
?shopid='+id
,是向jsp传递的参数 -
deleteShop.jsp的设计,本项目没有通过servlet实现删除,而是在jsp中直接实现
-
首先要连接数据库
<%! public static final String DBDRIVER="com.mysql.jdbc.Driver"; public static final String DBURL="jdbc:mysql://localhost:3306/shangpin?characterEncoding=UTF-8"+"&serverTimezone=UTC"; public static final String DBUSER="root"; public static final String DBPASS="xxx; %>
-
接着通过
request.getParameter("shopid");
获取参数<% Connection conn=null; PreparedStatement pst=null; int rs=0; String shopid=request.getParameter("shopid"); %>
-
然后用java和sql语言实现删除功能(参考上面deleteSaleServlet写法)
-
最后弹出提示,刷新界面
<script> // showMessage('添加成功') layer.msg("删除成功!", { icon: 6, time: 2000 } , function () { parent.window.location.reload(); var index = parent.layer.getFrameIndex(window.name); //获取窗口索引 parent.layer.close(index); }); </script>
jsp文件中的java代码都要放在<%%>中
-
3.更改功能
其实现原理与添加功能几乎相同,只不过本项目对updateShop.jsp进行了对用户友好的处理
-
updateShop.jsp设计,首先看一下它的渲染效果
-
由于商品编号是重要信息,用户不可更改,所以设置了只读功能,即readonly=“true”
<div class="layui-form-item"><label class="layui-form-label">商店编号</label><div class="layui-input-block"><input id="shopid" name="shopid" class="layui-input" readonly="true" style="background:#CCCCCC" value="<%=shoplist.get(0).getShopid()%>" placeholder="<%=shoplist.get(0).getShopid()%>" /></div></div>
设置readonly=“true”表示只读,disabled=“diabled”表示不可更改,form action也不能将value传递过去,所以只能用readonly
-
由于更改信息时用户可能要参照之前的信息进行更改,所以placeholder中保存了其原有信息,实现该功能只需找到该项的数据
<% int shopid=Integer.parseInt(request.getParameter("shopid")); DB db=new DB(); List<Shop> shoplist=new ArrayList<Shop>(); shoplist=db.findShopInfoByShopid(shopid); %>
这里只将shopid传过来,而没有将其他数据传过来,因为可能会造成乱码
-
6.查询功能实现
-
这里实现了多条件查询功能,即满足任意几个查询条件都可以组合查询
-
为了方便查询,这里设置了搜索选择框,将各列数据保存在下拉框中
<div class="layui-input-inline"> <select name="shopid" lay-verify="required" lay-search=""> <option value="">请选择商店编号</option> <% if(shop_list!=null&&shop_list.size()>0){ for(int i=0;i<shop_list.size();i++){ Shop shop=shop_list.get(i); %> <option value=<%=shop.getShopid()%> ><%=shop.getShopid()%></option> <% } } %> </select> </div>
- 通过循环实现信息的搜集
- 为了防止option value的值传递后乱码,将pageEncoding设置为utf-8即可
-
为了实现查询后,将符合条件的数据传递到数据表格呈现,findShop.jsp与shops.jsp代码几乎设置一样,只是循环前验证了shop_list是否为null
<%if(request.getAttribute("shop_list")!=null);{%> <% List<Shop> shopList=(List)request.getAttribute("shop_list"); if(shopList!=null&&shopList.size()>0){ for(int i=0;i<shopList.size();i++){ Shop shop=shopList.get(i); %> <tbody> <td></td> <td><%=shop.getShopid()%></td> <td><%=shop.getShopname()%></td> <td><%=shop.getArea()%></td> <td><%=shop.getManager()%></td> <td><%=shop.getTotal()%></td> </tbody> <% } } %> <%} %>
7.颜色及符号设置
layer.msg(“测试”,{icon:x}) | 效果 |
---|---|
0 | ![]() |
1 | ![]() |
2 | ![]() |
3 | ![]() |
4 | ![]() |
5 | ![]() |
6 | ![]() |
4.项目亮点小结
-
登录界面通过js设计实现了动态效果
-
登录界面密码的显隐性设置帮助用户记忆密码
-
数据表格筛选、导出、打印、提示功能,方便表格编辑
-
表格数据可以实现排序及求和功能,并且销售表改变,商店表总金额也会改变
-
表格各列可以实现左右自由拉伸改变宽度
-
表格具有分页功能,可以切换页数
-
表格居中,颜色丰富不单一
-
表格序号单双号颜色不同,总额以500为界限不同,方便用户判断
-
各列颜色、格式一致,方便用户区分
-
新增商品和添加商品跳出弹窗添加,使得主界面更简洁干净
-
删除商品会有提示,避免用户误删
-
更新商品序号为重要信息,对用户设为只读
-
更新商品输入框会提示原商品的信息,方便用户对照修改
-
执行操作成功会有弹窗提示操作成功,并且会立刻更新界面
-
查询商品实现多条件查询,任意几个查询条件都可以组合
-
查询框为搜索选择框,方便用户选择商品
-
查询结果会展示所有符合条件结果,没有符合条件的会显示无数据