JavaWeb:servlet+jsp+mybatis商品管理增删改查
1、环境准备
1.1、创建数据库
CREATE DATABASE jsp_test; USE jsp_test; -- 删除tb_brand表 DROP TABLE IF EXISTS tb_brand; -- 创建tb_brand表 CREATE TABLE tb_brand ( -- id 主键 id INT PRIMARY KEY AUTO_INCREMENT, -- 品牌名称 brand_name VARCHAR(20), -- 企业名称 company_name VARCHAR(20), -- 排序字段 ordered INT, -- 描述信息 description VARCHAR(100), -- 状态:0:禁用 1:启用 STATUS INT )DEFAULT CHARSET=utf8; -- 添加数据 INSERT INTO tb_brand (brand_name, company_name, ordered, description, STATUS) VALUES ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0), ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1), ('小米', '小米科技有限公司', 50, 'are you ok', 1); SELECT * FROM tb_brand; SELECT id, brand_name AS brandName, company_name AS companyName FROM tb_brand;
1.2、创建项目导入依赖
创建新的模块,引入坐标。
我们只要分析出要用到哪儿些技术,那么需要哪儿些坐标也就明确了 需要操作数据库。
<dependencies> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency> <!--servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--jsp--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies>
1.3、创建包
创建不同的包结构,用来存储不同的类。
包结构如下
1.4、创建实体类
在 pojo 包下创建名为 Brand 的类。
public class Brand { private Integer id; // 品牌名称 private String brandName; // 企业名称 private String companyName; // 排序字段 private Integer ordered; // 描述信息 private String description; // 状态:0:禁用 1:启用 private Integer status; /** 此处省略了get(),set()等方法,自己生成补全 **/ }
1.5、准备mybatis环境
定义核心配置文件 Mybatis-config.xml ,并将该文件放置在 resources 下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!--在控制台显示SQL语句--> <setting name="logImpl" value="STDOUT_LOGGING"/> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--起别名--> <typeAliases> <package name="com.demo.pojo"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/jsp_test?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <!--扫描mapper--> <package name="com.demo.mapper"/> </mappers> </configuration>
1.6、编写Mybatis工具类
在 com.demo 包下创建 utils 包,并在该包下创建名为 SqlSessionFactoryUtils 工具类
// 这是MyBatis的工具类,简化MyBatis代码 public class MyBatisUtils { private static SqlSessionFactory sqlSessionFactory; // 我们只需要一个SqlSessionFactory,在静态代码块中创建SqlSessionFactory static { try { // 编写代码让MyBatis跑起来,执行SQL语句 String resource = "mybatis-config.xml"; // 加载核心配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); // 得到SqlSession工厂,赋值给成员变量 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } // 返回SqlSessionFactory public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } // 返回SqlSession public static SqlSession openSession() { return sqlSessionFactory.openSession(); } public static SqlSession openSession(boolean autoCommit) { return sqlSessionFactory.openSession(autoCommit); } }
1.7、编写主页面
编写一个基础的前端主页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>品牌首页</title> </head> <body> <a href="https://www.bunian.cn/selectAllServlet">查看所有</a> </body> </html>
2、功能实现
2.1、查询所有
当我们点击 index.html 页面中的 查询所有 这个超链接时,就能查询到上图右半部分的数据。
对于上述的功能,点击查询所有超链接是需要先请后端的servlet ,由 servlet 跳转到对应的页面进行数据的动态展 示。
而整个流程如下图:
功能实现
1、在 mapper 包下创建创建 BrandMapper 接口,在接口中定义 selectAll() 方法
public interface BrandMapper { @Select("select * from tb_brand;") List<Brand> selectAll(); }
2、在 service 包下创建 BrandService 类
public class BrandService { /** * 查询品牌所有数据 * @return */ public List<Brand> selectAll() { SqlSession sqlSession = MyBatisUtils.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); List<Brand> brands = mapper.selectAll(); sqlSession.close(); return brands; } }
3、在 web 包下创建名为 SelectAllServlet 的 servlet
该 servlet 的逻辑如下: 调用 BrandService 的 selectAll() 方法进行业务逻辑处理,并接收返回的结果 将上一步返回的结果存储到 request 域对象中 跳转到 brand.jsp 页面进行数据的展示
@WebServlet(value = "/selectAllServlet") public class SelectAllServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BrandService brandService = new BrandService(); List<Brand> brands = brandService.selectAll(); request.setAttribute("brands",brands); request.getRequestDispatcher("/brandList.jsp").forward(request,response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doPost(request,response); } }
4、编写brand.jsp页面
brand.jsp 页面在表格中使用 JSTL 和 EL表达式 从request域对象中获取名为 brands 的集合数据 并展示出来。页面内容如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="com.demo.pojo.Brand" %> <%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>所有品牌</title> </head> <body> <input type="button" value="新增" onclick="location.href='https://www.bunian.cn/addBrand.jsp'"><br> <hr> <table border="1" cellspacing="0" width="80%"> <tr> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> <th>排序</th> <th>品牌介绍</th> <th>状态</th> <th>操作</th> </tr> <c:forEach items="${brands}" var="brand"> <tr align="center"> <td>${brand.id}</td> <td>${brand.brandName}</td> <td>${brand.companyName}</td> <td>${brand.ordered}</td> <td>${brand.description}</td> <c:if test="${brand.status == 0}"> <td>禁用</td> </c:if> <c:if test="${brand.status == 1}"> <td>启用</td> </c:if> <td><a href="https://www.bunian.cn/selectByIdServlet?id=">修改</a> <a href="https://www.bunian.cn/deleteByIdServlet?id=">删除</a></td> </tr> </c:forEach> </table> </body> </html>
2.2、添加功能
上图是做 添加 功能流程。
点击 新增 按钮后,会先跳转到 addBrand.jsp 新增页面,在该页面输入要添加的数据,输入完 毕后点击 提交 按钮,需要将数据提交到后端,而后端进行数据添加操作,并重新将所有的数据查询出来。
整个流程如下:
功能实现
1、在 BrandMapper 接口,在接口中定义 add(Brand brand) 方法
@Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status});") void addBrand(Brand brand);
2、在 BrandService 类中定义添加品牌数据方法 add(Brand brand)
public void addBrand(Brand brand) { SqlSession sqlSession = MyBatisUtils.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); mapper.addBrand(brand); sqlSession.commit(); sqlSession.close(); }
3、在 web 包下创建 AddServlet 的 servlet
该 servlet 的逻辑如下: 设置处理post请求乱码的字符集 接收客户端提交的数据 将接收到的数据封装到 Brand 对象中 调用 BrandService 的 add() 方法进行添加的业务逻辑处理 跳转到 selectAllServlet 资源重新查询数据
@WebServlet(value = "/addServlet") public class AddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Brand brand = new Brand(); Brand brand = new Brand(); String brandName = request.getParameter("brandName"); String companyName = request.getParameter("companyName"); String ordered = request.getParameter("ordered"); String description = request.getParameter("description"); String status = request.getParameter("status"); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setOrdered(Integer.parseInt(ordered)); brand.setDescription(description); brand.setStatus(Integer.parseInt(status)); //进行添加 BrandService brandService = new BrandService(); brandService.addBrand(brand); response.sendRedirect("selectAllServlet"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doGet(request,response); } }
但是我们可以看到上面的流程过于复杂,获取数据和添加数据太过于繁琐,所以我们可以导入一个工具类进行优化
添加依赖:
<dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency>
修改优化代码:
@WebServlet(value = "/addServlet") public class AddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Brand brand = new Brand(); Map<String, String[]> parameterMap = request.getParameterMap(); try { BeanUtils.populate(brand,parameterMap); //进行添加 BrandService brandService = new BrandService(); brandService.addBrand(brand); response.sendRedirect("selectAllServlet"); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doGet(request,response); } }
4、编写前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>添加品牌</title> </head> <body> <h3>添加品牌</h3> <form action="addServlet" method="post"> 品牌名称:<input name="brandName"><br> 企业名称:<input name="companyName"><br> 排序:<input name="ordered"><br> 描述信息:<textarea rows="5" cols="20" name="description"></textarea><br> 状态: <input type="radio" name="status" value="0">禁用 <input type="radio" name="status" value="1">启用<br> <input type="submit" value="提交"> </form> </body> </html>
2.3、修改数据回显
上图就是回显数据的效果。要实现这个效果,那当点击 修改 按钮时不能直接跳转到 update.jsp 页面,而是需要先带着当 前行数据的 id 请求后端程序,后端程序根据 id 查询数据,将数据存储到域对象中跳转到 update.jsp 页面进行数据展 示。整体流程如下
功能实现
1、编写BrandMapper方法
@Select("select * from tb_brand where id = #{id};") Brand selectById(int id);
2、编写BrandService方法
在 BrandService 类中定义根据id查询数据方法 selectById(int id)
public Brand selectById(int id) { SqlSession sqlSession = MyBatisUtils.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); Brand brand = mapper.selectById(id); sqlSession.close(); return brand; }
3、在 web 包下创建 SelectByIdServlet 的 servlet
@WebServlet(value = "/selectByIdServlet") public class SelectByIdServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); int id = Integer.parseInt(idStr); BrandService brandService = new BrandService(); Brand brand = brandService.selectById(id); request.setAttribute("brand",brand); request.getRequestDispatcher("updateBrand.jsp").forward(request,response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doGet(request,response); } }
2.4、修改数据
做完回显数据后,接下来我们要做修改数据了,而下图是修改数据的效果:
在修改页面进行数据修改,点击 提交 按钮,会将数据提交到后端程序,后端程序会对表中的数据进行修改操作,然后重新 进行数据的查询操作。
整体流程如下:
功能实现
1、编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 update(Brand brand) 方法
@Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id};") void updateBrand(Brand brand);
2、编写BrandService方法
在 BrandService 类中定义根据id查询数据方法 update(Brand brand)
public void updateBrand(Brand brand) { SqlSession sqlSession = MyBatisUtils.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); mapper.updateBrand(brand); sqlSession.commit(); sqlSession.close(); }
3、编写servlet 在 web 包下创建 updateServlet
@WebServlet(value = "/updateServlet") public class UpdateServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); Brand brand = new Brand(); Map<String, String[]> parameterMap = request.getParameterMap(); try { BeanUtils.populate(brand,parameterMap); BrandService brandService = new BrandService(); brandService.updateBrand(brand); response.sendRedirect("selectAllServlet"); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doGet(request,response); } }
4、编写前端页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改品牌</title> </head> <body> <h3>修改品牌</h3> <form action="updateServlet" method="post"> <input type="hidden" name="id" value="${brand.id}"> 品牌名称:<input name="brandName" value="${brand.brandName}"><br> 企业名称:<input name="companyName" value="${brand.companyName}"><br> 排序:<input name="ordered" value="${brand.ordered}"><br> 描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br> 状态: <c:if test="${brand.status == 0}"> <input type="radio" name="status" value="0" checked>禁用 <input type="radio" name="status" value="1">启用<br> </c:if> <c:if test="${brand.status == 1}"> <input type="radio" name="status" value="0">禁用 <input type="radio" name="status" value="1" checked>启用<br> </c:if> <input type="submit" value="提交"> </form> </body> </html>
2.5、删除数据
1、编写servlet 在 web 包下创建 DeleteServlet
@WebServlet(value = "/deleteByIdServlet") public class DeleteByIdServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); int id = Integer.parseInt(idStr); BrandService brandService = new BrandService(); brandService.deleteBrand(id); response.sendRedirect("selectAllServlet"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); doGet(request,response); } }
2、编写BrandService方法
在 BrandService 类中定义根据id查询数据方法 deleteBrand(int id)
public void deleteBrand(int id) { SqlSession sqlSession = MyBatisUtils.openSession(); BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); mapper.deleteBrand(id); sqlSession.commit(); sqlSession.close(); }
3、编写BrandMapper方法
在 BrandMapper 接口,在接口中定义 deleteBrand(int id) 方法
@Delete("delete from tb_brand where id = #{id}") void deleteBrand(int id);