JavaWeb中水果库存系统的学习

一、编辑和修改特定的信息

我们想达到的效果为:在页面点击一个水果,然后对这个水果进行编辑,之后更新页面。

第一步:

在水果名称这里增加一个超链接,点击可以跳转到编辑的页面中,

th:href="@{...}" 这样的操作会使得查找的路径从项目的根目录开始,而不是当前的目录下。

通过fid主键来查找数据库中对应的水果

@WebServlet("/edit.do")
public class EditServlet extends ViewBaseServlet {private FruitDAO fruitDAO = new FruitDAOImpl();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String fidStr = req.getParameter("fid");if(StringUtil.isNotEmpty(fidStr)){int fid = Integer.parseInt(fidStr);Fruit fruit = fruitDAO.getFruitByFid(fid);req.setAttribute("fruit",fruit);super.processTemplate("edit",req,resp);}}
}

最后一行是渲染edit.html页面,将查找到的水果信息渲染到edit.html页面中

第二步:修改

        我们将这个table表放入表单中可以提交信息。

<p class="center f30">编辑库存信息</p><form th:action="@{/update.do}" method="post"><input type="hidden" name="fid" th:value="${fruit.fid}"/><table id="tbl_fruit" th:object="${fruit}"><tr><th class="w20">名称</th><td><input type="text" name="fname" th:value="*{fname}"/></td></tr><tr><th class="w20">单价</th><td><input type="text" name="price" th:value="*{price}"/></td></tr><tr><th class="w20">库存</th><td><input type="text" name="fcount" th:value="*{fcount}"/></td></tr><tr><th class="w20">备注</th><td><input type="text" name="remark" th:value="*{remark}"/></td></tr><tr><th colspan="2"><input type="submit" value="修改"/></th></tr></table></form>

当点击提交按钮时,会将form表单的数据以post的方式,提交给update.do这个组件

对于每一行中的 th:value=.... 是为了上一步的渲染,能将数据显示到页面上。

没有使用 ${fruit.fname}这样的格式而使用了 *{fname} 因为在table中增加了th:object="${fruit}"。

update.do

@WebServlet("/update.do")
public class UpdateServlet extends ViewBaseServlet {private FruitDAO fruitDAO = new FruitDAOImpl();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");String fidStr = req.getParameter("fid");Integer fid = Integer.parseInt(fidStr);String fname = req.getParameter("fname");String priceStr = req.getParameter("price");Integer price = Integer.parseInt(priceStr);String fcountStr = req.getParameter("fcount");Integer fcount = Integer.parseInt(fcountStr);String remark = req.getParameter("remark");fruitDAO.updateFruit(new Fruit(fid,fname,price,fcount,remark));//此处需要重新向index页面发送请求,将更改后的数据进行渲染。resp.sendRedirect("index");}
}

最后一行要再次向index组件发送请求,将更改后的数据进行渲染。

二、实现删除操作

        在操作那一栏中有一个删除的图片,我们想要达到的效果是点击这个图片,会删除这一行的数据。

        所以在index页面上

 在thymeleaf中 | | 的作用是:将里面的字符串和thymeleaf表达式自动拼接起来

之后使用JS来处理删除操作:

function delFruit(fid){if(confirm('是否确认删除?')){window.location.href='del.do?fid='+fid;}
}

window.location.href  是在页面出现选框后 选确定就会跳转到del.do组件上,并且把fid的值也带着。

当然,我觉得在那里使用超链接到del.do也可以,只是没有一个确认的框框出现。

像这个:

三、实现添加功能

在index页面布置一个添加的地方,然后通过超链接来访问到add.html页面

<html xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><link rel="stylesheet" href="css/add.css"></head><body><div id="div_container"><div id="div_fruit_list"><p class="center f30">编辑库存信息</p><form action="add.do" method="post"><table id="tbl_fruit"><tr><th class="w20">名称</th><td><input type="text" name="fname"/></td></tr><tr><th class="w20">单价</th><td><input type="text" name="price"/></td></tr><tr><th class="w20">库存</th><td><input type="text" name="fcount"/></td></tr><tr><th class="w20">备注</th><td><input type="text" name="remark"/></td></tr><tr><th colspan="2"><input type="submit" value="添加"/></th></tr></table></form></div></div></body>
</html>

然后就表单输入数据提交通过action的值来访问 add组件即可。

@WebServlet("/add.do")
public class AddServlet extends ViewBaseServlet {private FruitDAO fruitDAO = new FruitDAOImpl();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");String fname = req.getParameter("fname");String priceStr = req.getParameter("price");Integer price = Integer.parseInt(priceStr);String fcountStr = req.getParameter("fcount");Integer fcount = Integer.parseInt(fcountStr);String remark = req.getParameter("remark");fruitDAO.addFruit(new Fruit(0, fname, price, fcount, remark));resp.sendRedirect("index");}
}

四、页面的分页功能

 在实现分页功能的时候,需要注意要获得数据库里的总记录个数,然后将其转换为对应的页数,每一页展示多少自己决定。

所以要理清这三个参数的数学关系。

在input中 按钮有一个属性为disabled:当满足后面的条件时,这个按钮不可用。

比如 第一个意思就是:当页面为1的时候,首页不能点。

​Integer pageNo = 1 ;String pageNoStr = req.getParameter("pageNo");if(StringUtil.isNotEmpty(pageNoStr)){pageNo = Integer.parseInt(pageNoStr);}​

在index组件上,定义了一个pageNo将所在的页的页数存入。当我们第一次访问index页面时候,pageNo 为1,当点击下一页的时候,pageNo = pageNo +1 ;当点击上一页的时候为 pageNo-1。

步骤:

        1、首先控制页面显示的数量:

    @Overridepublic List<Fruit> getFruitList(Integer pageNo) {return super.executeQuery("select * from t_fruit limit ?,5",(pageNo-1)*5);}

之前的方法没有参数,且查询的sql语句只是: select * from t_fruit 会显示所有数据,通过Limit限制即可。

        2、确定共有多少页

  @Overridepublic int getFruitCount() {return ((Long)super.executeComplexQuery("select count(*) from t_fruit")[0]).intValue();}

        pageCount:总页数       

        根据之前编写的dao方法来处理。并且在index组件上把pageNo保存在session中,方便在页面上使用。

        3、在页面上实现

<div style="width:60%;margin-left:20%;" class="center"><input type="button" value="首 页" class="btn" th:onclick="|page(1)|" th:disabled="${session.pageNo==1}"/><input type="button" value="上一页" class="btn" th:onclick="|page(${session.pageNo-1})|" th:disabled="${session.pageNo==1}"/><input type="button" value="下一页" class="btn" th:onclick="|page(${session.pageNo+1})|" th:disabled="${session.pageNo==session.pageCount}"/><input type="button" value="尾页" class="btn" th:onclick="|page(${session.pageCount})|" th:disabled="${session.pageNo==session.pageCount}"/></div>

        js文件中的page函数:

function page(pageNo){window.location.href="index?pageNo="+pageNo;
}

相当于在访问一次index组件,并且把更新的pageNo也带进去重新渲染。

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Integer pageNo = 1 ;String pageNoStr = req.getParameter("pageNo");if(StringUtil.isNotEmpty(pageNoStr)){pageNo = Integer.parseInt(pageNoStr);}HttpSession session = req.getSession();session.setAttribute("pageNo",pageNo);FruitDAO fruitDAO = new FruitDAOImpl();List<Fruit> fruitList = fruitDAO.getFruitList(pageNo);int fruitCount = fruitDAO.getFruitCount();int pageCount = (fruitCount+5-1)/5 ;//保存到session作用域session.setAttribute("fruitList",fruitList);session.setAttribute("pageCount",pageCount);super.processTemplate("index",req,resp);}
}

过程:一开始访问index组件的时候,pageNo为空,使用我们初始化的pageNo来显示。当点击下一页或者尾页这些操作的时候,会对应的改变pageNo的值,

 之后通过js里的代码再次访问index组件,并且将新的pageNo的值传入,因此第二次的pageNo为request中所带的。然后在通过函数getFruitList(pageNo)来更新页面即可。

五、根据关键字查询

1、根据关键字查询在sql里面相当于是模糊查询。因此在dao来访问数据库的时候对应操作的sql语言也应该有关键字存在:

    @Overridepublic List<Fruit> getFruitList(String keyword, Integer pageNo) {return super.executeQuery("select * from t_fruit where fname like ? or remark like ? limit ?,5 ","%"+keyword+"%", "%"+keyword+"%",(pageNo-1)*5);}

 2、在index页面,查询部分用表单来发送关键字:

<form th:action="@{/index}" method="post"><input type="hidden" name="oper" value="search"/>请输入关键字:<input type="text" name="keyword"/><input type="submit" value="查询" class="btn"/></form>

3、在index组件中,需要判断发来的请求是通过点击查询的请求还是点击页面其他按钮的请求:

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");Integer pageNo = 1 ;HttpSession session = req.getSession();String oper = req.getParameter("oper");//如果oper为空,说明不是点击查询按钮来访问 /index 的String keyword = null;if(StringUtil.isNotEmpty(oper) && "search".equals(oper)){//说明此时是点击 查询来进入index组件的,keyword可以从查询的表单中获取pageNo=1 ;keyword = req.getParameter("keyword");if(StringUtil.isEmpty(keyword)){keyword="";}session.setAttribute("keyword",keyword);}else {//说明此处不是通过点击查询来发送请求的,当点击下面的 页数的时候String pageNoStr = req.getParameter("pageNo");if(StringUtil.isNotEmpty(pageNoStr)){pageNo = Integer.parseInt(pageNoStr);}Object keywordObj = session.getAttribute("keyword");if(keywordObj!=null){keyword = (String)keywordObj;}else{keyword="";}}session.setAttribute("pageNo",pageNo);FruitDAO fruitDAO = new FruitDAOImpl();List<Fruit> fruitList = fruitDAO.getFruitList(keyword, pageNo);int fruitCount = fruitDAO.getFruitCount(keyword);int pageCount = (fruitCount+5-1)/5 ;//保存到session作用域session.setAttribute("fruitList",fruitList);session.setAttribute("pageCount",pageCount);super.processTemplate("index",req,resp);}
}

代码逻辑:当第一次访问index组件时候,没有点击查询操作,因此oper的值为空,所以会进入第一个else语句中,同时keyword的值也是初始化的值null且会话里也没有keyword的值,所以

 这一段获得的值为null。因此keyword的值就赋值为空字符串,然后在模糊查询中 %keyword%,由于keyword为空就相当于全查询,所以页面就会显示所有数据。

当我们输入关键字并且点击查询之后,此时oper就有值了且为search,进入if语句中

 之后获取到关键字的值。并且存入session中,方便之后使用。

输入关键字点击查询之后,页面展示的数据就是与关键字有关的数据,此时当点击下一页的时候,keyword的值还在session中保存着不变,改变的仅有pageNo。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

删不干净_“我劝你别删前任微信”

大家好&#xff0c;我是Lady Bird.几天前&#xff0c;我收到了前任测试单删的群发信息。看到他头像边亮起的红色数字一的瞬间&#xff0c;我才意识到分手之后我们再也没联系过。可能在很多人看来&#xff0c;留着对方微信就是危险信号。说实话&#xff0c;这事儿要放几年前&…

对于事务的认识

例子&#xff1a;当转账操作的时候&#xff0c;A用户转账给B用户&#xff0c;希望的结果是&#xff1a;A扣了钱&#xff0c;B加了钱&#xff1b;或者是A转账失败&#xff0c;B的钱数也没增加。 事务的处理原则&#xff1a;要么都执行&#xff0c;要么都不执行 理解&#xff1a;…

Spring中IOC与DI的学习

1、IOC 1.1步骤 2、DI 依赖注入 2.1步骤&#xff1a; 其中的set方法是IOC容器来调用的 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/…

Mybatis初始化配置

框架&#xff1a;jar包配置文件 一、添加依赖 在项目的pom.xml文件中添加mybatis依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version><scope>test</s…

用table展示树形结构数据_复习一下数据结构(二)——2.2 树形索引(23树)

普通树一个结点可以有多个孩子&#xff0c;但它本身只能存储一个元素&#xff0c;而二叉树结点最多只能有两个&#xff0c;这对于元素非常多的时候&#xff0c;会使得树的度或者是高度会非常大。这就使得内存存取外存的次数会增多&#xff0c;一旦涉及到外部存储设备&#xff0…

Spring中整合mybatis包

一、把对应的依赖都添加上&#xff1a; mysql、mybatis、spring的依赖&#xff08;都是基础的&#xff09; <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.17<…

dfa转正则表达式_从0到1打造正则表达式执行引擎(二)

本文原文地址https://blog.csdn.net/xindoo/article/details/106458165在上篇博客从0到1打造正则表达式执行引擎(一)中我们已经构建了一个可用的正则表达式引擎&#xff0c;相关源码见https://github.com/xindoo/regex&#xff0c;但上文中只是用到了NFA&#xff0c;NFA的引擎建…

AOP的学习

注意&#xff1a;不惊动原始设计 一、部署依赖 AOP开发默认导入 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency> 二、具体步骤 Aspect 告诉Sprin…

选择题_一级造价师选择题的分值是多少

一级造价工程师考试的选择题分为单选题和多选题&#xff0c;每科单选题为60题&#xff0c;每题一分&#xff1b;多选题为20题&#xff0c;每题两分&#xff0c;总分100分。一级造价师选择题的分值一级造价工程师考试共有《建设工程造价管理》、《建设工程计价》、《建设工程技术…

2017年什么命_所谓“佛系”,真的不是什么都不做!

文 | 新宇姐姐 猫咪de生活观在这匆忙的世道中&#xff0c;人心浮躁&#xff0c;急不可耐。这喧嚣的世界车水马龙&#xff0c;我们为了生活&#xff0c;三点一线的忙碌奔波。城市很繁华&#xff0c;容易让人迷失&#xff1b;尘世很奔波&#xff0c;容易让人疲倦。不由得让我们想…

flask 接口 让别人能访问_flask搭建一个前后端分离的系统

我们通常说三端&#xff0c;pc端&#xff0c;android端和ios端。如果前后端不分离&#xff0c;相当是要做三套系统。如果前后端分离的话&#xff0c;可以共用一个后端&#xff0c;前端各自做自己的&#xff0c;不用管后端。前后端不分离在前后端不分离的应用模式中&#xff0c;…

SpringMVC下5中参数类型传递

1、普通参数 //普通参数:请求参数名与形参名不同RequestMapping("/commonParamDifferentName")ResponseBodypublic String commonParamDifferentName(RequestParam("name") String username, int age){System.out.println("普通参数传递:username:&qu…