需求:完成品牌数据的增删改查操作
分以下步骤实现:
创建新的模块brand-demo,引入坐标,需要用到哪些技术就导哪些坐标
pom.xml内容如下:
- "1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
-
- <groupId>org.examplegroupId>
- <artifactId>brand-demoartifactId>
- <version>1.0-SNAPSHOTversion>
-
- <packaging>warpackaging>
-
- <properties>
- <maven.compiler.source>8maven.compiler.source>
- <maven.compiler.target>8maven.compiler.target>
- properties>
-
-
- <dependencies>
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.5version>
- dependency>
-
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>5.1.34version>
- dependency>
-
-
-
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>3.1.0version>
- <scope>providedscope>
- dependency>
-
-
- <dependency>
- <groupId>javax.servlet.jspgroupId>
- <artifactId>jsp-apiartifactId>
- <version>2.2version>
- <scope>providedscope>
- dependency>
-
-
- <dependency>
- <groupId>jstlgroupId>
- <artifactId>jstlartifactId>
- <version>1.2version>
- dependency>
- <dependency>
- <groupId>taglibsgroupId>
- <artifactId>standardartifactId>
- <version>1.1.2version>
- dependency>
-
- dependencies>
-
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.tomcat.mavengroupId>
- <artifactId>tomcat7-maven-pluginartifactId>
- <version>2.2version>
- plugin>
- plugins>
- build>
-
-
- project>
创建不同的包结构,用来存储不同的类。包结构如下:
- -- 删除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
- );
- -- 添加数据
- insert into tb_brand (brand_name, company_name, ordered, description, status)
- values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
- ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
- ('小米', '小米科技有限公司', 50, 'are you ok', 1);
在pojo包下创建名为Brand的类
- public class Brand {
- // id 主键
- private Integer id;
- // 品牌名称
- private String brandName;
- // 企业名称
- private String companyName;
- // 排序字段
- private Integer ordered;
- // 描述信息
- private String description;
- // 状态:0:禁用 1:启用
- private Integer status;
-
-
- public Brand() {
- }
-
- public Brand(Integer id, String brandName, String companyName, String description) {
- this.id = id;
- this.brandName = brandName;
- this.companyName = companyName;
- this.description = description;
- }
-
- public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
- this.id = id;
- this.brandName = brandName;
- this.companyName = companyName;
- this.ordered = ordered;
- this.description = description;
- this.status = status;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getBrandName() {
- return brandName;
- }
-
- public void setBrandName(String brandName) {
- this.brandName = brandName;
- }
-
- public String getCompanyName() {
- return companyName;
- }
-
- public void setCompanyName(String companyName) {
- this.companyName = companyName;
- }
-
- public Integer getOrdered() {
- return ordered;
- }
-
- public void setOrdered(Integer ordered) {
- this.ordered = ordered;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public Integer getStatus() {
- return status;
- }
-
- public void setStatus(Integer status) {
- this.status = status;
- }
-
- @Override
- public String toString() {
- return "Brand{" +
- "id=" + id +
- ", brandName='" + brandName + '\'' +
- ", companyName='" + companyName + '\'' +
- ", ordered=" + ordered +
- ", description='" + description + '\'' +
- ", status=" + status +
- '}';
- }
- }
定义核心配置文件mybatis-config.xml,将该文件放在resources下
- "1.0" encoding="UTF-8" ?>
- configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
-
- <typeAliases>
- <package name="com.huyijie.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:///mybatis?useSSL=false&useServerPrepStmts=true"/>
- <property name="username" value="root"/>
- <property name="password" value="1234"/>
- dataSource>
- environment>
- environments>
- <mappers>
-
- <package name="com.huyijie.mapper"/>
- mappers>
- configuration>
在resources下创建防止映射配置文件的目录结构com/huyijie/mapper,并在该目录下创建映射配置文件BrandMapper.xml
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.huyijie.mapper.BrandMapper">
-
- mapper>
当我们点击index.html页面中查询所有这个超链接时,就能查到题目中给出的信息
对于上述功能,点击查询所有超链接时需要先请后端的servlet,由servlet跳转到对应的页面进行数据动态展示,流程如下图
在mapper包下创建BrandMapper接口,在接口中定义selectAll()方法
- /**
- * 查询所有
- * @return
- */
- @Select("select * from tb_brand")
- List
selectAll();
在com.huyijie.utils包下创建SqlSessionFactoryUtils工具类
- public class SqlSessionFactoryUtils {
-
- private static SqlSessionFactory sqlSessionFactory;
-
- static {
- //静态代码块会随着类的加载而自动执行,且只执行一次
- try {
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static SqlSessionFactory getSqlSessionFactory(){
- return sqlSessionFactory;
- }
- }
在service包下创建BrandService类
- public class BrandService {
- SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
-
- /**
- * 查询所有
- * @return
- */
- public List
selectAll(){ - //调用BrandMapper.selectAll()
-
- //2. 获取SqlSession
- SqlSession sqlSession = factory.openSession();
- //3. 获取BrandMapper
- BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
-
- //4. 调用方法
- List
brands = mapper.selectAll(); -
- sqlSession.close();
-
- return brands;
- }
- }
在web包下创建名为SelectAllServlet的servlet,逻辑如下:
具体代码如下:
- @WebServlet("/selectAllServlet")
- public class SelectAllServlet extends HttpServlet {
- private BrandService service = new BrandService();
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //1. 调用BrandService完成查询
- List
brands = service.selectAll(); - //2. 存入request域中
- request.setAttribute("brands",brands);
- //3. 转发到brand.jsp
- request.getRequestDispatcher("/brand.jsp").forward(request,response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
主要在表格中使用jstl和EL表达式从request域对象中获取名为brands的集合数据并展示出来
- <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Titletitle>
- head>
- <body>
- <input type="button" value="新增"><br>
- <hr>
- <table border="1" cellspacing="0" width="800">
- <tr>
- <th>序号th>
- <th>品牌名称th>
- <th>企业名称th>
- <th>排序th>
- <th>品牌介绍th>
- <th>状态th>
- <th>操作th>
- tr>
-
- <c:forEach items="${brands}" var="brand" varStatus="status">
- <tr align="center">
- <%--<td>${brand.id}td>--%>
- <td>${status.count}td>
- <td>${brand.brandName}td>
- <td>${brand.companyName}td>
- <td>${brand.ordered}td>
- <td>${brand.description}td>
- <c:if test="${brand.status == 1}">
- <td>启用td>
- c:if>
- <c:if test="${brand.status != 1}">
- <td>禁用td>
- c:if>
- <td><a href="#">修改a> <a href="#">删除a>td>
- tr>
- c:forEach>
- table>
- body>
- html>
启动服务器,点击查询所有连接,会发现得出的结果如下
主要是因为查询到的字段名和实体类属性名没有一一对应,在映射配置文件中使用resultMap标签定义映射瓜西,内容如下:
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.huyijie.mapper.BrandMapper">
-
- <resultMap id="brandResultMap" type="brand">
- <result column="brand_name" property="brandName">result>
- <result column="company_name" property="companyName">result>
- resultMap>
-
- mapper>
在BrandMapper接口中使用@ResultMap注解使用该映射
- /**
- * 查询所有
- * @return
- */
- @Select("select * from tb_brand")
- @ResultMap("brandResultMap")
- List
selectAll();
重启,得到如下
上图时做添加功能流程,点击新增按钮后,会先跳转到addBrand.jsp新增页面,在该页面输入要添加的数据,输入完毕后点击提交按钮,需要将数据提交到后端,而后端进行数据添加操作,并重新将所有的数据查询出来,流程如下
根据流程实现功能:
在BrandMapper接口中定义add(Brand brand)方法
- @Insert("insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
- void add(Brand brand);
在BrandService类中定义添加品牌数据方法add(Brand brand)
- /**
- * 添加
- * @param brand
- */
- public void add(Brand brand){
-
- //2. 获取SqlSession
- SqlSession sqlSession = factory.openSession();
- //3. 获取BrandMapper
- BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
-
- //4. 调用方法
- mapper.add(brand);
-
- //提交事务
- sqlSession.commit();
- //释放资源
- sqlSession.close();
- }
在表格新增按钮上绑定事件,点击后跳转到addBrand.jsp页面
<input type="button" value="新增" id="add"><br>
- document.getElementById("add").onclick = function (){
- location.href = "/brand-demo/addBrand.jsp";
- }
该script标签建议放在body结束标签前面
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
-
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>添加品牌title>
- head>
- <body>
- <h3>添加品牌h3>
- <form action="/brand-demo/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>
在web包下创建AddServlet,逻辑如下:
- @WebServlet("/addServlet")
- public class AddServlet extends HttpServlet {
- private BrandService service = new BrandService();
-
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //处理POST请求的乱码问题
- request.setCharacterEncoding("utf-8");
-
- //1. 接收表单提交的数据,封装为一个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对象
- Brand brand = new Brand();
- brand.setBrandName(brandName);
- brand.setCompanyName(companyName);
- brand.setOrdered(Integer.parseInt(ordered));
- brand.setDescription(description);
- brand.setStatus(Integer.parseInt(status));
-
- //2. 调用service 完成添加
- service.add(brand);
-
- //3. 转发到查询所有Servlet
- request.getRequestDispatcher("/selectAllServlet").forward(request,response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
点击新增按钮即可
这是刚开始查询的所有数据,注意序号4中出现的乱码是因为AddServlet中没有对post请求进行格式化处理
我们点击修改按钮时,所点击修改的数据会回显到表单中,然后在修改表单中进行修改,点击提交会将数据提交到后端,后端再将数据存储到数据库中。由以上可知,修改功能要从两方面实现,数据回显和修改操作。
上图就是回显数据的效果。要实现这个效果,点击修改按钮时不能直接跳转到update.jsp页面,而是需要先带着当前行数据的id请求后端程序,后端程序根据id查询数据,将数据存储到域对象中跳转到update.jsp页面进行数据展示。流程如下
在BrandMapper接口中定义selectById(int id)方法
- /**
- * 根据id查询
- * @param id
- * @return
- */
- @Select("select * from tb_brand where id = #{id}")
- @ResultMap("brandResultMap")
- Brand selectById(int id);
在BrandService类中定义根据id查询数据方法selectById(int id)
- /**
- * 根据id查询
- * @return
- */
- public Brand selectById(int id){
- //调用BrandMapper.selectAll()
- //2. 获取SqlSession
- SqlSession sqlSession = factory.openSession();
- //3. 获取BrandMapper
- BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
- //4. 调用方法
- Brand brand = mapper.selectById(id);
- sqlSession.close();
- return brand;
- }
在web包下创建selectByIdServlet的servlet,逻辑如下:
- @WebServlet("/selectByIdServlet")
- public class SelectByIdServlet extends HttpServlet {
- private BrandService service = new BrandService();
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1. 接收id
- String id = request.getParameter("id");
- //2. 调用service查询
- Brand brand = service.selectById(Integer.parseInt(id));
- //3. 存储到request中
- request.setAttribute("brand",brand);
- //4. 转发到update.jsp
- request.getRequestDispatcher("/update.jsp").forward(request,response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
拷贝addBrand.jsp页面,做出以下修改:
- 品牌名称:"brandName" value="${brand.brandName}">
- 企业名称:"companyName" value="${brand.companyName}">
- 排序:"ordered" value="${brand.ordered}">
描述信息:
- 状态:
- <c:if test="${brand.status == 0}">
- 禁用
- 启用
-
- 禁用
- 启用
综上,update.jsp代码如下:
- <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>修改品牌title>
- head>
- <body>
- <h3>修改品牌h3>
- <form action="/brand-demo/updateServlet" method="post">
- 品牌名称:<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>
做完回显数据后,接下来我们要做修改数据了,而下图是修改数据的效果:
在修改页面进行数据修改,点击 提交
按钮,会将数据提交到后端程序,后端程序会对表中的数据进行修改操作,然后重新进行数据的查询操作。整体流程如下:
在BrandMapper接口中定义update(Brand brand)方法
- /**
- * 修改
- * @param brand
- */
- @Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id}")
- void update(Brand brand);
在BrandService类中定义根据id更新方法update(Brand brand)
- /**
- * 修改
- * @param brand
- */
- public void update(Brand brand){
- //2. 获取SqlSession
- SqlSession sqlSession = factory.openSession();
- //3. 获取BrandMapper
- BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
- //4. 调用方法
- mapper.update(brand);
- //提交事务
- sqlSession.commit();
- //释放资源
- sqlSession.close();
- }
在web包下创建UpdateServlet,逻辑如下:
代码如下:
- @WebServlet("/updateServlet")
- public class UpdateServlet extends HttpServlet {
- private BrandService service = new BrandService();
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //处理POST请求的乱码问题
- request.setCharacterEncoding("utf-8");
- //1. 接收表单提交的数据,封装为一个Brand对象
- String id = request.getParameter("id");
- 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对象
- Brand brand = new Brand();
- brand.setId(Integer.parseInt(id));
- brand.setBrandName(brandName);
- brand.setCompanyName(companyName);
- brand.setOrdered(Integer.parseInt(ordered));
- brand.setDescription(description);
- brand.setStatus(Integer.parseInt(status));
-
- //2. 调用service 完成修改
- service.update(brand);
-
- //3. 转发到查询所有Servlet
- request.getRequestDispatcher("/selectAllServlet").forward(request,response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
存在问题:update.jsp页面提交数据时是没有携带主键数据的,而后台修改数据需要根据主键进行修改
对于这个问题,我们不希望页面将主键id展示给用户看,但是又希望在提交数据时能将主键id提交到后端。可以使用HTML的隐藏域,在update.jsp页面的表单中添加如下代码:
- <%--隐藏域,提交id--%>
- <input type="hidden" name="id" value="${brand.id}">
update.jsp最终代码如下:
- <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>修改品牌title>
- head>
- <body>
- <h3>修改品牌h3>
- <form action="/brand-demo/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>
删除即点击删除按钮后,该条数据消失。最好加一个警示框,确认是否删除。
在brand.jsp中添加删除链接
- <td><a href="/brand-demo/selectByIdServlet?id=${brand.id}">修改a>
- <a href="/brand-demo/deleteByIdServlet?id=${brand.id}">删除a>td>
- @Delete("delete from tb_brand where id=#{id};")
- void delById(int id);
- public void deleteById(int id){
- SqlSession sqlSession = factory.openSession();
-
- BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
-
- mapper.delById(id);
-
- sqlSession.commit();
-
- sqlSession.close();
-
- }
- @WebServlet( "/deleteByIdServlet")
- public class DeleteByIdServlet extends HttpServlet {
- private BrandService service=new BrandService();
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String id=request.getParameter("id");
- service.deleteById(Integer.parseInt(id));
-
- request.getRequestDispatcher("/selectAllServlet").forward(request,response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
基本已经完成,演示如下
但是我们在点击删除按钮时没有警告框,容易导致误删,所以得再优化一下。
试了挺久了,不知道为什么跳不出警告框,等之后再优化吧~
项目工程包已上传资源,可在本人上传资源中查看