Soldier增删改查
1 数据建模
1.1 物理建模
CREATE TABLE t_soldier(
soldier_id INT PRIMARY KEY AUTO_INCREMENT,
soldier_name CHAR(100),
soldier_weapon CHAR(100)
);
1.2 逻辑建模
package com.atguigu.pojo;
public class Soldier {
private Integer soldierId;
private String soldierName;
private String soldierWeapon;
public Soldier() {
}
public Soldier(Integer soldierId, String soldierName, String soldierWeapon) {
this.soldierId = soldierId;
this.soldierName = soldierName;
this.soldierWeapon = soldierWeapon;
}
public Integer getSoldierId() {
return soldierId;
}
public void setSoldierId(Integer soldierId) {
this.soldierId = soldierId;
}
public String getSoldierName() {
return soldierName;
}
public void setSoldierName(String soldierName) {
this.soldierName = soldierName;
}
public String getSoldierWeapon() {
return soldierWeapon;
}
public void setSoldierWeapon(String soldierWeapon) {
this.soldierWeapon = soldierWeapon;
}
@Override
public String toString() {
return "Soldier{" +
"soldierId=" + soldierId +
", soldierName='" + soldierName + '\'' +
", soldierWeapon='" + soldierWeapon + '\'' +
'}';
}
}
2 总体架构
3 搭建环境
3.1 搭建持久层环境
- 拷贝持久层的jar包: mysql驱动、druid、dbutils、junit、BeanUtils
- 拷贝JDBCUtils工具类、jdbc.properties文件、BaseDao类
3.2 搭建Thymeleaf环境
-
拷贝Thymeleaf所需的jar包
-
拷贝ViewBaseServlet类
-
配置web.xml
<!-- 在上下文参数中配置视图前缀和视图后缀 --> <context-param> <param-name>start</param-name> <param-value>/WEB-INF/pages/</param-value> </context-param> <context-param> <param-name>end</param-name> <param-value>.html</param-value> </context-param>
-
创建view目录
4 需要实现的功能列表
- 显示首页:浏览器通过index.html访问首页Servlet,然后再解析对应的模板视图
- 显示列表:在首页点击超链接,跳转到目标页面把所有士兵的信息列表显示出来
- 删除信息:在列表上点击删除超链接,执行信息的删除操作
- 新增信息:
- 在列表页面点击超链接跳转到新增士兵信息的表单页面
- 在新增信息的表单页面点击提交按钮执行保存
- 更新信息:
- 在列表上点击更新超链接,跳转到更新士兵信息的表单页面:表单回显
- 在更新信息的表单页面点击提交按钮执行更新
5 显示首页功能
5.1 目标
浏览器访问index.html,通过首页Servlet,渲染视图,显示首页。
5.2 代码
① 创建IndexServlet
Servlet代码:
package com.atguigu.servlet.app;
import com.atguigu.servlet.base.ViewBaseServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/index.html")
public class IndexServlet extends ViewBaseServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
processTemplate("index", req, resp);
}
}
②创建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<a href="soldier?method=showAll">展示士兵信息</a>
</body>
</html>
6 显示列表
6.1 目标
在目标页面显示所有士兵信息,士兵信息是从数据库查询出来的
6.2 思路
6.3 代码
① ModelBaseServlet
创建这个基类的原因是:我们希望每一个模块能够对应同一个Servlet,这个模块所需要调用的所有方法都集中在同一个Servlet中。如果没有这个ModelBaseServlet基类,我们doGet()、doPost()方法可以用来处理请求,这样一来,每一个方法都需要专门创建一个Servlet(就好比咱们之前的LoginServlet、RegisterServlet其实都应该合并为UserServlet)。
package com.atguigu.servlet.base;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class ModelBaseServlet extends ViewBaseServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String methodName = req.getParameter("method");
System.out.println("this = " + this);
// 执行方法
try {
Class clazz = this.getClass();
Method method = clazz.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
// 可以直接使用私有方法 跳过java语法的检测
method.setAccessible(true);
// 执行方法
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
② SoldierDao.selectSoldierList()
接口方法:
package com.atguigu.dao;
import com.pojo.Soldier;
import java.util.List;
public interface SoldierDao {
// 查询所有士兵
List<Soldier> selectSoldierList();
}
实现类方法:
package com.atguigu.dao.impl;
import com.atguigu.dao.BaseDao;
import com.atguigu.dao.SoldierDao;
import com.pojo.Soldier;
import java.util.List;
public class SoldierDaoImpl extends BaseDao implements SoldierDao {
@Override
public List<Soldier> selectSoldierList() {
String sql = "select * from t_soldier";
List<Soldier> soldierList = findAllBean(sql, Soldier.class);
return soldierList;
}
}
③ SoldierService.getSoldierList()
接口方法:
package com.atguigu.service;
import com.atguigu.dao.SoldierDao;
import com.atguigu.dao.impl.SoldierDaoImpl;
import com.pojo.Soldier;
import java.util.List;
public interface SoldierService {
List<Soldier> findAllSoldier();
}
实现类方法:
package com.atguigu.service.impl;
import com.atguigu.dao.SoldierDao;
import com.atguigu.dao.impl.SoldierDaoImpl;
import com.atguigu.service.SoldierService;
import com.pojo.Soldier;
import java.util.List;
public class SoldierServiceImpl implements SoldierService {
// 创建dao对象
SoldierDao dao = new SoldierDaoImpl();
@Override
public List<Soldier> findAllSoldier() {
List<Soldier> soldierList = dao.selectSoldierList();
return soldierList;
}
}
④ SoldierServlet.showList()
/**
* 处理查询所有士兵信息的请求
* @param request
* @param response
*/
protected void showAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建服务层对象
SoldierService service = new SoldierServiceImpl();
// 调用业务层方法查询士兵列表
List<Soldier> soldierList = service.findAllSoldier();
// 将查询到的士兵列表放进请求域中
req.setAttribute("soldierList", soldierList);
// 跳转到展示页面进行展示
processTemplate("show", req, resp);
}
}
⑤ 显示士兵列表的show.html页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>士兵展示页面</title>
</head>
<body>
<table border="1" width="900" >
<tr>
<th>士兵编号</th>
<th>士兵姓名</th>
<th>士兵武器</th>
<th>信息删除</th>
<th>信息修改</th>
</tr>
<tbody th:if="${#lists.isEmpty(soldierList)}">
<td colspan="5" style="text-align: center">没有数据请添加</td>
</tbody>
<tbody th:unless="${#lists.isEmpty(soldierList)}">
<tr th:each="soldier:${soldierList}">
<th th:text="${soldier.soldier_id}" ></th>
<th th:text="${soldier.soldier_name}" ></th>
<th th:text="${soldier.soldier_weapon}" ></th>
<th><a th:href="@{/soldier(method=delSoldierById,id=${soldier.soldier_id})}">删除</a> </th>
<th><a href="">编辑</a></th>
</tr>
</tbody>
</table>
</body>
</html>
7 删除功能
7.1 目标
点击页面上的超链接,把数据库表中的记录删除。
7.2 思路
7.3 代码
① 完成删除超链接
<th><a th:href="@{/soldier(method=delSoldierById,id=${soldier.soldier_id})}">删除</a> </th>
关于@{地址}附加请求参数的语法格式:
- 只有一个请求参数:@{地址(请求参数名=普通字符串)}或@{地址(请求参数名=${需要解析的表达式})}
- 多个请求参数:@{地址(名=值,名=值)}
官方文档中的说明如下:
② Servlet方法
// 根据id删除士兵
protected void delSoldierById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取传入的id
String id = req.getParameter("id");
// id转成int类型
int intId = Integer.parseInt(id);
// 调用业务层方法删除士兵
service.delSoldierById(intId);
// 重定向到showAll方法
resp.sendRedirect(req.getContextPath() + "/soldier?method=showAll");
}
③ Service方法
@Override
public void delSoldierById(int intId) {
dao.removeSoldierById(intId);
}
④ Dao方法
@Override
public void removeSoldierById(int intId) {
String sql = "delete from t_soldier where soldier_id = ?";
update(sql, intId);
}
8 前往新增信息的表单页面
8.1 创建超链接
<a th:href="@{/soldier(method='toAddSoldierPage')}">添加士兵信息</a>
8.2 Servlet
// 跳转到添加士兵页面
protected void toAddSoldierPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
processTemplate("addSoldier", req, resp);
}
8.3 创建表单页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>添加士兵页面</title>
</head>
<body>
<form action="soldier">
<h3>添加士兵</h3>
<input type="hidden" name="method" value="addSoldier">
<span th:text="${errMsg}" style="color: red"></span> <br>
士兵姓名 <input type="text" name="soldier_name"> <br>
士兵武器 <input type="text" name="soldier_weapon"> <br>
<input type="submit" value="添加">
</form>
</body>
</html>
9 执行保存
9.1 目标
提交表单后,将表单数据封装为Soldier对象,然后将Soldier对象保存到数据库。
9. 代码
① Servlet方法
// 添加士兵
protected void addSoldier(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
Map<String, String[]> map = req.getParameterMap();
// 将参数封装到Soldier对象
Soldier soldier = new Soldier();
try {
BeanUtils.populate(soldier, map);
// 调用业务层方法进行添加
service.addSoldier(soldier);
// 重定向跳转到showAll方法
resp.sendRedirect(req.getContextPath() + "/soldier?method=showAll");
} catch (Exception e) {
e.printStackTrace();
req.setAttribute("errMsg", e.getMessage());
processTemplate("addSoldier", req, resp);
}
}
② Service方法
@Override
public void addSoldier(Soldier soldier) {
if (soldier.getSoldier_name().equals("") || soldier.getSoldier_weapon().equals("")){
throw new RuntimeException("名字或武器不能为空");
}else{
dao.addSoldier(soldier);
}
}
③ Dao方法
@Override
public void addSoldier(Soldier soldier) {
String sql = "insert into t_soldier values(null,?,?)";
update(sql, soldier.getSoldier_name(), soldier.getSoldier_weapon());
}
10 前往修改信息的表单页面
10.1 创建超链接
<th><a th:href="@{/soldier(method=toUpdateSoldierPage,id=${soldier.soldier_id})}">编辑</a></th>
10.2 Servlet方法
protected void toUpdateSoldierPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取要修改士兵的id
String id = req.getParameter("id");
int intId = Integer.parseInt(id);
// 查询出当前士兵的信息
Soldier soldier = service.findSoldier(intId);
// 将soldier存储到请求域中
req.setAttribute("soldier", soldier);
// 跳转到修改页面
processTemplate("editSoldier", req, resp);
}
10.3 Service方法
@Override
public Soldier findSoldier(int intId) {
Soldier soldier = dao.findSoldier(intId);
return soldier;
}
10.4 Dao方法
@Override
public Soldier findSoldier(int intId) {
String sql = "select * from t_soldier where soldier_id = ?";
Soldier soldier = findOneBean(sql, Soldier.class, intId);
return soldier;
}
10.5 表单页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>编辑士兵页面</title>
</head>
<body>
<form action="soldier">
<input type="hidden" name="method" value="updateSoldier">
<h3>修改士兵</h3>
<input type="hidden" name="soldier_id" th:value="${soldier.soldier_id}">
<input type="hidden" name="method" value="addSoldier">
<span th:text="${errMsg}" style="color: red"></span> <br>
士兵姓名 <input type="text" name="soldier_name" th:value="${soldier.soldier_name}"> <br>
士兵武器 <input type="text" name="soldier_weapon" th:value="${soldier.soldier_weapon}"> <br>
<input type="submit" value="修改">
</form>
</body>
</html>
11 执行更新
11.1 Servlet方法
// 编辑士兵
protected void updateSoldier(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, InvocationTargetException, IllegalAccessException {
// 获取表单提交的数据
Map<String, String[]> map = req.getParameterMap();
Soldier soldier = new Soldier();
// 将请求参数封装到Soldier对象
BeanUtils.populate(soldier, map);
// 调用业务层方法进行修改
service.updateSoldier(soldier);
// 重定向跳转到showAll方法中
resp.sendRedirect(req.getContextPath() + "/soldier?method=showAll");
}
11.2 Service方法
@Override
public void updateSoldier(Soldier soldier) {
dao.updateSoldier(soldier);
}
11.3 Dao方法
@Override
public void updateSoldier(Soldier soldier) {
String sql = "update t_soldier set soldier_name=?,soldier_weapon=? where soldier_id=?";
update(sql, soldier.getSoldier_name(), soldier.getSoldier_weapon(), soldier.getSoldier_id());
}