前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >maven+vue+servlet+element+MyBatis 前后端分离小项目

maven+vue+servlet+element+MyBatis 前后端分离小项目

原创
作者头像
ruochen
修改2022-03-07 17:54:41
3K0
修改2022-03-07 17:54:41
举报

准备工作

需要的文件我已经打包好了:

链接:https://pan.baidu.com/s/1gTIi2nTHHv3bfcy5khKxgw

提取码:i2al

  • 前端页面:可参考此篇文章 Element 入门教程 自行编写,也可以直接使用我准备好的模板
  • sql 文件 ```sql -- 创建数据库 create database db1 character set utf8; use db1;
代码语言:txt
复制
-- 删除tb_brand表
代码语言:txt
复制
drop table if exists tb_brand;
代码语言:txt
复制
-- 创建tb_brand表
代码语言:txt
复制
create table tb_brand
代码语言:txt
复制
(
代码语言:txt
复制
    -- id 主键
代码语言:txt
复制
    id           int primary key auto_increment,
代码语言:txt
复制
    -- 品牌名称
代码语言:txt
复制
    brand_name   varchar(20),
代码语言:txt
复制
    -- 企业名称
代码语言:txt
复制
    company_name varchar(20),
代码语言:txt
复制
    -- 排序字段
代码语言:txt
复制
    ordered      int,
代码语言:txt
复制
    -- 描述信息
代码语言:txt
复制
    description  varchar(100),
代码语言:txt
复制
    -- 状态:0:禁用  1:启用
代码语言:txt
复制
    status       int
代码语言:txt
复制
);
代码语言:txt
复制
-- 添加数据
代码语言:txt
复制
insert into tb_brand (brand_name, company_name, ordered, description, status)
代码语言:txt
复制
values 
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
代码语言:txt
复制
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
代码语言:txt
复制
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
代码语言:txt
复制
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
代码语言:txt
复制
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
代码语言:txt
复制
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
代码语言:txt
复制
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
代码语言:txt
复制
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1)
代码语言:txt
复制
        ;
代码语言:txt
复制
SELECT * FROM tb_brand;
代码语言:txt
复制
```

业务 - 查询所有

后端

  • BrandMapper.java:这里要注意实体类属性名称和数据库表名称不一致,使用 resultMap 映射 ```java /** * 查询所有 * @return */ @Select("select * from tb_brand") @ResultMap("brandResultMap") List<Brand> selectAll(); ```
  • service - service 接口:BrandService.java ```java package com.ruochen.service;
代码语言:txt
复制
import com.ruochen.pojo.Brand;
代码语言:txt
复制
import java.util.List;
代码语言:txt
复制
public interface BrandService {
代码语言:txt
复制
    /**
代码语言:txt
复制
     * 查询所有
     * @return
     */
    List<Brand> selectAll();
}
```
- service 实现类:`BrandServiceImpl.java`
```java
package com.ruochen.service.impl;
代码语言:txt
复制
import com.ruochen.mapper.BrandMapper;
代码语言:txt
复制
import com.ruochen.pojo.Brand;
代码语言:txt
复制
import com.ruochen.service.BrandService;
代码语言:txt
复制
import com.ruochen.util.SqlSessionFactoryUtils;
代码语言:txt
复制
import org.apache.ibatis.session.SqlSession;
代码语言:txt
复制
import org.apache.ibatis.session.SqlSessionFactory;
代码语言:txt
复制
import java.util.List;
代码语言:txt
复制
public class BrandServiceImpl implements BrandService {
代码语言:txt
复制
    // 1. 创建 SqlSessionFactory 工厂对象
代码语言:txt
复制
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
代码语言:txt
复制
    @Override
代码语言:txt
复制
    public List<Brand> selectAll() {
代码语言:txt
复制
        // 2. 获取 SqlSession 对象
代码语言:txt
复制
        SqlSession sqlSession = factory.openSession();
代码语言:txt
复制
        // 3. 获取 BrandMapper
代码语言:txt
复制
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
代码语言:txt
复制
        // 4. 调用方法
代码语言:txt
复制
        List<Brand> brands = brandMapper.selectAll();
代码语言:txt
复制
        // 5. 释放资源
代码语言:txt
复制
        sqlSession.close();
代码语言:txt
复制
        return brands;
代码语言:txt
复制
    }
代码语言:txt
复制
}
代码语言:txt
复制
```
  • SelectAllServlet.java ```java package com.ruochen.web.servlet;
代码语言:txt
复制
import com.alibaba.fastjson.JSON;
代码语言:txt
复制
import com.ruochen.pojo.Brand;
代码语言:txt
复制
import com.ruochen.service.BrandService;
代码语言:txt
复制
import com.ruochen.service.impl.BrandServiceImpl;
代码语言:txt
复制
import javax.servlet.*;
代码语言:txt
复制
import javax.servlet.http.*;
代码语言:txt
复制
import javax.servlet.annotation.*;
代码语言:txt
复制
import java.io.IOException;
代码语言:txt
复制
import java.util.List;
代码语言:txt
复制
@WebServlet("/selectAllServlet")
代码语言:txt
复制
public class SelectAllServlet extends HttpServlet {
代码语言:txt
复制
    private BrandService brandService = new BrandServiceImpl();
代码语言:txt
复制
    @Override
代码语言:txt
复制
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
代码语言:txt
复制
        // 1. 调用 service 查询
代码语言:txt
复制
        List<Brand> brands = brandService.selectAll();
代码语言:txt
复制
        // 2. 数据转为 JSON
代码语言:txt
复制
        String jsonString = JSON.toJSONString(brands);
代码语言:txt
复制
        // 3. 写数据
代码语言:txt
复制
        // 数据存在中文
代码语言:txt
复制
        response.setContentType("text/json;charset=utf-8");
代码语言:txt
复制
        response.getWriter().write(jsonString);
代码语言:txt
复制
    }
代码语言:txt
复制
    @Override
代码语言:txt
复制
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
代码语言:txt
复制
        this.doGet(request, response);
代码语言:txt
复制
    }
代码语言:txt
复制
}
代码语言:txt
复制
```
  • 测试

前端

  • 页面加载完成后,发送异步请求,获取数据,绑定表格上模型 tableData ```js mounted() { // 当页面加载完成后,发送异步请求,获取数据 var _this = this; axios({ method: "get", url: "http://localhost:8080/brand-case/selectAllServlet" }).then(function (resp) { _this.tableData = resp.data; }) }, ```
  • 测试
    业务 - 新增品牌

后端

  • BrandMapper.java ```java /** * 添加数据 * @param brand */ @Insert("insert into tb_brand values (null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status})") void add(Brand brand); ```
  • service - service 接口:BrandService.java ```java /** * 添加数据 * @param brand */ void add(Brand brand); ``` - service 实现类:`BrandServiceImpl.java` ```java @Override public void add(Brand brand) { // 2. 获取 SqlSession 对象 SqlSession sqlSession = factory.openSession(); // 3. 获取 BrandMapper BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 4. 调用方法 brandMapper.add(brand); // 5. 提交事务 sqlSession.commit(); // 6. 释放资源 sqlSession.close(); } } ```
  • AddServlet.java ```java package com.ruochen.web.servlet;
代码语言:txt
复制
import com.alibaba.fastjson.JSON;
代码语言:txt
复制
import com.ruochen.pojo.Brand;
代码语言:txt
复制
import com.ruochen.service.BrandService;
代码语言:txt
复制
import com.ruochen.service.impl.BrandServiceImpl;
代码语言:txt
复制
import javax.servlet.ServletException;
代码语言:txt
复制
import javax.servlet.annotation.WebServlet;
代码语言:txt
复制
import javax.servlet.http.HttpServlet;
代码语言:txt
复制
import javax.servlet.http.HttpServletRequest;
代码语言:txt
复制
import javax.servlet.http.HttpServletResponse;
代码语言:txt
复制
import java.io.BufferedReader;
代码语言:txt
复制
import java.io.IOException;
代码语言:txt
复制
import java.util.List;
代码语言:txt
复制
@WebServlet("/addServlet")
代码语言:txt
复制
public class AddServlet extends HttpServlet {
代码语言:txt
复制
    private BrandService brandService = new BrandServiceImpl();
代码语言:txt
复制
    @Override
代码语言:txt
复制
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
代码语言:txt
复制
        // 1. 接收品牌数据
代码语言:txt
复制
        BufferedReader br = request.getReader();
代码语言:txt
复制
        String params = br.readLine();  // json 字符串
代码语言:txt
复制
        // JSON 字符串转为 brand 对象
代码语言:txt
复制
        Brand brand = JSON.parseObject(params, Brand.class);
代码语言:txt
复制
        // 2. 调用 service 添加
代码语言:txt
复制
        brandService.add(brand);
代码语言:txt
复制
        // 3. 响应成功标识
代码语言:txt
复制
        response.getWriter().write("success");
代码语言:txt
复制
    }
代码语言:txt
复制
    @Override
代码语言:txt
复制
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
代码语言:txt
复制
        this.doGet(request, response);
代码语言:txt
复制
    }
代码语言:txt
复制
}
代码语言:txt
复制
```

前端

  • 我们先将上一个功能中查询所有数据 ajax 请求封装为一个方法,方便调用 ```js // 查询所有数据 selectAll() { // 当页面加载完成后,发送异步请求,获取数据 var _this = this; axios({ method: "get", url: "http://localhost:8080/brand-case/selectAllServlet" }).then(function (resp) { _this.tableData = resp.data; }) }, ```
  • 提交按钮绑定了 addBrand 方法,点击提交按钮时发送 ajax 请求,添加数据(数据由模型 brand 绑定获得) ```js // 添加数据 addBrand() { var _this = this; // 发送 ajax 请求,添加数据 axios({ method: "post", url: "http://localhost:8080/brand-case/addServlet", data: _this.brand }).then(function (resp) { if (resp.data == 'success') { // 添加成功 // 关闭窗口 _this.dialogVisible = false; // 查询数据 _this.selectAll();
代码语言:txt
复制
            // 弹出消息提示
代码语言:txt
复制
			_this.$message({
代码语言:txt
复制
			     message: '恭喜你,添加成功',
代码语言:txt
复制
			     type: 'success'
代码语言:txt
复制
			});
代码语言:txt
复制
        }
代码语言:txt
复制
    })
代码语言:txt
复制
},
代码语言:txt
复制
```

Servlet 优化

  • 查看文章:Javaweb 自定义 Servlet 实现按照访问路径转发

业务 - 批量删除

后端

  • Dao 层 - BrandMapper.java ```java /** * 批量删除 * @param ids */ void deleteByIds(@Param("ids") int[] ids); ``` - `BrandMapper.xml` ```xml <!--批量删除--> <delete id="deleteByIds"> delete from tb_brand where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> ```
  • Service 层 - Service 接口:BrandService.java ```java /** * 批量删除 * @param ids */ void deleteByIds(int[] ids); ``` - Service 实现类:`BrandServiceImpl.java` ```java @Override public void deleteByIds(int[] ids) { // 2. 获取 SqlSession 对象 SqlSession sqlSession = factory.openSession(); // 3. 获取 BrandMapper BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 4. 调用方法 brandMapper.deleteByIds(ids); // 5. 提交事务 sqlSession.commit(); // 6. 释放资源 sqlSession.close(); } ```
  • Web 层:BrandServlet.java ```java /** * 批量删除 * * @param request * @param response * @throws ServletException * @throws IOException */ public void deleteByIds(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 接收数据 [1,2,...] BufferedReader br = request.getReader(); String params = br.readLine(); // json 字符串
代码语言:txt
复制
        // 转为 int[]
代码语言:txt
复制
        int[] ids = JSON.parseObject(params, int[].class);
代码语言:txt
复制
        // 2. 调用 service 添加
代码语言:txt
复制
        brandService.deleteByIds(ids);
代码语言:txt
复制
        // 3. 响应成功标识
代码语言:txt
复制
        response.getWriter().write("success");
代码语言:txt
复制
    }
代码语言:txt
复制
```

前端

  • 首先要给批量删除按钮添加点击事件 ```html <el-button type="danger" plain @click="deleteByIds">批量删除</el-button> ```
  • 在编写 deleteByIds 方法之前,我们要想办法获取到选中的 id,复选框选中后会执行一个 handleSelectionChange 回调方法,我们可以通过该方法中的 this.multipleSelection 获取到选中的对象数组 ```js // 复选框选中后执行的方法 handleSelectionChange(val) { this.multipleSelection = val;
代码语言:txt
复制
    // console.log(this.multipleSelection)
代码语言:txt
复制
},
代码语言:txt
复制
```
  • 然后我们再写一个模型 multipleSelection 用于存放从 this.multipleSelection 获取到的 id ```js // 复选框选中数据集合 multipleSelection: [], ```
  • 现在我们编写 deleteByIds 方法 ```js // 批量删除 deleteByIds() { // 弹出确认提示框 this.$confirm('此操作将删除该数据, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { // 用户点击确认按钮 // 1. 创建id 数组 从 this.multipleSelection 获取即可 for (let selectionElement of this.multipleSelection) { this.selectedIds.push(selectionElement.id); } // 2. 发送 ajax 请求,携带 ID var _this = this; // 发送 ajax 请求,添加数据 axios({ method: "post", url: "http://localhost:8080/brand-case/brand/deleteByIds", data: _this.selectedIds }).then(function (resp) { if (resp.data == 'success') { // 删除成功 // 重新查询数据 _this.selectAll();
代码语言:txt
复制
                // 弹出消息提示
代码语言:txt
复制
                _this.$message({
代码语言:txt
复制
                    message: '恭喜你,删除成功',
代码语言:txt
复制
                    type: 'success'
代码语言:txt
复制
                });
代码语言:txt
复制
            }
代码语言:txt
复制
        })
代码语言:txt
复制
    }).catch(() => {
代码语言:txt
复制
        // 用户点击取消按钮
代码语言:txt
复制
        this.$message({
代码语言:txt
复制
            type: 'info',
代码语言:txt
复制
            message: '已取消删除'
代码语言:txt
复制
        });
代码语言:txt
复制
    });
代码语言:txt
复制
}
代码语言:txt
复制
```

业务 - 分页查询

分析

  • SQL Limit 查询语句 - 参数1:开始索引 - 参数2:查询的条目数
  • 页面传递的参数 - 当前页码 - 每页显示条数
  • 计算 - 开始索引 = (当前页码 - 1) * 每页显示条数 - 查询的条目数 = 每页显示条数

后端

  • 创建 JavaBean:PageBean.java ```java package com.ruochen.pojo;
代码语言:txt
复制
import java.util.List;
代码语言:txt
复制
// 分页查询的 JavaBean
代码语言:txt
复制
public class PageBean<T> {
代码语言:txt
复制
    // 总记录数
代码语言:txt
复制
    private int totalCount;
代码语言:txt
复制
    // 当前页数据
代码语言:txt
复制
    private List<T> rows;
代码语言:txt
复制
    public int getTotalCount() {
代码语言:txt
复制
        return totalCount;
代码语言:txt
复制
    }
代码语言:txt
复制
    public void setTotalCount(int totalCount) {
代码语言:txt
复制
        this.totalCount = totalCount;
代码语言:txt
复制
    }
代码语言:txt
复制
    public List<T> getRows() {
代码语言:txt
复制
        return rows;
代码语言:txt
复制
    }
代码语言:txt
复制
    public void setRows(List<T> rows) {
代码语言:txt
复制
        this.rows = rows;
代码语言:txt
复制
    }
代码语言:txt
复制
}
代码语言:txt
复制
```
  • Dao 层:BrandMapper.java ```java /** * 分页查询 * * @param begin 开始索引 * @param size 查询数据条数 * @return */ @Select("select * from tb_brand limit #{begin}, #{size}") @ResultMap("brandResultMap") List<Brand> selectByPage(@Param("begin") int begin, @Param("size") int size);
代码语言:txt
复制
    /**
代码语言:txt
复制
     * 查询总记录数
     *
     * @return
     */
    @Select("select count(*) from tb_brand")
    int selectTotalCount();
```Service 层
		- Service 接口类:
代码语言:txt
复制
        // 4. 计算 开始索引 和 查询条目数
代码语言:txt
复制
        int begin = (currentPage - 1) * pageSize;
代码语言:txt
复制
        int size = pageSize;
代码语言:txt
复制
        // 5. 查询当前页数据
代码语言:txt
复制
        List<Brand> rows = brandMapper.selectByPage(begin, size);
代码语言:txt
复制
        // 6. 查询总记录数
代码语言:txt
复制
        int totalCount = brandMapper.selectTotalCount();
代码语言:txt
复制
        // 7. 封装 pageBean 对象
代码语言:txt
复制
        PageBean<Brand> pageBean = new PageBean<>();
代码语言:txt
复制
        pageBean.setRows(rows);
代码语言:txt
复制
        pageBean.setTotalCount(totalCount);
代码语言:txt
复制
        // 8. 释放资源
代码语言:txt
复制
        sqlSession.close();
代码语言:txt
复制
        return pageBean;
代码语言:txt
复制
    }
代码语言:txt
复制
```
  • Web 层:BrandServlet.java ```java /** * 分页查询 * * @param request * @param response * @throws ServletException * @throws IOException */ public void selectByPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 接收 当前页码 和 每页展示条数 url?currentPage=1&pageSize=5 String _currentPage = request.getParameter("currentPage"); String _pageSize = request.getParameter("pageSize");
代码语言:txt
复制
        // 转换为 int 类型
代码语言:txt
复制
        int currentPage = Integer.parseInt(_currentPage);
代码语言:txt
复制
        int pageSize = Integer.parseInt(_pageSize);
代码语言:txt
复制
        // 2. 调用 Service 查询
代码语言:txt
复制
        PageBean<Brand> pageBean = brandService.selectByPage(currentPage, pageSize);
代码语言:txt
复制
        // 2. 数据转为 JSON
代码语言:txt
复制
        String jsonString = JSON.toJSONString(pageBean);
代码语言:txt
复制
        // 3. 写数据
代码语言:txt
复制
        // 数据存在中文
代码语言:txt
复制
        response.setContentType("text/json;charset=utf-8");
代码语言:txt
复制
        response.getWriter().write(jsonString);
代码语言:txt
复制
    }
代码语言:txt
复制
```
  • 测试
    前端
  • 设置模型总记录数:totalCount,初值设为100,在selectAll方法中赋值
  • 当前页码模型 currentPage 初值设置为1
  • 每页条数模型 pageSize,默认值为 5 ```js // 每页显示条数 pageSize: 5, // 总记录数 totalCount: 100, // 当前页码 currentPage: 1, ```
  • currentPage 和 pageSize 动态拼接到 selectAll url 中
  • selectAll 方法改为查询分页 ```java // 查询分页数据 var _this = this; axios({ method: "get", url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + this.currentPage + "&pageSize=" + this.pageSize, }).then(function (resp) { // 设置表格数据 _this.tableData = resp.data.rows; // 设置总记录数 _this.totalCount = resp.data.totalCount; }) ```
  • 分页工具条绑定了 handleCurrentChangehandleSizeChange 方法,方法中将值设置到模型中,再调用 selectAll 方法即可 ```js //分页 handleSizeChange(val) { // console.log(`每页 ${val} 条`); // 重新设置每页显示条数 this.pageSize = val; // 重新查询 this.selectAll(); }, handleCurrentChange(val) { // console.log(`当前页: ${val}`); // 重新设置当前页码 this.currentPage = val; // 重新查询 this.selectAll(); }, ```

业务 - 条件查询

后端

在这里插入图片描述
在这里插入图片描述
  • Dao 层 - BrandMapper.java ```java /** * 分页条件查询 * * @param begin 开始索引 * @param size 查询数据条数 * @param brand 查询条件 * @return */ @ResultMap("brandResultMap") List<Brand> selectByPageAndCondition(@Param("begin") int begin, @Param("size") int size, @Param("brand") Brand brand);
代码语言:txt
复制
    /**
代码语言:txt
复制
     * 根据条件查询总记录数
     *
     * @param brand 查询条件
     * @return
     */
    int selectTotalCountByCondition(Brand brand);
```
- `BrandMapper.xml`
```xml
    <select id="selectByPageAndCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        <where>
            <if test="brand.brandName != null and brand.brandName != ''">
                and brand_name like #{brand.brandName}
            </if>
            <if test="brand.companyName != null and brand.companyName != ''">
                and company_name like #{brand.companyName}
            </if>
            <if test="brand.status != null">
                and status like #{brand.status}
            </if>
        </where>
        limit #{begin}, #{size}
    </select>
代码语言:txt
复制
    <select id="selectTotalCountByCondition" resultType="java.lang.Integer">
代码语言:txt
复制
        select count(*)
代码语言:txt
复制
        from tb_brand
代码语言:txt
复制
        <where>
代码语言:txt
复制
            <if test="brandName != null and brandName != ''">
代码语言:txt
复制
                and brand_name like #{brandName}
代码语言:txt
复制
            </if>
代码语言:txt
复制
            <if test="companyName != null and companyName != ''">
代码语言:txt
复制
                and company_name like #{companyName}
代码语言:txt
复制
            </if>
代码语言:txt
复制
            <if test="status != null">
代码语言:txt
复制
                and status like #{status}
代码语言:txt
复制
            </if>
代码语言:txt
复制
        </where>
代码语言:txt
复制
    </select>
代码语言:txt
复制
```
  • Service 层 - Service 接口类:BrandService.java ```java /** * 分页条件查询 * * @param currentPage * @param pageSize * @param brand * @return */ PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand); ```
代码语言:txt
复制
- Service 实现类:`BrandServiceImpl.java`
```java
    @Override
    public PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {
        // 2. 获取 SqlSession 对象
        SqlSession sqlSession = factory.openSession();
        // 3. 获取 BrandMapper
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
代码语言:txt
复制
        // 4. 计算 开始索引 和 查询条目数
代码语言:txt
复制
        int begin = (currentPage - 1) * pageSize;
代码语言:txt
复制
        int size = pageSize;
代码语言:txt
复制
        // 处理 brand 条件,模糊表达式
代码语言:txt
复制
        String brandName = brand.getBrandName();
代码语言:txt
复制
        if (brandName != null && brandName.length() > 0) {
代码语言:txt
复制
            brand.setBrandName("%" + brandName + "%");
代码语言:txt
复制
        }
代码语言:txt
复制
        String companyName = brand.getCompanyName();
代码语言:txt
复制
        if (companyName != null && companyName.length() > 0) {
代码语言:txt
复制
            brand.setCompanyName("%" + companyName + "%");
代码语言:txt
复制
        }
代码语言:txt
复制
        // 5. 查询当前页数据
代码语言:txt
复制
        List<Brand> rows = brandMapper.selectByPageAndCondition(begin, size, brand);
代码语言:txt
复制
        // 6. 查询总记录数
代码语言:txt
复制
        int totalCount = brandMapper.selectTotalCountByCondition(brand);
代码语言:txt
复制
        // 7. 封装 pageBean 对象
代码语言:txt
复制
        PageBean<Brand> pageBean = new PageBean<>();
代码语言:txt
复制
        pageBean.setRows(rows);
代码语言:txt
复制
        pageBean.setTotalCount(totalCount);
代码语言:txt
复制
        // 8. 释放资源
代码语言:txt
复制
        sqlSession.close();
代码语言:txt
复制
        return pageBean;
代码语言:txt
复制
    }
代码语言:txt
复制
```
  • Web 层:BrandServlet.java ```java /** * 分页条件查询 * * @param request * @param response * @throws ServletException * @throws IOException */ public void selectByPageAndCondition(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 接收 当前页码 和 每页展示条数 url?currentPage=1&pageSize=5 String _currentPage = request.getParameter("currentPage"); String _pageSize = request.getParameter("pageSize");
代码语言:txt
复制
        // 转换为 int 类型
代码语言:txt
复制
        int currentPage = Integer.parseInt(_currentPage);
代码语言:txt
复制
        int pageSize = Integer.parseInt(_pageSize);
代码语言:txt
复制
        // 获取查询条件对象
代码语言:txt
复制
        BufferedReader br = request.getReader();
代码语言:txt
复制
        String params = br.readLine();  // json 字符串
代码语言:txt
复制
        // 转为 brand 对象
代码语言:txt
复制
        Brand brand = JSON.parseObject(params, Brand.class);
代码语言:txt
复制
        // 2. 调用 Service 查询
代码语言:txt
复制
        PageBean<Brand> pageBean = brandService.selectByPageAndCondition(currentPage, pageSize, brand);
代码语言:txt
复制
        // 2. 数据转为 JSON
代码语言:txt
复制
        String jsonString = JSON.toJSONString(pageBean);
代码语言:txt
复制
        // 3. 写数据
代码语言:txt
复制
        // 数据存在中文
代码语言:txt
复制
        response.setContentType("text/json;charset=utf-8");
代码语言:txt
复制
        response.getWriter().write(jsonString);
代码语言:txt
复制
    }
代码语言:txt
复制
```

前端

  • 搜索框绑定模型 brand ```html <!--搜索表单--> <el-form :inline="true" :model="brand" class="demo-form-inline"> ```
  • 给按钮绑定单击事件 onSubmit ,调用 selectAll 方法,这里我们就要给后台携带 brand 参数(post 方式),但是我们还需要在 url 中携带 currentPage 和 pageSize 参数(get方式),需要同时传输 post 和 get 数据,所以把请求方式改为 post ```js // 查询分页数据 var _this = this; axios({ method: "post", url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + this.currentPage + "&pageSize=" + this.pageSize, data: this.brand }).then(function (resp) { // 设置表格数据 _this.tableData = resp.data.rows; // 设置总记录数 _this.totalCount = resp.data.totalCount; }) ```
  • onSubmit ```js this.currentPage = 1; ```
  • 最后,测试时我们发现 status 显示的仍然是数字,我们要让其显示 启动/禁用,我们在 Brand.java 里面有逻辑视图 getStatusStr,所以在前端页面表格中当前状态 prpostatusStr 即可 ```html <el-table-column prop="statusStr" align="center" label="当前状态"> </el-table-column> ```

业务 - 删除功能

后端

  • Dao 层:BrandMapper.java ```java /** * 删除操作 * @param id */ @Delete("delete from tb_brand where id = #{id}") void deleteById(int id); ```
  • Service 层 - Service 接口类:BrandService.java ```java /** * 删除 * @param id */ void deleteById(int id); ``` - Service 实现类:`BrandServiceImpl.java` ```java @Override public void deleteById(int id) { // 2. 获取 SqlSession 对象 SqlSession sqlSession = factory.openSession(); // 3. 获取 BrandMapper BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 4. 调用方法 brandMapper.deleteById(id); // 5. 提交事务 sqlSession.commit(); // 6. 释放资源 sqlSession.close(); } ```
  • Web 层:BrandServlet.java,这里我们不需要单独编写根据 id 删除的 servlet,直接调用 deleteByIdIds 即可前端
  • 删除操作前端要返回给后端删除数据的 id,这里我们通过 template 参数 scope 可以获取到当前行的数据,然后从数据中取出 id,携带 id 通过 axios 向后端发起请求即可 ```html <el-table-column align="center" label="操作"> <template slot-scope="scope"> <el-row> <el-button type="primary">修改</el-button> <el-button type="danger" @click="deleteById(scope.row)">删除</el-button> </el-row> </template> </el-table-column> ``` ```js // 根据Id 删除 deleteById(row) { this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { // 用户点击确认按钮 let rowId = [row.id]; // 发送 ajax 请求,携带 id axios({ method: "pose", url: "http://localhost:8080/brand-case/brand/deleteByIds", data: rowId }).then(resp => { if (resp.data == 'success') { // 删除成功 // 重新查询数据 this.selectAll();
代码语言:txt
复制
                // 弹出消息提示
代码语言:txt
复制
                this.$message({
代码语言:txt
复制
                    message: '恭喜你,删除成功',
代码语言:txt
复制
                    type: 'success'
代码语言:txt
复制
                });
代码语言:txt
复制
            }
代码语言:txt
复制
        })
代码语言:txt
复制
    }).catch(() => {
代码语言:txt
复制
        this.$message({
代码语言:txt
复制
            type: 'info',
代码语言:txt
复制
            message: '已取消删除'
代码语言:txt
复制
        });
代码语言:txt
复制
    });
代码语言:txt
复制
}
代码语言:txt
复制
```

业务 - 修改功能

后端

  • Dao 层:BrandMapper.java ```java /** * 更新操作 * * @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); ```
  • Service 层 - Service 接口类:BrandService.java ```java /** * 修改 * @param brand */ void update(Brand brand); ``` - Service 实现类:`BrandServiceImpl.java` ```java @Override public void update(Brand brand) { // 2. 获取 SqlSession 对象 SqlSession sqlSession = factory.openSession(); // 3. 获取 BrandMapper BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 4. 调用方法 brandMapper.update(brand); // 5. 提交事务 sqlSession.commit(); // 6. 释放资源 sqlSession.close(); } ``` - Web 层:`BrandServlet.java` ```java /** * 更新操作 * * @param request * @param response * @throws ServletException * @throws IOException */ public void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 接收品牌数据 BufferedReader br = request.getReader(); String params = br.readLine(); // json 字符串
代码语言:txt
复制
        // JSON 字符串转为 brand 对象
代码语言:txt
复制
        Brand brand = JSON.parseObject(params, Brand.class);
代码语言:txt
复制
        // 2. 调用 service 添加
代码语言:txt
复制
        brandService.update(brand);
代码语言:txt
复制
        // 3. 响应成功标识
代码语言:txt
复制
        response.getWriter().write("success");
代码语言:txt
复制
    }
代码语言:txt
复制
```

前端

  • 首先,我们要新建一个 dialog 来进行数据回显(不用直接用新增数据的 dialog 的原因是新增 dialog 绑定的模型 brand 在搜索框也有绑定,直接使用会出现乱七八糟的问题),同时绑定模型 updateBrand ```html <!--更新数据对话框表单--> <el-dialog title="更新品牌" :visible.sync="updateVisible" width="30%" >
代码语言:txt
复制
    <el-form ref="form" :model="updateBrand" label-width="80px">
代码语言:txt
复制
        <el-form-item label="品牌名称">
代码语言:txt
复制
            <el-input v-model="updateBrand.brandName"></el-input>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
        <el-form-item label="企业名称">
代码语言:txt
复制
            <el-input v-model="updateBrand.companyName"></el-input>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
        <el-form-item label="排序">
代码语言:txt
复制
            <el-input v-model="updateBrand.ordered"></el-input>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
        <el-form-item label="备注">
代码语言:txt
复制
            <el-input type="textarea" v-model="updateBrand.description"></el-input>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
        <el-form-item label="状态">
代码语言:txt
复制
            <el-switch v-model="updateBrand.status"
代码语言:txt
复制
                       active-value="1"
代码语言:txt
复制
                       inactive-value="0"
代码语言:txt
复制
            ></el-switch>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
        <el-form-item>
代码语言:txt
复制
            <el-button type="primary" @click="updateByBrand">提交</el-button>
代码语言:txt
复制
            <el-button @click="updateVisible = false">取消</el-button>
代码语言:txt
复制
        </el-form-item>
代码语言:txt
复制
    </el-form>
代码语言:txt
复制
</el-dialog>
代码语言:txt
复制
```
  • updateBrand 模型 和 updateVisible 定义如下 ```js // 更新brand updateBrand: { status: '', brandName: '', companyName: '', id: "", ordered: "", description: "" }, // 更新数据对话框是否展示的标记 updateVisible: false, ```
  • 在修改按钮通过 slot-scopescope.row 获取选中行数据 ```html <el-table-column align="center" label="操作"> <template slot-scope="scope"> <el-row> <el-button type="primary" @click="update(scope.row)">修改</el-button> <el-button type="danger" @click="deleteById(scope.row)">删除</el-button> </el-row> </template> </el-table-column> ```
  • 修改按钮绑定 update 方法,进行数据回显 ```js // 数据回显 update(row) { // 数据回显 this.updateBrand = { status: row.status, brandName: row.brandName, companyName: row.companyName, id: row.id, ordered: row.ordered, description: row.description }; // 打开窗口 this.updateVisible = true; }, ```
  • update dialog 绑定 updateByBrand 方法,进行更新操作 ```js // 更新数据 updateByBrand() { // 发送 ajax 请求,添加数据 axios({ method: "post", url: "http://localhost:8080/brand-case/brand/update", data: this.updateBrand }).then(resp => { if (resp.data == 'success') { // 添加成功 // 关闭窗口 this.updateVisible = false; // 重新查询数据 this.selectAll();
代码语言:txt
复制
            // 弹出消息提示
代码语言:txt
复制
            this.$message({
代码语言:txt
复制
                message: '恭喜你,更新成功',
代码语言:txt
复制
                type: 'success'
代码语言:txt
复制
            });
代码语言:txt
复制
        }
代码语言:txt
复制
    })
代码语言:txt
复制
}
代码语言:txt
复制
```

问题:status(switch开关)回显有问题,目前不会实现

前端代码优化

  • 最后,我们对 axios 进行一下优化,之前我们的异步请求代码是这样的 ```js var _this = this; axios({ method: "post", url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + this.currentPage + "&pageSize=" + this.pageSize, data: this.brand }).then(function (resp) { // 设置表格数据 _this.tableData = resp.data.rows; // 设置总记录数 _this.totalCount = resp.data.totalCount; }) ```
  • 因为在 axios 中 this 指代的是 axios 而不是 vue,我们每次都需要在 axios 外面先将指代 vue 的 this 赋值给 _this,然后在 axios 中使用 _this 调用 vue 中的模型,这样很不方便
  • 我们可以将 axios then 的 function 改为箭头函数,箭头函数中 this 会根据上下文语义进行判断,这样就可以代表 vue 对象,修改如下```js axios({ method: "post", url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + this.currentPage + "&pageSize=" + this.pageSize, data: this.brand }).then(resp => { // 设置表格数据 this.tableData = resp.data.rows; // 设置总记录数 this.totalCount = resp.data.totalCount; }) ```最后的成品我也打包放在了网盘,需要可以自行下载 链接:https://pan.baidu.com/s/1Ps3parEeOJtazS-Kv7bWEw 提取码:msjj

觉得本文还不错可以点个赞支持一下 :smile:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备工作
  • 业务 - 查询所有
    • 后端
      • 前端
        • 后端
          • 前端
          • Servlet 优化
          • 业务 - 批量删除
            • 后端
              • 前端
              • 业务 - 分页查询
                • 分析
                  • 后端
                  • 业务 - 条件查询
                    • 后端
                      • 前端
                      • 业务 - 删除功能
                        • 后端
                        • 业务 - 修改功能
                          • 后端
                            • 前端
                            • 前端代码优化
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                            http://www.vxiaotou.com