Java web 2022跟学尚硅谷后端基础
回顾知识点
review:
1. post提交方式下的设置编码,防止中文乱码
request.setCharacterEncoding("utf-8");
get提交方式,tomcat8开始,编码不需要设置
tomcat8之前,get方式设置比较麻烦:
String fname = request.getParameter("fname");
byte[] bytes = fname.getBytes("iso-8859-1");
fname = new String(bytes,"UTF-8");
2. Servlet继承关系以及生命周期
1) Servlet接口 : init() , service() , destroy()
GenericServlet抽象子类: abstract service();
HttpServlet抽象子类:实现了service方法,在service方法内部通过request.getMethod()来判断请求的方式,
然后根据请求的方式去调用内部的do方法。每一个do方法进行了简单实现,主要是如果请求方式不符合,则报405错误。
目的是让我们的Servlet子类去重写对应的方法(如果重写的不对,则使用父类的405错误实现)
2) 生命周期:实例化、初始化、服务、销毁
- Tomcat负责维护Servlet实例的生命周期
- 每个Servlet在Tomcat容器中只有一个实例,它是线程不安全的
- Servlet的启动时机:<load-on-startup>
- Servlet3.0开始支持注解: @WebServlet
3. HTTP协议:
1) 由 Request 和 Response 两部分组成
2) 请求包含了三部分:请求行、请求消息头、请求主体: 普通的get方式请求-query string;post方式- form data ; json格式 - request payload
3) 响应包含了三部分:响应行、响应消息头、响应主体
4. HttpSession
1) HttpSession :表示 会话
2) 为什么需要HttpSession , 原因是因为 Http协议是无状态的
3) Session保存作用域 :一次会话范围都有效 ; void session.setAttribute(k,v) ,Object session.getAttribute(k)
4) 其他的API: session.getId() , session.isNew() , session.getCreationTime() , session.invalidate() 等等
5. 服务器端转发和客户端重定向
1) 服务器端转发 : request.getRequestDispatcher("index.html").forward(request,response);
2) 客户端重定向: response.sendRedirect("index.html");
6. thymeleaf的部分标签
1) 使用步骤: 添加jar , 新建ViewBaseServlet(有两个方法) , 配置两个<context-param> : view-prefix , view-suffix
2) 部分标签: <th:if> , <th:unless> , <th:each> , <th:text>
今日内容:
1. 保存作用域
原始情况下,保存作用域我们可以认为有四个: page(页面级别,现在几乎不用) , request(一次请求响应范围) , session(一次会话范围) , application(整个应用程序范围)
1) request:一次请求响应范围
2) session:一次会话范围有效
3) application: 一次应用程序范围有效
2. 路径问题
1) 相对路径
2) 绝对路径
3. 实现库存系统的功能
保存作用域
request:一次请求响应范围
客户端重定向
Demo01Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo01Servlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向request保存作用域保存数据
request.setAttribute("uname", "linda");
response.sendRedirect("demo02");
}
}
Demo02Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo02Servlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object uname = request.getAttribute("uname");
System.out.println(uname);
}
}
输出结果
null
服务器端转发
Demo01Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo01Servlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向request保存作用域保存数据
request.setAttribute("uname", "linda");
// 2.服务器端转发
request.getRequestDispatcher("demo02").forward(request, response);
}
}
Demo02Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo02Servlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object uname = request.getAttribute("uname");
System.out.println(uname);
}
}
输出结果
linda
session一次会话范围有效
一次会话范围内,客户端重定向和服务端转发都可以获取到值
客户端重定向
Demo03Servlet
package com.atguigu.demo;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @ClassName: Demo01Servlet
* @Description: session:一次会话范围有效
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo03")
public class Demo03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向session保存作用域保存数据
HttpSession session = request.getSession();
session.setAttribute("uname", "linda");
// 2.客户端重定向
response.sendRedirect("demo04");
}
}
Demo04Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo02Servlet
* @Description: session:一次会话范围有效
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo04")
public class Demo04Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object uname = request.getSession().getAttribute("uname");
System.out.println(uname);
}
}
输出
linda
服务器端转发
Demo03Servlet
package com.atguigu.demo;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @ClassName: Demo01Servlet
* @Description: session:一次会话范围有效
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo03")
public class Demo03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向session保存作用域保存数据
HttpSession session = request.getSession();
session.setAttribute("uname", "linda");
// 2.服务器端转发
request.getRequestDispatcher("demo04").forward(request, response);
}
}
Demo04Servlet
package com.atguigu.demo;
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;
/**
* @ClassName: Demo02Servlet
* @Description: session:一次会话范围有效
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo04")
public class Demo04Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object uname = request.getSession().getAttribute("uname");
System.out.println(uname);
}
}
输出
linda
application一次应用程序范围有效
客户端重定向
Demo05Servlet
package com.atguigu.demo;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @ClassName: Demo05Servlet
* @Description:application保存作用域
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo05")
public class Demo05Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向application保存作用域保存数据
// ServletContext上下文(Tomcat停止,上下文结束)
ServletContext application = request.getServletContext();
application.setAttribute("uname", "linda");
// 2.客户端重定向
response.sendRedirect("demo06");
}
}
Demo06Servlet
package com.atguigu.demo;
import javax.servlet.ServletContext;
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;
/**
* @ClassName: Demo06Servlet
* @Description:application保存作用域
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo06")
public class Demo06Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取application保存作用域保存的数据
ServletContext application = request.getServletContext();
Object uname = application.getAttribute("uname");
System.out.println(uname);
}
}
输出结果
linda
服务端转发
Demo05Servlet
package com.atguigu.demo;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @ClassName: Demo05Servlet
* @Description:application保存作用域
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo05")
public class Demo05Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.向application保存作用域保存数据
// ServletContext上下文(Tomcat停止,上下文结束)
ServletContext application = request.getServletContext();
application.setAttribute("uname", "linda");
// 2.客户端重定向
//response.sendRedirect("demo06");
// 3.服务器端转发
request.getRequestDispatcher("demo06").forward(request, response);
}
}
Demo06Servlet
package com.atguigu.demo;
import javax.servlet.ServletContext;
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;
/**
* @ClassName: Demo06Servlet
* @Description:application保存作用域
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/demo06")
public class Demo06Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取application保存作用域保存的数据
ServletContext application = request.getServletContext();
Object uname = application.getAttribute("uname");
System.out.println(uname);
}
}
输出
linda
路径问题
水果库存优化1.5增删改功能添加
界面展示
添加
删除
修改
代码展示
后台修改相关代码
AddServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName: AddServlet
* @Description:
* @Author: wty
* @Date: 2022/12/6
*/
@WebServlet("/add.do")
public class AddServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
processTemplate("add", request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 获取参数
String fname = request.getParameter("fname");
String priceStr = request.getParameter("price");
Integer price = Integer.parseInt(priceStr);
String fcountStr = request.getParameter("fcount");
Integer fcount = Integer.parseInt(fcountStr);
String remark = request.getParameter("remark");
fruitService.addFruit(new Fruit(0, fname, price, fcount, remark));
response.sendRedirect("index");
}
}
DelServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.service.FruitService;
import com.atguigu.uils.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName: DelServlet
* @Description:
* @Author: wty
* @Date: 2022/12/6
*/
@WebServlet("/del.do")
public class DelServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fidStr = request.getParameter("fid");
if (StringUtils.isNotEmpty(fidStr)) {
Integer fid = Integer.parseInt(fidStr);
//fruitService
fruitService.delFruitByFid(fid);
response.sendRedirect("index");
}
}
}
EditServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import com.atguigu.uils.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName: EditServlet
* @Description:
* @Author: wty
* @Date: 2022/12/6
*/
@WebServlet("/edit.do")
public class EditServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fidStr = request.getParameter("fid");
if (StringUtils.isNotEmpty(fidStr)) {
Integer fid = Integer.parseInt(fidStr);
Fruit fruit = fruitService.getFruitByFid(fid);
request.setAttribute("fruit", fruit);
processTemplate("edit", request, response);
}
}
}
IndexServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
/**
* @ClassName: IndexServlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Fruit> fruitList = fruitService.getFruitList();
// 保存到session作用域
HttpSession session = request.getSession();
session.setAttribute("fruitList", fruitList);
// 此处的视图名称是index
// thymeleaf会将这个逻辑视图名称对应到物理视图名称中去
// 物理视图名称 = view-prefix + 逻辑视图名称 + view-suffix
// 所以真实视图名称: /index.html
super.processTemplate("index", request, response);
}
}
UpdateServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName: UpdateServlet
* @Description:
* @Author: wty
* @Date: 2022/12/6
*/
@WebServlet("/update.do")
public class UpdateServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 获取参数
String fidStr = request.getParameter("fid");
Integer fid = Integer.parseInt(fidStr);
String fname = request.getParameter("fname");
String priceStr = request.getParameter("price");
Integer price = Integer.parseInt(priceStr);
String fcountStr = request.getParameter("fcount");
Integer fcount = Integer.parseInt(fcountStr);
String remark = request.getParameter("remark");
// 执行更新
fruitService.updateFruitByFid(new Fruit(fid, fname, price, fcount, remark));
// 资源跳转
//processTemplate("index", request, response);
// 此处需要重定向,目的是重新给indexServlet发请求,重新获取fruitList然后覆盖到session中的数据才是最新的
response.sendRedirect("index");
}
}
FruitService
package com.atguigu.fruit.service;
import com.atguigu.fruit.dao.FruitDAO;
import com.atguigu.fruit.pojo.Fruit;
import java.util.List;
/**
* @ClassName: FruitService
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
public class FruitService {
FruitDAO fruitDAO = new FruitDAO();
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 查询库存列表
* @date 2022/12/4 19:08
* @author wty
**/
public List<Fruit> getFruitList() {
String sqlStr = "select * from t_fruit";
return fruitDAO.queryMulti(sqlStr, Fruit.class);
}
/**
* @param
* @return boolean
* @description 添加库存
* @param: fruit
* @date 2022/12/4 19:11
* @author wty
**/
public boolean addFruit(Fruit fruit) {
String sqlStr = "insert into t_fruit values(0,?,?,?,?)";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 更新某水果的库存数量
* @param: fruit
* @date 2022/12/4 19:12
* @author wty
**/
public boolean updateFruit(Fruit fruit) {
String sqlStr = "update t_fruit set fcount = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFcount(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return com.atguigu.fruit.pojo.Fruit
* @description 根据水果的名字,获取一行的详细信息
* @param: fname
* @date 2022/12/4 19:13
* @author wty
**/
public Fruit getFruitByFname(String fname) {
String sqlStr = "select * from t_fruit where fname like ?";
Fruit fruit = fruitDAO.querySingle(sqlStr, Fruit.class, fname);
return fruit;
}
/**
* @param
* @return boolean
* @description 根据名字删除某个水果的信息
* @param: fname
* @date 2022/12/4 19:15
* @author wty
**/
public boolean delFruit(String fname) {
String sqlStr = "delete from t_fruit where fname like ?";
int affectedrows = fruitDAO.dml(sqlStr, fname);
return affectedrows > 0;
}
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 通过fid查询水果的详细信息
* @param: fid
* @date 2022/12/6 0:19
* @author wty
**/
public Fruit getFruitByFid(Integer fid) {
String sqlStr = "select * from t_fruit where fid = ?";
return fruitDAO.querySingle(sqlStr, Fruit.class, fid);
}
/**
* @param
* @return boolean
* @description 根据fid更新表中的所有行数据
* @param: fruit
* @date 2022/12/6 13:55
* @author wty
**/
public boolean updateFruitByFid(Fruit fruit) {
String sqlStr = "update t_fruit set fname = ?, price = ?, fcount = ?, remark = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 根据fid删除当前行
* @param: fid
* @date 2022/12/6 13:56
* @author wty
**/
public boolean delFruitByFid(Integer fid) {
String sqlStr = "delete from t_fruit where fid = ?";
int affectedrows = fruitDAO.dml(sqlStr, fid);
return affectedrows > 0;
}
}
前台修改相关代码
add.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<link rel="stylesheet" href="css/add.css" type="text/css"></link>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center_p f32">添加库存信息</p>
<form th:action="@{/add.do}" method="post">
<table id="table_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>
add.css
div {
position: relative;
float: left;
}
#div_container {
height: 100%;
width: 80%;
border: 1px solid blue;
margin-left: 10%;
background-color: honeydew;
float: left;
border-radius: 8px;
}
#table_fruit {
width: 80%;
/* 边框合并 */
border-collapse: collapse;
line-height: 28px;
margin-top: 60px;
margin-left: 40%;
background-color: ghostwhite;
}
#table_fruit tr, #table_fruit td, #table_fruit th {
border: 1px solid gray;
text-align: center;
font-size: 16px;
font-family: "黑体";
font-weight: lighter;
}
/* 表头字体大一号 */
#table_fruit th {
font-size: 20px;
background-color: lightgray;
}
/* 表格每一列占比设置 */
.w20 {
width: 40%;
}
body {
margin: 0;
padding: 0;
background-color: gray;
}
.center_p {
margin-left: 400px;
}
.f32 {
font-size: 32px;
}
edit.css
div {
position: relative;
float: left;
}
#div_container {
height: 100%;
width: 80%;
border: 1px solid blue;
margin-left: 10%;
background-color: honeydew;
float: left;
border-radius: 8px;
}
#table_fruit {
width: 80%;
/* 边框合并 */
border-collapse: collapse;
line-height: 28px;
margin-top: 60px;
margin-left: 40%;
background-color: ghostwhite;
}
#table_fruit tr, #table_fruit td, #table_fruit th {
border: 1px solid gray;
text-align: center;
font-size: 16px;
font-family: "黑体";
font-weight: lighter;
}
/* 表头字体大一号 */
#table_fruit th {
font-size: 20px;
background-color: lightgray;
}
/* 表格每一列占比设置 */
.w20 {
width: 40%;
}
body {
margin: 0;
padding: 0;
background-color: gray;
}
.center_p {
margin-left: 350px;
}
.f32 {
font-size: 32px;
}
index.css
div {
position: relative;
float: left;
}
#div_container {
height: 100%;
width: 80%;
border: 1px solid blue;
margin-left: 10%;
background-color: honeydew;
float: left;
border-radius: 8px;
}
#table_fruit {
width: 60%;
/* 边框合并 */
border-collapse: collapse;
line-height: 28px;
margin-top: 60px;
margin-left: 20%;
background-color: ghostwhite;
}
#table_fruit tr, #table_fruit td, #table_fruit th {
border: 1px solid gray;
text-align: center;
font-size: 16px;
font-family: "黑体";
font-weight: lighter;
}
/* 表头字体大一号 */
#table_fruit th {
font-size: 20px;
background-color: lightgray;
}
/* 表格每一列占比设置 */
.w20 {
width: 40%;
}
/* 删除图标样式设置 */
.delImg {
width: 35px;
height: 35px;
margin-top: 5px;
margin-left: 5px;
}
body {
margin: 0;
padding: 0;
background-color: gray;
}
.center_p {
text-align: center;
}
.f32 {
font-size: 32px;
}
/* 添加库存记录超链接底下没有下划线 */
a {
text-decoration: none;
}
/* 添加库存记录 */
#div_add {
border: 0px solid red;
margin-left: 600px;
}
edit.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<link rel="stylesheet" href="css/edit.css" type="text/css"></link>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center_p f32">编辑库存信息</p>
<form th:action="@{/update.do}" method="post" th:object="${fruit}">
<!--隐藏域:功能类似于文本框,它的值会随着表单的发送也会发送给服务器,但是界面上用户看不到-->
<input type="hidden" name="fid" th:value="*{fid}"/>
<table id="table_fruit">
<tr>
<th class="w20">名称:</th>
<!--<td><input type="text" name="fname" th:value="${fruit.fname}"></td>-->
<td><input type="text" name="fname" th:value="*{fname}"/></td>
</tr>
<tr>
<th class="w20">单价</th>
<!--<td><input type="text" name="price" th:value="${fruit.price}"></td>-->
<td><input type="text" name="price" th:value="*{price}"/></td>
</tr>
<tr>
<th class="w20">库存</th>
<!--<td><input type="text" name="fcount" th:value="${fruit.fcount}"></td>-->
<td><input type="text" name="fcount" th:value="*{fcount}"/></td>
</tr>
<tr>
<th class="w20">备注</th>
<!--<td><input type="text" name="remark" th:value="${fruit.remark}"></td>-->
<td><input type="text" name="remark" th:value="*{remark}"/></td>
</tr>
<tr>
<th colspan="2">
<input type="submit" value="修改"/>
</th>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/index.css"></link>
<script language="JavaScript" src="js/index.js"></script>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center_p f32">欢迎使用水果库存后台管理系统</p>
<div id="div_add">
<a th:href="@{/add.do}">添加库存记录</a>
</div>
<table id="table_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">库存</th>
<th class="w20">操作</th>
</tr>
<tr th:if="${#lists.isEmpty(session.fruitList)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
<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><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.jpeg" class="delImg" th:οnclick="'delFruit('+${fruit.fid}+')'"></img></td>-->
<td><img src="imgs/del.jpeg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"></img></td>
</tr>
</table>
</div>
</div>
</body>
</html>
水果库存继续优化1.6分页
界面展示
index.css
div {
position: relative;
float: left;
}
#div_container {
height: 100%;
width: 80%;
border: 1px solid blue;
margin-left: 10%;
background-color: honeydew;
float: left;
border-radius: 8px;
}
#table_fruit {
width: 60%;
/* 边框合并 */
border-collapse: collapse;
line-height: 28px;
margin-top: 60px;
margin-left: 20%;
background-color: ghostwhite;
}
#table_fruit tr, #table_fruit td, #table_fruit th {
border: 1px solid gray;
text-align: center;
font-size: 16px;
font-family: "黑体";
font-weight: lighter;
}
/* 表头字体大一号 */
#table_fruit th {
font-size: 20px;
background-color: lightgray;
}
/* 表格每一列占比设置 */
.w20 {
width: 40%;
}
/* 删除图标样式设置 */
.delImg {
width: 35px;
height: 35px;
margin-top: 5px;
margin-left: 5px;
}
body {
margin: 0;
padding: 0;
background-color: gray;
}
.center_p {
text-align: center;
}
.f32 {
font-size: 32px;
}
/* 添加库存记录超链接底下没有下划线 */
a {
text-decoration: none;
}
/* 添加库存记录 */
#div_add, #div_page {
border: 0px solid red;
margin-left: 600px;
}
/* 分页查询 */
#div_page {
border: 0px solid red;
margin-top: 30px;
margin-left: 450px;
}
index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/index.css"></link>
<script language="JavaScript" src="js/index.js"></script>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center_p f32">欢迎使用水果库存后台管理系统</p>
<div id="div_add">
<a th:href="@{/add.do}">添加库存记录</a>
</div>
<table id="table_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">库存</th>
<th class="w20">操作</th>
</tr>
<tr th:if="${#lists.isEmpty(session.fruitList)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
<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><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.jpeg" class="delImg" th:οnclick="'delFruit('+${fruit.fid}+')'"></img></td>-->
<td><img src="imgs/del.jpeg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"></img></td>
</tr>
</table>
<div id="div_page">
<div>
<input type="button" value="首 页" th:onclick="page(1)" th:disabled="${session.pageNumber==1}"></input>
<input type="button" value="上一页" th:onclick="|page(${session.pageNumber - 1})|"
th:disabled="${session.pageNumber==1}"></input>
<input type="button" value="下一页" th:onclick="|page(${session.pageNumber + 1})|"
th:disabled="${session.pageNumber==session.pageCount}"></input>
<input type="button" value="尾 页" th:onclick="|page(${session.pageCount})|"
th:disabled="${session.pageNumber==session.pageCount}"></input>
</div>
</div>
</div>
</div>
</body>
</html>
IndexServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import com.atguigu.uils.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
/**
* @ClassName: IndexServlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 非分页,显示全部
// List<Fruit> fruitList = fruitService.getFruitList();
// 分页查询(增加参数pageNumber)
Integer pageNumber = 1;
String pageNumberStr = request.getParameter("pageNumber");
if (StringUtils.isNotEmpty(pageNumberStr)) {
pageNumber = Integer.parseInt(pageNumberStr);
}
HttpSession session = request.getSession();
session.setAttribute("pageNumber", pageNumber);
List<Fruit> fruitList = fruitService.getFruitList(pageNumber);
// 获取总条数
int sum = fruitService.getFruitCount();
// 获取总页数pageCount
session.setAttribute("pageCount", ((sum + 5 - 1) / 5));
// 保存到session作用域
//HttpSession session = request.getSession();
session.setAttribute("fruitList", fruitList);
// 此处的视图名称是index
// thymeleaf会将这个逻辑视图名称对应到物理视图名称中去
// 物理视图名称 = view-prefix + 逻辑视图名称 + view-suffix
// 所以真实视图名称: /index.html
super.processTemplate("index", request, response);
}
}
FruitService
package com.atguigu.fruit.service;
import com.atguigu.fruit.dao.FruitDAO;
import com.atguigu.fruit.pojo.Fruit;
import java.util.List;
/**
* @ClassName: FruitService
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
public class FruitService {
FruitDAO fruitDAO = new FruitDAO();
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 查询库存列表
* @date 2022/12/4 19:08
* @author wty
**/
public List<Fruit> getFruitList() {
String sqlStr = "select * from t_fruit";
return fruitDAO.queryMulti(sqlStr, Fruit.class);
}
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 重载上述方法,支持分页查询所有水果库存,每页显示5条数据
* @param: pageNumber
* @date 2022/12/6 15:31
* @author wty
**/
public List<Fruit> getFruitList(Integer pageNumber) {
String sqlStr = "select * from t_fruit limit ?,5";
return fruitDAO.queryMulti(sqlStr, Fruit.class, (pageNumber - 1) * 5);
}
/**
* @param
* @return boolean
* @description 添加库存
* @param: fruit
* @date 2022/12/4 19:11
* @author wty
**/
public boolean addFruit(Fruit fruit) {
String sqlStr = "insert into t_fruit values(0,?,?,?,?)";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 更新某水果的库存数量
* @param: fruit
* @date 2022/12/4 19:12
* @author wty
**/
public boolean updateFruit(Fruit fruit) {
String sqlStr = "update t_fruit set fcount = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFcount(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return com.atguigu.fruit.pojo.Fruit
* @description 根据水果的名字,获取一行的详细信息
* @param: fname
* @date 2022/12/4 19:13
* @author wty
**/
public Fruit getFruitByFname(String fname) {
String sqlStr = "select * from t_fruit where fname like ?";
Fruit fruit = fruitDAO.querySingle(sqlStr, Fruit.class, fname);
return fruit;
}
/**
* @param
* @return boolean
* @description 根据名字删除某个水果的信息
* @param: fname
* @date 2022/12/4 19:15
* @author wty
**/
public boolean delFruit(String fname) {
String sqlStr = "delete from t_fruit where fname like ?";
int affectedrows = fruitDAO.dml(sqlStr, fname);
return affectedrows > 0;
}
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 通过fid查询水果的详细信息
* @param: fid
* @date 2022/12/6 0:19
* @author wty
**/
public Fruit getFruitByFid(Integer fid) {
String sqlStr = "select * from t_fruit where fid = ?";
return fruitDAO.querySingle(sqlStr, Fruit.class, fid);
}
/**
* @param
* @return boolean
* @description 根据fid更新表中的所有行数据
* @param: fruit
* @date 2022/12/6 13:55
* @author wty
**/
public boolean updateFruitByFid(Fruit fruit) {
String sqlStr = "update t_fruit set fname = ?, price = ?, fcount = ?, remark = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 根据fid删除当前行
* @param: fid
* @date 2022/12/6 13:56
* @author wty
**/
public boolean delFruitByFid(Integer fid) {
String sqlStr = "delete from t_fruit where fid = ?";
int affectedrows = fruitDAO.dml(sqlStr, fid);
return affectedrows > 0;
}
public int getFruitCount() {
String sqlStr = "select count(*) from t_fruit";
Object o = fruitDAO.queryScalar(sqlStr);
Integer i = 0;
if (o instanceof Long) {
i = ((Long) o).intValue();
}
return i;
}
}
水果库存继续优化1.7支持模糊查询
页面展示
index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/index.css"></link>
<script language="JavaScript" src="js/index.js"></script>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center_p f32">欢迎使用水果库存后台管理系统</p>
<div id="div_add">
<form id="form_search" th:action="@{/index}" method="post">
<input type="hidden" name="oper" value="search"></input>
请输入查询关键字:<input type="text" name="keyword" th:value="${session.keyword}"></input>
<input type="submit" value="查询"></input>
</form>
<a th:href="@{/add.do}" id="a_add">添加库存记录</a>
</div>
<table id="table_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">库存</th>
<th class="w20">操作</th>
</tr>
<tr th:if="${#lists.isEmpty(session.fruitList)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
<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><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.jpeg" class="delImg" th:οnclick="'delFruit('+${fruit.fid}+')'"></img></td>-->
<td><img src="imgs/del.jpeg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"></img></td>
</tr>
</table>
<div id="div_page">
<div>
<input type="button" value="首 页" th:onclick="page(1)" th:disabled="${session.pageNumber==1}"></input>
<input type="button" value="上一页" th:onclick="|page(${session.pageNumber - 1})|"
th:disabled="${session.pageNumber==1}"></input>
<input type="button" value="下一页" th:onclick="|page(${session.pageNumber + 1})|"
th:disabled="${session.pageNumber==session.pageCount}"></input>
<input type="button" value="尾 页" th:onclick="|page(${session.pageCount})|"
th:disabled="${session.pageNumber==session.pageCount}"></input>
</div>
</div>
</div>
</div>
</body>
</html>
IndexServlet
package com.atguigu.fruit.servlets;
import com.atguigu.fruit.myspringmvc.ViewBaseServlet;
import com.atguigu.fruit.pojo.Fruit;
import com.atguigu.fruit.service.FruitService;
import com.atguigu.uils.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
/**
* @ClassName: IndexServlet
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
private FruitService fruitService = new FruitService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
List<Fruit> fruitList = null;
// 分页查询(增加参数pageNumber)
Integer pageNumber = 1;
int sum = 0;
HttpSession session = request.getSession();
// 模糊查询
String oper = request.getParameter("oper");
String keyword = null;
if (StringUtils.isNotEmpty(oper) && "search".equals(oper)) {
// 相当于是模糊查询
keyword = request.getParameter("keyword");
if (StringUtils.isEmpty(keyword)) {
keyword = "";
}
//fruitList = fruitService.getFruitByFnameList(keyword);
pageNumber = 1;
} else {
// 说明此处不是模糊查询,此时keyword应该从session作用域获取
// 分页查询(增加参数pageNumber)
String pageNumberStr = request.getParameter("pageNumber");
if (StringUtils.isNotEmpty(pageNumberStr)) {
pageNumber = Integer.parseInt(pageNumberStr);
}
Object keywordObj = session.getAttribute("keyword");
if (null != keywordObj) {
keyword = (String) keywordObj;
} else {
keyword = "";
}
//fruitList = fruitService.getFruitList(pageNumber);
// 获取总条数
//sum = fruitService.getFruitCount();
}
session.setAttribute("keyword", keyword);
fruitList = fruitService.getFruitList(pageNumber, keyword);
// 非分页,显示全部
// List<Fruit> fruitList = fruitService.getFruitList();
session.setAttribute("pageNumber", pageNumber);
// 获取总条数
sum = fruitService.getFruitCount(keyword);
// 获取总页数pageCount
session.setAttribute("pageCount", ((sum + 5 - 1) / 5));
// 保存到session作用域
//HttpSession session = request.getSession();
session.setAttribute("fruitList", fruitList);
// 此处的视图名称是index
// thymeleaf会将这个逻辑视图名称对应到物理视图名称中去
// 物理视图名称 = view-prefix + 逻辑视图名称 + view-suffix
// 所以真实视图名称: /index.html
super.processTemplate("index", request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
FruitService
package com.atguigu.fruit.service;
import com.atguigu.fruit.dao.FruitDAO;
import com.atguigu.fruit.pojo.Fruit;
import java.util.List;
/**
* @ClassName: FruitService
* @Description:
* @Author: wty
* @Date: 2022/12/5
*/
public class FruitService {
FruitDAO fruitDAO = new FruitDAO();
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 查询库存列表
* @date 2022/12/4 19:08
* @author wty
**/
public List<Fruit> getFruitList() {
String sqlStr = "select * from t_fruit";
return fruitDAO.queryMulti(sqlStr, Fruit.class);
}
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 重载上述方法,支持分页查询所有水果库存,每页显示5条数据--支持模糊查询
* @param: pageNumber
* @date 2022/12/6 15:31
* @author wty
**/
public List<Fruit> getFruitList(Integer pageNumber, String keyword) {
String sqlStr = "select * from t_fruit where fname like ? or remark like ? limit ?,5";
return fruitDAO.queryMulti(sqlStr, Fruit.class, "%" + keyword + "%", "%" + keyword + "%", (pageNumber - 1) * 5);
}
/**
* @param
* @return boolean
* @description 添加库存
* @param: fruit
* @date 2022/12/4 19:11
* @author wty
**/
public boolean addFruit(Fruit fruit) {
String sqlStr = "insert into t_fruit values(0,?,?,?,?)";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 更新某水果的库存数量
* @param: fruit
* @date 2022/12/4 19:12
* @author wty
**/
public boolean updateFruit(Fruit fruit) {
String sqlStr = "update t_fruit set fcount = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFcount(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return com.atguigu.fruit.pojo.Fruit
* @description 根据水果的名字,获取一行的详细信息
* @param: fname
* @date 2022/12/4 19:13
* @author wty
**/
public Fruit getFruitByFname(String fname) {
String sqlStr = "select * from t_fruit where fname like ?";
Fruit fruit = fruitDAO.querySingle(sqlStr, Fruit.class, fname);
return fruit;
}
/**
* @param
* @return boolean
* @description 根据名字删除某个水果的信息
* @param: fname
* @date 2022/12/4 19:15
* @author wty
**/
public boolean delFruit(String fname) {
String sqlStr = "delete from t_fruit where fname like ?";
int affectedrows = fruitDAO.dml(sqlStr, fname);
return affectedrows > 0;
}
/**
* @param
* @return java.util.List<com.atguigu.fruit.pojo.Fruit>
* @description 通过fid查询水果的详细信息
* @param: fid
* @date 2022/12/6 0:19
* @author wty
**/
public Fruit getFruitByFid(Integer fid) {
String sqlStr = "select * from t_fruit where fid = ?";
return fruitDAO.querySingle(sqlStr, Fruit.class, fid);
}
/**
* @param
* @return boolean
* @description 根据fid更新表中的所有行数据
* @param: fruit
* @date 2022/12/6 13:55
* @author wty
**/
public boolean updateFruitByFid(Fruit fruit) {
String sqlStr = "update t_fruit set fname = ?, price = ?, fcount = ?, remark = ? where fid = ? ";
int affectedrows = fruitDAO.dml(sqlStr, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark(), fruit.getFid());
return affectedrows > 0;
}
/**
* @param
* @return boolean
* @description 根据fid删除当前行
* @param: fid
* @date 2022/12/6 13:56
* @author wty
**/
public boolean delFruitByFid(Integer fid) {
String sqlStr = "delete from t_fruit where fid = ?";
int affectedrows = fruitDAO.dml(sqlStr, fid);
return affectedrows > 0;
}
/**
* @param
* @return int
* @description 查询总条数--支持模糊查询
* @date 2022/12/6 22:45
* @author wty
**/
public int getFruitCount(String keyword) {
String sqlStr = "select count(*) from t_fruit where fname like ? or remark like ?";
Object o = fruitDAO.queryScalar(sqlStr, "%" + keyword + "%", "%" + keyword + "%");
Integer i = 0;
if (o instanceof Long) {
i = ((Long) o).intValue();
}
return i;
}
}