家居购项目
🐇servlet合并
需求
1.如果处理一个请求, 就对应一个Servlet, 会造成Servlet文件太多, 不利于管理.
2.在项目开发中, 同一个业务(模块), 一般对应一个Servlet即可, 比如LoginServlet, RegisterServlet, 都是在处理和会员相关的业务, 应当合并.
🍎方案一: 隐藏域
1.给login和register表单增加hidden元素, 区分登录和注册.
2但信息提交到MemberServlet后, 获取action参数值
3.分发请求.
代码实现
1.修改web/views/member/login.jsp
, 增加隐藏域, 修改请求url为memberServlet
2.新建src/com/zzw/furns/web/MemberServlet.java
, 合并到MemberServlet
public class MemberServlet extends HttpServlet {
private MemberService memberService = new MemberServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if ("login".equals(action)) {
login(request, response);
} else if ("register".equals(action)) {
register(request, response);
} else {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h1>404</h1>");
}
}
protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
Member member = new Member(null, username, password, null);
if (member != null) {
System.out.println("登录成功");
request.getRequestDispatcher("/views/member/login_ok.jsp").forward(request, response);
} else {
System.out.println("登录失败");
request.setAttribute("msg", "用户名或密码错误,请重新登录");
request.setAttribute("username", username);
request.getRequestDispatcher(request.getHeader("Referer")).forward(request, response);
}
}
protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
Member member = new Member(null, username, password, email);
if (!memberService.isExistsByUsername(username)) {
//用户名可用
if (memberService.registerMember(member)) {
//注册成功
System.out.println("注册成功,请登录");
request.getRequestDispatcher("/views/member/register_ok.jsp").forward(request, response);
} else {
//注册失败
System.out.println("注册失败,请重新注册");
request.getRequestDispatcher("/views/member/register_fail.jsp").forward(request, response);
}
} else {
request.setCharacterEncoding("UTF-8");
request.setAttribute("msg", "用户名已存在,请重新注册");
request.setAttribute("username", username);
request.setAttribute("active", "register_tab");
request.getRequestDispatcher("/views/member/login.jsp").forward(request, response);
}
}
}
3.测试…
🍎方案二: 反射+模板设计模式+动态代理
1.新建BasicServlet类, 继承HttpServlet
public class BasicServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("action");
try {
//1.得到子类对应的class对象
Class<? extends BasicServlet> aClass = this.getClass();
//2.创建对象
Object o = aClass.newInstance();
//3.得到action方法对象
Method declaredMethod = this.getClass()
.getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
declaredMethod.invoke(o, req, resp);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.子类中没有doGet, doPost方法, 会调用父类的doGet, doPost.
🌳显示家居
需求分析
1.给后台管理提供独立登陆页面 [manage_login.jsp(已提供)
2.管理员(admin表)登陆成功后, 显示管理菜单页面
3.管理员点击家居管理, 显示所有家居信息
程序框架图
1.页面准备
2.新建admin表 👉 参考member表
-- 创建会员表
CREATE TABLE admin (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32) NOT NULL DEFAULT '' UNIQUE,
`password` VARCHAR(32) NOT NULL,
email VARCHAR(64)
)CHARSET utf8 ENGINE INNODB;
-- 插入数据
INSERT INTO admin VALUES(NULL, 'admin', MD5('admin'), '978964140@qq.com');
INSERT INTO admin VALUES(NULL, 'zhaozhiwei', MD5('zhaozhiwei'), '978964140@qq.com');
INSERT INTO admin(id, username, `password`, email) VALUES(NULL, 'tom', MD5('tom'), 'tom@sohu.com');
-- 查询
SELECT * FROM admin;
SELECT id, username, `password`, email FROM admin WHERE username = 'admine'
SELECT id, username, `password`, email FROM admin WHERE username = 'admin123' AND `password` = MD5('123456');
UPDATE admin SET `password`=MD5('admin') WHERE username='admin';
3.新建furn表
-- 创建家居网购需要的数据库和表
-- 删除数据库
DROP DATABASE IF EXISTS home_furnishing;
-- 删除表
DROP TABLE furn;
-- 创建数据库
CREATE DATABASE home_furnishing;
-- 切换
USE home_furnishing;
-- id int(11) 11表示的是宽度
-- id int(2) 2表示的也是宽度
-- 66360 -> int(11) 00000066360
-- 66360 -> int(2) 66360
-- unsigned 无符号类型,表示的范围大一些
-- 创建家居表
CREATE TABLE furn (
id INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT, -- id编号
`name` VARCHAR(32) NOT NULL,-- 家居名
business VARCHAR(32) NOT NULL,-- 商家
price DECIMAL(10, 2) NOT NULL,-- 价格
saleNum INT UNSIGNED NOT NULL,-- 销量
inventory INT UNSIGNED NOT NULL,-- 库存
image_path VARCHAR(256) NOT NULL -- 图片
)CHARSET utf8 ENGINE INNODB;
-- 插入数据
insert into `furn` (`id`, `name`, `business`, `price`, `saleNum`, `inventory`, `image_path`) values('1','小台灯','南极人','35.50','3002','6998','assets/images/product-image/default.jpg');
insert into `furn` (`id`, `name`, `business`, `price`, `saleNum`, `inventory`, `image_path`) values('2','黑丝袜','南极人','25.50','4002','5998','assets/images/product-image/default.jpg');
insert into `furn` (`id`, `name`, `business`, `price`, `saleNum`, `inventory`, `image_path`) values('3','胸罩','南极人','45.50','5002','4998','assets/images/product-image/default.jpg');
-- 查询数据
SELECT id, `name`, business, price, saleNum, inventory, image_path FROM furn WHERE `name` = '小台灯' LIMIT 1, 3;
SELECT id, `name`, business, price, saleNum, inventory, image_path FROM furn
SELECT COUNT(*) FROM furn WHERE `name` LIKE '%台%';
-- 删除数据
DELETE FROM furn WHERE id = 32;
-- 修改数据
UPDATE furn SET image_path = 'assets/images/product-image/default.jpg';
UPDATE furn SET `name`='手机', business='小米', price=3000, saleNum=9000, inventory=9000, image_path='zzw' WHERE id=37
UPDATE furn SET `name`='笔记本', business='戴尔', price=6000.00, saleNum=6500, inventory=5500 WHERE id=75;
4.新建Admin实体类 src/com/zzw/furns/entity/Admin.java
public class Admin {
private Integer id;
private String username;
private String password;
private String email;
public Admin() {
}
}
5.新建Furn实体类(无参构造器与set方法底层反射用, get方法前端EL表达式用) src/com/zzw/furns/entity/Furn.java
public class Furn {
private String name;
private String business;
private BigDecimal price;//Decimal对应BigDecimal
private Integer saleNum;
private Integer inventory;
private String imagePath;
public Furn() {
}
}
6.新建src/com/zzw/furns/dao/AdminDao.java
public interface AdminDAO {
//根据用户名和密码查询数据库中有无对应的Admin对象
public Admin queryAdminByUsernameAndPassword(String username, String password);
}
7.新建src/com/zzw/furns/dao/impl/AdminDaoImpl.java
public class AdminDAOImpl extends BasicDAO<Admin> implements AdminDAO {
/**
* 根据用户名和密码查询对应的Admin对象
* @param username 用户名
* @param password 密码
* @return 对应的Admin对象, 如果没有 则返回null
*/
@Override
public Admin queryAdminByUsernameAndPassword(String username, String password) {
String sql = "SELECT id, username, `password`, email FROM admin WHERE username = ? AND `password` = MD5(?)";
Admin admin = querySingle(sql, Admin.class, username, password);
return admin;
}
}
8.测试, 新建src/com/zzw/furns/test/AdminDAOTest.java
public class AdminDAOTest {
private AdminDAO adminDAO = new AdminDAOImpl();
@Test
public void queryAdminByUsernameAndPassword() {
String username = "zhaozhiwei";
String password = "123123";
Admin admin = adminDAO.queryAdminByUsernameAndPassword(username, password);
System.out.println(admin);
}
}
9.新建src/com/zzw/furns/service/AdminService.java
public interface AdminService {
/**
* 根据传入的admin信息, 返回对应在DB中的admin对象
* @param admin 是根据用户登录构建一个admin
* @return 返回的是对应的DB中的admin对象, 如果不存在返回null
*/
public Admin login(Admin admin);
}
10.新建src/com/zzw/furns/service/AdminServiceImpl.java
public class AdminServiceImpl implements AdminService {
private AdminDAO adminDAO = new AdminDAOImpl();
/**
* 判断用户名和密码是否存在
* @param username 用户名
* @param password 密码
* @return
*/
@Override
public Admin login(Admin admin) {
//返回一个对象
return adminDAO.
queryAdminByUsernameAndPassword(admin.getUsername(), admin.getPassword());
}
}
11.测试, 新建src/com/zzw/furns/test/AdminServiceTest.java
public class AdminServiceTest {
private AdminService adminService = new AdminServiceImpl();
@Test
public void login() {
Admin admin = new Admin(null, "zhaozhiwei", "123123", null);
Admin login = adminService.login(admin);
System.out.println("login = " + login);
}
}
12.新建src/com/zzw/furns/dao/FurnDao.java
public interface FurnDAO {
//返回所有Furn对象
public List<Furn> list();
}
13.新建src/com/zzw/furns/dao/impl/FurnDaoImpl.java
给字段起别名, 对应实体类的某一个属性
public class FurnDAOImpl extends BasicDAO<Furn> implements FurnDAO {
@Override
public List<Furn> listAll() {
String sql = "SELECT id, `name`, business, price, saleNum, inventory, image_path as imagePath FROM furn";
List<Furn> furns = queryMany(sql, Furn.class);
return furns;
}
}
14.测试, 新建src/com/zzw/furns/test/FurnDaoTest.java
public class FurnDAOTest {
private FurnDAO furnDAO = new FurnDAOImpl();
@Test
public void listAll() {
List<Furn> furns = furnDAO.listAll();
for (Furn furn : furns) {
System.out.println(furn);
}
}
}
15.新建src/com/zzw/furns/service/FurnService.java
public interface FurnService {
//显示家居
public List<Furn> queryFurn();
}
16.新建src/com/zzw/furns/service/AdminServiceImpl.java
public class FurnServiceImpl implements FurnService {
private FurnDAO furnDAO = new FurnDAOImpl();
@Override
public List<Furn> queryFurn() {
List<Furn> furns = furnDAO.listAll();
return furns;
}
}
17.测试, 新建src/com/zzw/furns/test/AdminServiceTest.java
public class FurnServiceTest {
private FurnService furnService = new FurnServiceImpl();
@Test
public void queryFurn() {
List<Furn> furns = furnService.queryFurn();
for (int i = 0; i < furns.size(); i++) {
System.out.println(furns.get(i));
}
}
}
18.接通web层, 创建src/com/zzw/furns/web/AdminServlet.java
, 管理员登录Servlet
public class AdminServlet extends BasicServlet {
private AdminService adminService = new AdminServiceImpl();
protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//如果在登陆界面用户没有输入内容, 后台接收到的是""
String username = request.getParameter("username");
String password = request.getParameter("password");
Admin admin = new Admin(null, username, password, null);
admin = adminService.login(admin);
if (admin != null) {//用户存在DB
System.out.println("管理员登陆成功...");
request.getRequestDispatcher("/views/manage/manage_menu.jsp")
.forward(request, response);
} else {//用户不存在
System.out.println("该管理员用户不存在, 登陆失败");
request.setAttribute("username", username);
request.setAttribute("errorMsg", "用户名或密码不正确");
request.getRequestDispatcher("/views/manage/manage_login.jsp")
.forward(request, response);
}
}
}
配置web.xml
<servlet>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>com.zzw.furns.web.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/adminServlet</url-pattern>
</servlet-mapping>
19.创建src/com/zzw/furns/web/FurnServlet.java
, 家居显示Servlet
public class FurnServlet extends BasicServlet {
private FurnService furnService = new FurnServiceImpl();
protected void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Furn> furns = furnService.queryFurn();
//将结果保存到request域
request.setAttribute("furns", furns);
//请求转发到管理家具页面
request.getRequestDispatcher("/views/manage/furn_manage.jsp")
.forward(request, response);
}
}
配置web.xml
<servlet>
<servlet-name>FurnServlet</servlet-name>
<servlet-class>com.zzw.furns.web.FurnServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FurnServlet</servlet-name>
<url-pattern>/manage/furnServlet</url-pattern>
</servlet-mapping>
20.前端页面, web/views/manage/manage_login.jsp
, 管理员登录页面
<span class="errorMsg"
style="float: right; font-weight: bold; color: lightgray; font-size: 20pt; margin-left: 10px;">${msg}</span>
<%--管理员登陆--%>
<form action="adminServlet" method="post">
<input type="hidden" name="action" value="login"/>
<input type="text" name="username" value="${username}" placeholder="Username"/>
<input type="password" name="password" placeholder="Password"/>
<div class="button-box">
<div class="login-toggle-btn">
<input type="checkbox"/>
<a class="flote-none" href="javascript:void(0)">Remember me</a>
<a href="#">Forgot Password?</a>
</div>
<button type="submit"><span>Login</span></button>
</div>
</form>
21.修改manage_menu.jsp, 家居菜单页面
22.修改furn_manage.jsp, 家居显示页面
<thead>
<tr>
<th>家居名</th>
<th>商家</th>
<th>价格</th>
<th>销量</th>
<th>库存</th>
<th>图片</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${furns}" var="furn">
<tr>
<td class="product-thumbnail">
<a href="#"><img class="img-responsive ml-3"
src="assets/images/product-image/1.jpg"
alt=""/></a>
</td>
<td class="product-name"><a href="#">${furn.name}</a></td>
<td class="product-name"><a href="#">${furn.business}</a></td>
<td class="product-price-cart"><span class="amount">${furn.price}</span></td>
<td class="product-quantity">
${furn.saleNum}
</td>
<td class="product-quantity">
${furn.inventory}
</td>
<td class="product-remove">
<a href="#"><i class="icon-pencil"></i></a>
<a href="#"><i class="icon-close"></i></a>
</td>
</tr>
</c:forEach>
</tbody>
23.测试
1)管理员登录
🌳添加家居
思路分析
1.请求添加家居, 请求FurnServlet的add方法, 将前端提交的数据封装到Furn对象
2.调用FurnService.add(Furn furn)方法
3.跳转到显示家居的页面
程序框架图
1.修改com.zzw.furns.FurnDAO
//添加Furn对象
public boolean add(Furn furn);
2.修改com.zzw.furns.impl.FurnDaoImpl
@Override
public boolean add(Furn furn) {
String sql = "INSERT INTO furn(id, `name`, business, price, saleNum, inventory, image_path) " +
"VALUES(NULL, ?, ?, ?, ?, ?, ?)";
int updateRows = update(sql, furn.getName(), furn.getBusiness(), furn.getPrice(),
furn.getSaleNum(), furn.getInventory(), furn.getImagePath());
return updateRows > 0;
}
3.测试, 修改FurnDaoTest
@Test
public void add() {
BigDecimal price = new BigDecimal(32.2);
String imagePath = "assets/images/product-image/4.jpg";
Furn furn =
new Furn(null, "桌子", "南极人", price, 4500, 8000, imagePath);
System.out.println(furnDAO.add(furn) ? "添加成功" : "添加失败");
}
4.修改com.zzw.furns.FurnService
//添加家居
public boolean addFurn(Furn furn);
/**
* 添加家居
*
* @param furn 前端传来的Furn对象
* @return 返回布尔值
*/
@Override
public boolean addFurn(Furn furn) {
return furnDAO.add(furn);
}
5.修改com.zzw.furns.impl.FurnServiceImpl
/**
* 添加家居
*
* @param furn 前端传来的Furn对象
* @return 返回布尔值
*/
@Override
public boolean addFurn(Furn furn) {
return furnDAO.add(furn);
}
6.测试,修改com.zzw.furns.impl.FurnServiceTest
/**
* 添加家居
*
* @param furn 前端传来的Furn对象
* @return 返回布尔值
*/
@Override
public boolean addFurn(Furn furn) {
return furnDAO.add(furn);
}
7.工具类src/com/zzw/furns/utils/DataUtils.java
public class DataUtils {
public static int parseInt(String str, Integer defaultValue) {
try {
int num = Integer.parseInt(str);
return num;
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
8.web层, 修改FurnServlet
, 添加方法add
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String business = req.getParameter("business");
BigDecimal price = new BigDecimal(req.getParameter("price"));
int saleNum = DataUtils.parseInt(req.getParameter("saleNum"), 0);
int inventory = DataUtils.parseInt(req.getParameter("inventory"), 0);
Furn furn = new Furn(null, name,
business, price, saleNum, inventory, "assets/images/product-image/default.jpg");
if (furnService.add(furn) > 0) {
System.out.println("添加成功, 请求转发到list");
//req.getRequestDispatcher("/manage/furnServlet?action=list")
// .forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/manage/furnServlet?action=list");
} else {
System.out.println("添加失败, 返回到添加页面");
req.getRequestDispatcher("views/manage/furn_add.jsp")
.forward(req, resp);
}
}
9.解决中文乱码问题
在BasicServlet中设置utf-8.
10.前端: furn_manage跳转到添加家居页面
<!-- Single Wedge Start -->
<div class="header-bottom-set dropdown">
<a href="views/manage/furn_add.jsp">添加家居</a>
</div>
11.添加furn_add.jsp
<!--添加到table标签的下一行-->
<span class="errorMsg"
style="float: right; font-weight: bold; color: lightgray; font-size: 20pt; margin-left: 10px;"></span>
12.测试
🍉解决重复添加
1.请求转发设置成重定向
🍉后端数据校验说明
后端方案一: 修改FurnServlet.java
String name = req.getParameter("name");
if (StringUtils.isEmpty(name)) {
req.setAttribute("msg", "商品名不能为空");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
String business = req.getParameter("business");
if (StringUtils.isEmpty(business)) {
req.setAttribute("msg", "商家不能为空");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
String saleNumTemp = req.getParameter("saleNum");
//不能为空
if (StringUtils.isEmpty(saleNumTemp)) {
req.setAttribute("msg", "销量不能为空");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
String inventoryTemp = req.getParameter("inventory");
if (StringUtils.isEmpty(inventoryTemp)) {
req.setAttribute("msg", "库存不能为空");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
String priceTemp = req.getParameter("price");
if (StringUtils.isEmpty(priceTemp)) {
req.setAttribute("msg", "价格不能为空");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
Integer saleNum = null;
try {
saleNum = Integer.parseInt(saleNumTemp);
} catch (NumberFormatException e) {
req.setAttribute("msg", "销量格式错误");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
Integer inventory = null;
try {
inventory = Integer.parseInt(inventoryTemp);
} catch (NumberFormatException e) {
req.setAttribute("msg", "库存格式错误");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
BigDecimal price = null;
try {
price = new BigDecimal(priceTemp);
} catch (NumberFormatException e) {
req.setAttribute("msg", "价格格式错误");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
return;
}
前端数据校验, 修改web/views/manage/furn_add.jsp
<script src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
window.onload = function () {
$("input[type='submit']")[0].onclick = function () {
if ($("input[name='name']").val() == "" || $("input[name='name']").val() == null) {
alert("请输入家居名");
return false;
} else if ($("input[name='business']").val() == "" || $("input[name='business']").val() == null) {
alert("请输入商家名");
return false;
} else if ($("input[name='price']").val() == "" || $("input[name='price']").val() == null) {
alert("请输入价格");
return false;
} else if ($("input[name='saleNum']").val() == "" || $("input[name='saleNum']").val() == null) {
alert("请输入销量");
return false;
} else if ($("input[name='inventory']").val() == "" || $("input[name='inventory']").val() == null) {
alert("请输入库存");
return false;
}else if (!/^\d+(\.\d+)?$/.test($("input[name='price']").val())) {
alert("价格格式不对");
return false;
} else if (!/^\d+$/.test($("input[name='saleNum']").val())) {
alert("销量格式不对");
return false;
} else if (!/^\d+$/.test($("input[name='inventory']").val())) {
alert("库存格式不对");
return false;
}
}
}
</script>
🍉BeanUtils自动封装Bean
1.引入jar包
2.修改src/com/zzw/furns/utils/DataUtils.java
, 增加方法
//将方法, 封装到静态方法, 方便使用
public static <T> T copyParamToBean(Map value, T bean) {
try {
//req.getParameterMap() 将数据封装到furn对象
// 底层使用反射封装数据
// 前端的name属性值需要和javabean的属性名一致
BeanUtils.populate(bean, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
return bean;
}
3.修改src/com/zzw/furns/web/FurnServlet.java
的add
方法, 使用BeanUtils自动封装javabean
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//这里我们使用第二种方式, 将前端提交的数据, 自动封装成Furn的Javabean对象
//使用beanUtils完成javabean对象的自动封装
Furn furn =
DataUtils.copyParamToBean(req.getParameterMap(), new Furn());
if (furnService.addFurn(furn)) {
String pageNo = req.getParameter("pageNo");
System.out.println("添加成功..");
//req.getRequestDispatcher("/manage/furnServlet?action=list").forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/manage/furnServlet?action=list");
} else {
System.out.println("添加失败");
req.setAttribute("errorMsg", "添加失败");
req.getRequestDispatcher("/views/manage/furn_add.jsp").forward(req, resp);
}
}
debug小技巧👉
2.报错
原因: 由于前端没有传imagePath的字段, 所以后端在构建furn对象的时候, imagePath属性位null
解决方案👇
🌳删除家居
需求分析
1.管理员进入到家居管理页面
2.点击删除家居链接, 弹出确认窗口, 确认-删除, 取消-放弃
程序框架图
1.修改com.zzw.furns.FurnDAO
//根据id删除对应的furn对象
public boolean deleteFurnById(int id);
2.修改com.zzw.furns.impl.FurnDaoImpl
@Override
public boolean deleteFurnById(int id) {
String sql = "DELETE FROM furn WHERE id = ?";
int updateRows = update(sql, id);
return updateRows > 0;
}
3.测试, 修改FurnDaoTest
@Test
public void deleteFurnById() {
int id = 30;
System.out.println("执行结果= " + furnDAO.deleteFurnById(id));
}
4.修改com.zzw.furns.FurnService
//根据id删除家居
public boolean deleteFurnById(int id);
5.修改com.zzw.furns.impl.FurnServiceImpl
@Override
public boolean deleteFurnById(int id) {
return furnDAO.deleteFurnById(id);
}
6.测试,修改com.zzw.furns.impl.FurnServiceTest
@Test
public void deleteFurnById() {
int id = 31;
System.out.println("执行结果= " + furnService.deleteFurnById(id));
}
6.web层 - 修改src/com/zzw/furns/web/FurnServlet.java
, 增加del
方法
protected void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = DataUtils.parseInt(req.getParameter("id"), 0);
if (furnService.deleteFurnById(id) > 0) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
req.setAttribute("msg", "删除失败");
}
resp.sendRedirect(req.getContextPath() + "/manage/furnServlet?action=list");
}
7.修改web/views/manage/furn_manage.jsp
页面
<a furnName="${furn.name}" href="manage/furnServlet?action=del&id=${furn.id}">
<i class="icon-close"></i>
</a>
jQuery操作父元素, 兄弟元素, 子元素, 请移步👉
js弹框请移步👉
<script src="scripts/jquery-3.6.0.js"></script>
<script type="text/javascript">
window.onload = function () {
$("a[furnName]").click(function () {
var furnName = $(this).attr("furnName");
//js弹框
//1.window.confirm 方法会弹出一个确认窗口
//2.点击确定, 返回true
//3.点击取消, 返回false
var b = window.confirm("你确认要删除 " + furnName+ " 家居信息吗?");
if (!b) {
return false;
}
//简便写法
return window.confirm("你确认要删除 " + furnName+ " 家居信息吗?");
//最终写法
return confirm("你确定要删除 " + furnName + " 家居信息嘛?");
});
}
</script>
🌳修改家具
思路分析
1.管理员进入家居管理页面furn_manage.jsp
2.点击修改家居链接, 回显该家居信息 furn_update.jsp
3.填写新的信息, 点击修改家居按钮
4.修改成功后, 显示刷新后的家居列表
程序框架图
1.修改com.zzw.furns.FurnDAO
//根据id查询furn对象
public Furn queryFurnById(int id);
//将传入的furn对象, 更新到数据库
public boolean updateFurn(Furn furn);
2.修改com.zzw.furns.impl.FurnDaoImpl
/**
* 根据传来的id查询对应的Furn对象
*
* @param id 参数
* @return 返回查询到的Furn对象
*/
@Override
public Furn queryFurnById(int id) {
String sql = "SELECT id, `name`, business, price, saleNum, inventory, " +
"image_path as imagePath FROM furn WHERE id = ?";
Furn furn = querySingle(sql, Furn.class, id);
return furn;
}
/**
* 根据id修改furn表对应的记录
* @param furn 要修改的内容
* @return 返回true或false
*/
@Override
public boolean updateFurn(Furn furn) {
String sql = "UPDATE furn SET `name`=?, business=?, price=?, saleNum=?, inventory=?, image_path=? WHERE id=?";
int updateRows =
update(sql, furn.getName(), furn.getBusiness(), furn.getPrice(), furn.getSaleNum(),
furn.getInventory(), furn.getImagePath(), furn.getId());
return updateRows > 0;
}
3.测试, 修改FurnDaoTest
@Test
public void queryFurnById() {
int id = 75;
Furn furn = furnDAO.queryFurnById(id);
System.out.println(furn);
}
@Test
public void updateFurn() {
Furn furn = new Furn(5, "手机", "小米", new BigDecimal(3000), 6000, 9000, "zzw");
furnDAO.updateFurn(furn);
System.out.println();
}
4.修改com.zzw.furns.FurnService
//根据id查询家居
public Furn queryFurnById(int id);
//根据id修改家居信息
public boolean updateFurn(Furn furn);
5.修改com.zzw.furns.impl.FurnServiceImpl
/**
* 根据前端传来的id查询家居
*
* @param id 参数
* @return 返回查询到的家居
*/
@Override
public Furn queryFurnById(int id) {
Furn furn = furnDAO.queryFurnById(id);
return furn;
}
/**
* 根据id修改家居信息
*
* @param furn 要修改的内容
* @return 返回true或false
*/
@Override
public boolean updateFurn(Furn furn) {
return furnDAO.updateFurn(furn);
}
6.测试,修改com.zzw.furns.impl.FurnServiceTest
@Test
public void queryFurnById() {
int id = 75;
Furn furn = furnService.queryFurnById(id);
System.out.println(furn);
}
@Test
public void updateFurn() {
Furn furn = new Furn(75, "耳麦", "苹果", new BigDecimal(500),
5000, 7000, "");
System.out.println(furnService.updateFurn(furn));
}
7.web层 - 修改src/com/zzw/furns/web/FurnServlet.java
, 增加display
方法和update
方法
protected void display(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = DataUtils.parseInt(req.getParameter("id"), 0);
Furn furn = furnService.queryFurnById(id);
if (furn != null) {
//将furn对象放入request域
req.setAttribute("furn", furn);
req.getRequestDispatcher("/views/manage/furn_update.jsp")
.forward(req, resp);
} else {
System.out.println("查询不到该信息");
req.getRequestDispatcher("/manage/furnServlet?action=list")
.forward(req, resp);
}
}
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Furn furn =
DataUtils.copyParamToBean(req.getParameterMap(), new Furn());
if (furnService.updateFurn(furn) > 0) {
System.out.println("更新成功");
resp.sendRedirect(req.getContextPath() + "/manage/furnServlet?action=list");
} else {
req.setAttribute("msg", "更新失败");
req.getRequestDispatcher("/manage/furnServlet?action=display&id=" + furn.getId())
.forward(req, resp);
}
}
8.前端, 修改web/views/manage/furn_manage.jsp
页面, 点击修改,发出请求
<a href="manage/furnServlet?action=display&id=${furn.id}">
<i class="icon-pencil"></i>
</a>
9.添加web/views/manage/furn_update.jsp
页面, 在tr标签下面添加span标签
<span class="errorMsg"
style="float: right; font-weight: bold; color: lightgray; font-size: 20pt; margin-left: 10px;">${msg}</span>
10.修改web/views/manage/furn_update.jsp
页面, 数据校验
<script src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
window.onload = function () {
$("input[type='submit']")[0].onclick = function () {
if ($("input[name='name']").val() == "" || $("input[name='name']").val() == null) {
alert("请输入家居名");
return false;
} else if ($("input[name='business']").val() == "" || $("input[name='business']").val() == null) {
alert("请输入商家名");
return false;
} else if ($("input[name='price']").val() == "" || $("input[name='price']").val() == null) {
alert("请输入价格");
return false;
} else if ($("input[name='saleNum']").val() == "" || $("input[name='saleNum']").val() == null) {
alert("请输入销量");
return false;
} else if ($("input[name='inventory']").val() == "" || $("input[name='inventory']").val() == null) {
alert("请输入库存");
return false;
}else if (!/^\d+(\.\d+)?$/.test($("input[name='price']").val())) {
alert("价格格式不对");
return false;
} else if (!/^\d+$/.test($("input[name='saleNum']").val())) {
alert("销量格式不对");
return false;
} else if (!/^\d+$/.test($("input[name='inventory']").val())) {
alert("库存格式不对");
return false;
}
}
}
</script>
11.测试,修改数据,点击提交