JavaWeb简易水果库存系统的实现

本系统仅使用servlet以及thymeleaf技术,记录设计时的逻辑思路,暂时还未考虑servlet优化以及Filter和Listener,也并未将所有源码粘贴展示。

1. 首页展示效果

1.1 将数据库中的库存记录显示到前台

获取IndexServlet传过来的fruitList列表,如果没有,则显示为库存为空:

<tr th:if="${#lists.isEmpty(session.fruitList)}">
	<td colspan="4">对不起,库存为空!</td>
</tr>

如果有则通过session域获取,通过thymeleaf语法在前端进行展示:

<tr th:unless="${#lists.isEmpty(session.fruitList)}" th:each="fruit : ${session.fruitList}">
<!--						<td><a th:text="${fruit.fname}" th:href="@{'edit.do?fid='+${fruit.fid}}">苹果</a></td>-->
	<td th:text="${fruit.price}">5</td>
	<td th:text="${fruit.fcount}">20</td>
	<td><img src="imgs/del.jpg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"/></td>
</tr>

接下来就需要IndexServlet能够获取到数据库的值,那么先对FruitDAO接口定义一个能够查询数据库的方法:

//获取指定页码的库存列表信息,每页显示5条
	List<Fruit> getFruitList(String keyword,Integer pageNo);

这里的FruitDAO继承了BaseDAO,BaseDAO是定义了一些数据库的通用增删改查操作以及数据库的连接方法。
    接下来在FruitDAOImpl实现类中实现该方法的具体操作:

public 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);
    }

这里使用到的keyword是在后述中的实现查询操作的时候修改了,这里可以先忽视。
    在IndexServlet中创建FruitDAOImpl实现类的对象,调用该方法得到一个fruitList,然后将该对象保存到session作用域中:

FruitDAO fruitDAO = new FruitDAOImpl();
List<Fruit> fruitList = fruitDAO.getFruitList(keyword,pageNo);
//保存到session作用域
HttpSession session = request.getSession() ;
session.setAttribute("fruitList",fruitList);

这样前台就能拿到作用域中的fruitList进行展示

1.2 翻页功能的实现

由于上述代码仅仅实现了在首页展示数据库中5条记录的功能,并未实现翻页功能,所以在这节实现翻页功能的设计与实现。
    同样的,先设计前端的翻页按钮:

<div style="width: 60%; margin-left: 20%; text-align: center; padding-top: 4px;">
	<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}"/>
	<span th:text="${session.pageNo}"></span>
	<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方法:

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

点击按钮将会执行page()方法,同样是在session作用域中取到pageNo,然后直接使用pageNo + 1或pageNo - 1进行上一页下一页的实现操作,需要能在session中获取到pageNo,那么就需要对IndexServlet进行相应的设计:

Integer pageNo = 1;
String pageNoStr = request.getParameter("pageNo");
if (StringUtil.isNotEmpty(pageNoStr)){
  pageNo = Integer.parseInt(pageNoStr);
}
//放入session会话域
session.setAttribute("pageNo",pageNo);

首页只需要调用page(1),尾页则需要知道库存中有多少库存记录,通过库存记录数来计算得到库存的总页数到底是多少,所以就需要对FruitDAO和FruitDAOImpl添加相应的方法:

//查询数据库中的条目数
int fruitCount(String keyword);
public int fruitCount(String keyword) {
  	return ((Long)super.executeComplexQuery("select count(*) from t_fruit where fname like ? or remark like ?","%"+keyword+"%","%"+keyword+"%")[0]).intValue();
}

然后在IndexServlet中计算pageCount并将其保存到session作用域:

int fruitCount = fruitDAO.fruitCount(keyword);
int pageCount = (fruitCount + 5 - 1) / 5;
session.setAttribute("pageCount",pageCount);

那么实现尾页的操作就只需要调用page(${session.pageCount})方法
     这样设计其实存在一个弊端,在页码为1时上一页的功能仍然可用,此时就会出现负数页的情况,解决这个问题的很简单,只需要在按钮之后设置一个禁用属性即可:上述的:

<!--这里是需要使用thymeleaf获取session中的pageNo值,所以使用th-->
th:disabled="${session.pageNo==1}

2. 编辑水果库存功能的实现

前端edit.html的form表单的设计:

<form th:action="@{/update.do}" method="post" th:object="${fruit}">
   <!--隐藏域:类似于文本框,它的值会随着表单的发送而发送给服务器,但是用户看不到-->
   <input type="hidden" name="fid" th:value="*{fid}">
   <table id="tbl_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>

这里将表单提交到updateServlet处理:

//1.设置编码
req.setCharacterEncoding("UTF-8");

 //2.获取参数
 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");

 //3.执行更新
 fruitDAO.updateFruit(new Fruit(fid,fname,price,fcount,remark));

这里就需要调用fruitDAO中的updateFruit方法,所以在FruitDAO及其实现类中添加相应的方法:

//修改指定的库存记录
    void updateFruit(Fruit fruit);
public void updateFruit(Fruit fruit) {
        String sql = "update t_fruit set fname = ?, price = ?, fcount = ?, remark = ? where fid = ?";
        super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark(),fruit.getFid());
 }

然后资源跳转,回到index

resp.sendRedirect("index");

此处需要重定向,目的是重新给IndexServlet发请求,重新获取fruitList,然后覆盖到session中。这样主页上显示的数据才是最新的

3. 新增水果库存的实现

add.html的form表单:

<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>

提交后将表单交给AddServlet处理,此时AddServlet获取传来的值,调用DAO的添加库存方法,所以需要向FruitDAO及其实现类添加相应的方法:

//添加一条记录
void addFruit(Fruit fruit);
public void addFruit(Fruit fruit) {
        String sql = "insert into t_fruit values(0,?,?,?,?)";
        super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark());
}

然后在AddServlet中获取表单的指,将其添加到数据库中:

	//1.设置编码
    req.setCharacterEncoding("UTF-8");

    //2.获取客户端传过来的值
    String fname = req.getParameter("fname");
    Integer price = Integer.parseInt(req.getParameter("price"));
    int fcount = Integer.parseInt(req.getParameter("fcount"));
    String remark = req.getParameter("remark");

    //3.添加进入数据库
    fruitDAO.addFruit(new Fruit(0,fname,price,fcount,remark));

然后重定向刷新index

	resp.sendRedirect("index");

4 删除库存功能的实现

在index的del图标上添加鼠标点击的js方法:

<td><img src="imgs/del.jpg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"/></td>
function delFruit(fid){
    if (confirm("是否确认删除?")){
        window.location.href='del.do?fid=' + fid;
    }
}

传入到DelServlet处理

String fidStr = req.getParameter("fid");
	if (StringUtil.isNotEmpty(fidStr)){
	    Integer fid = Integer.parseInt(fidStr);
	    fruitDAO.delFruit(fid);

这里就需要在FruitDAO及其实现类添加删除方法:

//删除指定id的记录
  void delFruit(Integer fid);
public void delFruit(Integer fid) {
   String sql = "delete from t_fruit where fid = ?";
   super.executeUpdate(sql,fid);
}

最后重定向到首页index刷新数据:

resp.sendRedirect("index");

5. 查询功能的实现

index.html相关表单设计

<div style="border:0px solid red; width: 60%; margin-left: 20%; text-align: right; float: left;">
	<form th:action="@{/index}" method="post" style="float: left;">
		<input type="hidden" name="oper" value="search">
		请输入查询的关键字:<input type="text" name="keyword"/>
		<input type="submit" th:value="查询" class="btn">
	</form>
	<a th:href="@{/add.html}" style="border:0px solid blue; margin-bottom: 4px" >添加新库存记录</a>
</div>

将查询的关键字和隐藏域的oper的值传入到IndexServlet中,就查询逻辑设计IndexServlet的逻辑:

 request.setCharacterEncoding("UTF-8");
    Integer pageNo = 1;
    HttpSession session = request.getSession() ;
    String oper = request.getParameter("oper");

    String keyword = null;
    //如果oper是null说明不是通过表单的查询按钮进来的
    //如果oper不是null则说明是通过表单的查询按钮进来的
    if (StringUtil.isNotEmpty(oper) && "search".equals(oper)){
        //说明是点击表单查询提交过来的请求
        //此时pageNo应该还原为1.keyword应该从请求参数中获取
        pageNo = 1;
        keyword = request.getParameter("keyword");
        if (StringUtil.isEmpty(keyword)){
            keyword = "";
        }
        session.setAttribute("keyword",keyword);
    }else {
        //否则就是点击例如上一页、下一页或者直接在地址栏输入网址
        //此时keyword应该从session作用域中获取
        String pageNoStr = request.getParameter("pageNo");
        if (StringUtil.isNotEmpty(pageNoStr)){
            pageNo = Integer.parseInt(pageNoStr);
        }
        Object keywordObj = session.getAttribute("keyword");
        if (keywordObj != null){
            keyword = (String) keywordObj;
        }else {
            keyword = "";
        }
    }

6. 实现效果

主页:
在这里插入图片描述
改:
在这里插入图片描述
增:
在这里插入图片描述
删:
在这里插入图片描述
查:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值