难点:模糊查询后再次分页,并可以选择页数。
最终环境配置:
maven3.8:依赖包管理
IDEA2021+JDK8+mysql connector java5+Mysql5+mybatis3.5:从数据库取出数据。
tomcat7插件:web服务器
servlet、fastjson、axios:处理前后端数据交互
fastjson:阿里提供的依赖包。新增时后端收到前端发过来的JSON字符串后,简化将JSON字符串解析成对象。展示商品列表时后端通过mybatis从数据库中查出数据封装成实体类对象的list之后,简化将对象list序列化成JSON字符串。
axios框架:封装了原生JavaScript的ajax操作,简化了HTTP请求的发起和响应参数的获取。
vue.js+ElementUI+html5+css3+chorme:vue.js封装了JavaScript。ElementUI组件库,封装了vue.js,通过提供了搭配的CSS。所以作为后端搭建个简易前端界面,只需要新建个html页面,new一个Vue,绑定一个DIV,然后在这个DIV里填ElementUI提供的组件,并且在head标签中的style中填ElementUI提供的CSS样式就行了。
重点:记住一切操作的背后都是对象,比如前端是在操作vue data中return的对象,后端就是new 的Brand对象。深浅拷贝涉及JS的内存知识
================================================================
项目结构:
表结构
运行效果
=================================================================
代码
pom.xml
4.0.0
com.ldj
brand-crud
1.0-SNAPSHOT
brand-crud
war
8
8
javax.servlet
javax.servlet-api
3.1.0
provided
org.mybatis
mybatis
3.5.5
mysql
mysql-connector-java
5.1.34
com.alibaba
fastjson
1.2.62
junit
junit
4.11
test
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
BrandMapper
package com.ldj.mapper;
import com.ldj.pojo.Brand;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface BrandMapper {
/**
* 查询所有
*
* @return
*/
List selectAll();
/**
* 添加数据
*
* @param brand
*/
int add(Brand brand);
int update(Brand brand);
int delete(Integer id);
//根据批量删除
int deleteByIds(int[] ids);
//多条件查询动态SQL。多个参数可以使用map
List selectLike4(Map map);
//分页查询。多个参数也可以使用@Param标签
List selectByPage(@Param("begin") int begin, @Param("size") int size);
//查询总记录数
int selectTotalCount();
//分页模糊条件查询
List selectByPageAndCondition(Map map);
//分页模糊查询
//查询总记录数
int selectTotalCountByPageAndCondition(Map map);
}
Brand
package com.ldj.pojo;
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 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 String getStatusStr(){
if (status == null){
return "未知";
}
return status == 0 ? "禁用":"启用";
}
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 +
'}';
}
}
PageBean
package com.ldj.pojo;
import java.util.List;
//用于分页查询的数据传递,泛型T在new的时候指定
public class PageBean {
//总记录数
private int totalCount;
//当前页数据
private List rows;
@Override
public String toString() {
return "PageBean{" +
"totalCount=" + totalCount +
", rows=" + rows +
'}';
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public List getRows() {
return rows;
}
public void setRows(List rows) {
this.rows = rows;
}
}
BrandService
package com.ldj.service;
import com.ldj.pojo.Brand;
import com.ldj.pojo.PageBean;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//接口约束功能,方便servlet更换具体的实现类
public interface BrandService {
/**
* 查询所有
*
* @return
*/
List selectAll();
/**
* 添加数据
*
* @param brand
*/
int add(Brand brand);
/**
* 修改数据
*
* @param brand
*/
int update(Brand brand);
int delete(Integer id);
List selectLike4(Map map);
int deleteByIds(int[] ids);
PageBean selectByPage(int currentPage, int pageSize);
List selectByPageLike(Map map);
int selectTotalCountByPageAndCondition(Map map);
}
BrandServiceImpl
package com.ldj.service.impl;
import com.ldj.mapper.BrandMapper;
import com.ldj.pojo.Brand;
import com.ldj.pojo.PageBean;
import com.ldj.service.BrandService;
import com.ldj.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//实现接口
public class BrandServiceImpl implements BrandService {
//1. 创建SqlSessionFactory 工厂对象
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
@Override
public List selectAll() {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
List brands = mapper.selectAll();
//5. 释放资源
sqlSession.close();
return brands;
}
@Override
public int add(Brand brand) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int add = mapper.add(brand);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return add;
}
@Override
public int delete(Integer id) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int delete = mapper.delete(id);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return delete;
}
@Override
public int update(Brand brand) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int update = mapper.update(brand);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return update;
}
@Override
public List selectLike4(Map map) {//多条件动态查询,如果某些条件用户不填写,就要用这种对应的映射文件,类似java if else if
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List tbBrands = mapper.selectLike4(map);
System.out.println(tbBrands);
return tbBrands;
}
@Override
public int deleteByIds(int[] ids) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int res = mapper.deleteByIds(ids);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return res;
}
@Override
public PageBean selectByPage(int currentPage, int pageSize) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int begin = (currentPage - 1) * pageSize;
List list = mapper.selectByPage(begin, pageSize);
int totalCount = mapper.selectTotalCount();
PageBean pageBean = new PageBean<>();
pageBean.setRows(list);
pageBean.setTotalCount(totalCount);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return pageBean;
}
@Override
public List selectByPageLike(Map map) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
List brands = mapper.selectByPageAndCondition(map);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return brands;
}
@Override
public int selectTotalCountByPageAndCondition(Map map) {
//2. 获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
int count = mapper.selectTotalCountByPageAndCondition(map);
sqlSession.commit();//提交事务
//5. 释放资源
sqlSession.close();
return count;
}
}
SqlSessionFactoryUtils
package com.ldj.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
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;
}
}
BaseServlet
package com.ldj.web.servletoptimization;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String requestURI = req.getRequestURI();
int i = requestURI.lastIndexOf('/');
String methodName = requestURI.substring(i + 1);
System.out.println(methodName);
Class clazz = this.getClass();
Method method = null;
try {
method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this, req, resp);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
BrandServletAfterOptimization
package com.ldj.web.servletoptimization;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ldj.pojo.Brand;
import com.ldj.pojo.PageBean;
import com.ldj.service.BrandService;
import com.ldj.service.impl.BrandServiceImpl;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author ldj
* 优化后的servlet,通过BaseServlet重写HttpServlet的service方法,解析出访问的方法名,通过反射获取相应的方法并调用
*/
@WebServlet("/brandAfterOptimization/*")
public class BrandServletAfterOptimization extends BaseServlet {
private BrandService brandService = new BrandServiceImpl();
//查询所有
public void selectAllServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("收到查询所有的请求");
//1. 调用service查询
List brands = brandService.selectAll();
//2. 转为JSON
String jsonString = JSON.toJSONString(brands);
System.out.println(jsonString);
//3. 写数据
//有中文防止乱码
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
//添加一条数据
public void addServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("收到添加一条数据的请求");
//解决乱码
request.setCharacterEncoding("utf-8");//指定输入流的解码方式
//1. 接收品牌数据
BufferedReader br = request.getReader();
String params = br.readLine();//json字符串
/*
阿里的fastJson.jar:(import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;)
//list转换为json
List list = new ArrayList();
String str=JSON.toJSON(list).toString();
//json转换为list
List list = new ArrayList();
list = JSONObject.parseArray(jasonArray, Person.class);
*/
if (!"".equals(params)) {
//转为Brand对象
Brand brand = JSON.parseObject(params, Brand.class);
System.out.println("收到一条修改信息" + params);
//2. 调用service添加
int add = brandService.add(brand);
//3. 响应成功的标识
if (add == 1) {
response.getWriter().write("success");
}
}
}
//批量删除
public void deleteSelectedListServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("收到批量删除的请求");
//解决乱码
request.setCharacterEncoding("utf-8");//指定输入流的解码方式
//1. 接收品牌数据
BufferedReader br = request.getReader();
String params = br.readLine();//json字符串
System.out.println("前端想要批量删除传过来的JSON字符串:" + params + "======");
/*
阿里的fastJson.jar:(import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;)
//list转换为json
List list = new ArrayList();
String str=JSON.toJSON(list).toString();
//json转换为list
List list = new ArrayList();
list = JSONObject.parseArray(jasonArray, Person.class);
*/
if (!"".equals(params)) {
//转为ids数组
int[] arr = JSONObject.parseObject(params, int[].class);
if (arr.length != 0) {
//2. 调用service删除
brandService.deleteByIds(arr);
//3. 响应成功的标识
response.getWriter().write("success");
}
}
}
//删除一条数据
public void deleteOneServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("收到删除一条数据的请求");
//解决乱码
request.setCharacterEncoding("utf-8");//指定输入流的解码方式
//1. 接收想要删除的ID
String id = request.getParameter("id");
//转为
System.out.println("收到一条删除信息,想要删除的ID是" + id);
//2. 调用service删除
brandService.delete(Integer.valueOf(id));
//3. 响应成功的标识
response.getWriter().write("success");
}
//模糊分页查询
public void selectLikeServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取前端传过来的三个参数封装进Map
//解决乱码
request.setCharacterEncoding("utf-8");//指定输入流的解码方式
//1. 接收模糊查询的品牌数据
BufferedReader br = request.getReader();
String params = br.readLine();//json字符串
//转为Brand对象
Brand brandLike = JSON.parseObject(params, Brand.class);
System.out.println("收到一条模糊查询信息" + params);
//2接收当前页信息和每页显示多少页
int currentPageLike = Integer.parseInt(request.getParameter("currentPageLike"));
int pageSizeLike = Integer.parseInt(request.getParameter("pageSizeLike"));
int begin = (currentPageLike - 1) * pageSizeLike;
//封装查询条件
Map map = new HashMap();
String companyName = "";
String brandName = "";
if (!"".equals(brandLike.getCompanyName())) {//不为空则进行模糊查询
companyName = "%" + brandLike.getCompanyName() + "%";
brandLike.setCompanyName(companyName);
}
if (!"".equals(brandLike.getBrandName())) {//不为空则进行模糊查询
brandName = "%" + brandLike.getBrandName() + "%";
brandLike.setBrandName(brandName);
}
map.put("begin", begin);
map.put("pageSizeLike", pageSizeLike);
map.put("brandLike", brandLike);
//1. 调用service模糊查询
List brands = brandService.selectByPageLike(map);
int countLike = brandService.selectTotalCountByPageAndCondition(map);
PageBean pageBean =new PageBean<>();
pageBean.setTotalCount(countLike);
pageBean.setRows(brands);
//2. 转为JSON
String jsonString = JSON.toJSONString(pageBean);
System.out.println("模糊查询到的" + jsonString);
//3. 写数据
//有中文防止乱码
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
//更新一条数据
public void updateOneBrandServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
//解决乱码
request.setCharacterEncoding("utf-8");//指定输入流的解码方式
//1. 接收品牌数据
BufferedReader br = request.getReader();
String params = br.readLine();//json字符串
//转为Brand对象
Brand brand = JSON.parseObject(params, Brand.class);
System.out.println("收到一条修改信息" + params);
//2. 调用service添加
int update = brandService.update(brand);
//3. 响应成功的标识
if (update == 1) {
response.getWriter().write("success");
}
}
//分页查询
public void selectByPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
int currentPage = Integer.parseInt(request.getParameter("currentPage"));
int pageSize = Integer.parseInt(request.getParameter("pageSize"));
PageBean pageBean = brandService.selectByPage(currentPage, pageSize);
//2. 转为JSON
String jsonString = JSON.toJSONString(pageBean);
System.out.println("模糊查询到的" + jsonString);
//3. 写数据
//有中文防止乱码
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
}
BrandMapper.xml
insert into tb_brand
values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
update tb_brand
set brand_name = #{brandName},
company_name = #{companyName},
ordered = #{ordered},
description = #{description},
`status` = #{status}
where id = #{id}
delete
from tb_brand
where id = #{id}
delete
from tb_brand where id in
#{item}
mybatis-config.xml
brandAfterOptimizationPageBehind.html
Title
去往前端分页未优化servlet
去往前端分页已优化servlet
去往后端分页已优化servlet
模糊查询
批量删除
新增
提交
取消
提交修改
取消
修改
删除
index.html
首页
去往前端分页,未优化servlet
去往前端分页,已优化servlet
去往后端分页,已优化servlet
web.xml
element-UI和vue.js和axios的依赖包太长,需要时直接上官网下载吧,版本如下:
Vue.js v2.6.10
=================================
"name": "element-ui",
"version": "2.13.0",
===============================
axios v0.18.0
在pom.xml上右键点击tomcat7.run后,浏览器输入初始页面的地址,点击第三个功能:
http://localhost:8080/brand-crud
如上,实现了:
1、单表的后端分页显示到前端页面、前端页面三种方式选择页数。
2、进行模糊查询,并且模糊查询后能在模糊查询结果中实现分页。
3、新增一条、删除一条、批量删除、修改