需求:完成品牌数据的增删改查操作
分以下步骤实现:
创建新的模块brand-demo,引入坐标,需要用到哪些技术就导哪些坐标
pom.xml内容如下:
4.0.0
org.example
brand-demo
1.0-SNAPSHOT
war
8
8
org.mybatis
mybatis
3.5.5
mysql
mysql-connector-java
5.1.34
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet.jsp
jsp-api
2.2
provided
jstl
jstl
1.2
taglibs
standard
1.1.2
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
创建不同的包结构,用来存储不同的类。包结构如下:
-- 删除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下
在resources下创建防止映射配置文件的目录结构com/huyijie/mapper,并在该目录下创建映射配置文件BrandMapper.xml
当我们点击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" %>
Title
序号
品牌名称
企业名称
排序
品牌介绍
状态
操作
<%--${brand.id} --%>
${status.count}
${brand.brandName}
${brand.companyName}
${brand.ordered}
${brand.description}
启用
禁用
修改 删除
启动服务器,点击查询所有连接,会发现得出的结果如下
主要是因为查询到的字段名和实体类属性名没有一一对应,在映射配置文件中使用resultMap标签定义映射瓜西,内容如下:
在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页面
该script标签建议放在body结束标签前面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
添加品牌
添加品牌
在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页面,做出以下修改:
品牌名称:
企业名称:
排序:
描述信息:
状态:
禁用
启用
禁用
启用
综上,update.jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
修改品牌
修改品牌
做完回显数据后,接下来我们要做修改数据了,而下图是修改数据的效果:
在修改页面进行数据修改,点击 提交
按钮,会将数据提交到后端程序,后端程序会对表中的数据进行修改操作,然后重新进行数据的查询操作。整体流程如下:
在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--%>
update.jsp最终代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
修改品牌
修改品牌
删除即点击删除按钮后,该条数据消失。最好加一个警示框,确认是否删除。
在brand.jsp中添加删除链接
修改
删除
@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);
}
}
基本已经完成,演示如下
但是我们在点击删除按钮时没有警告框,容易导致误删,所以得再优化一下。
试了挺久了,不知道为什么跳不出警告框,等之后再优化吧~
项目工程包已上传资源,可在本人上传资源中查看