商品增删改查以及查询+批量删除
image.png

环境搭建

  1. 创建Maven文件引入依赖

image.png

  1. 实现逻辑

image.png

查询所有

后端代码

  1. 使用Mybatis插件创建对应的配置文件

image.png

  1. 创建Mapper层并在resource中创建同样目录下的xxxMapper.xml

image.png

  1. 后端三层架构实现
    1. 创建实体层

image.png

  1. 创建对应的Mapper层

image.png

  1. 创建对应的Service层(旧版)

image.png

  1. 创建对应的Service层(新版)
    1. 旧版直接在servlet中新建service对象,service层更改servlet也要更改
    2. 新版通过接口实现service对象,在servlet中创建对应的实现类指向接口
    3. 未来spring直接管理对象,可以通过接口自动分配实现类
    4. 优化外层代码耦合度

image.png

  1. 创建对应的Servlet层
    1. 创建实现接口类Service层对象
    2. 查询方法接口层调用service对象的方法
    3. 使用JSON.toString将对象序列化
    4. 处理JSON中文乱码问题使用setContentType
    5. 将处理的数据响应给浏览器

image.png

前端页面

image.png

  1. 页面加载完成后发送异步请求获取列表数据
  2. 使用mounted生命周期并使用axios放松ajax请i去
  3. 创建对应的模型数据将数据渲染到页面
  4. 因为axios中异步的数据是dom层的需要将数据赋值给vue
  5. 使用this.data获取dom层的数据,在vue层面定义方法接收该值

image.pngimage.png
代码可以看出resp.data是服务器响应的数据
自定义的_this.tableData是vue自定义的渲染的数据模型

新增品牌

image.png

后端代码

Mapper层

  1. Mapper层写入对应的添加方法
  2. 使用@Insert注解添加语句

image.png
Service层

  1. Service层在对应的接口层写方法,实现类重写添加方法
  2. 调用SqlSessionFactoryUtil工具类
  3. 获取SqlSession对象,反射对应的Mapper类
  4. 调用Mapper类添加方法
  5. 因为是增删改操作需要开启事务commit()

image.png
Servlet层

  1. 获取浏览器post请求数据
  2. 因为是JSON数据无法使用getParameters获取
  3. 使用字符输入流读取数据
  4. 并使用JSON工具反序列化为Java对应的类的对象
  5. 调用Service层封装的方法
  6. 添加成功服务层添加响应数据

image.png

前端页面

image.pngimage.png
弹窗表单
image.png
提交方法以及表单模型数据

  1. 添加查询方法调用selectAll()方法
  2. 调用mounted生命周期页面加载后异步加查询方法
  3. 创建添加功能,异步提交post请求携带dom层数据判断回调数据
  4. 成功关闭弹窗并重新调用selectAll()方法,并添加添加成功提示框

TIPS: 区别this和自定义的vue获取变量的值

  1. mounted()中使用this直接调用查询selectAll()方法是因为mounted和methods都属于vue标签属性并没有声明额外变量去获取DOM层的值
  2. 但是在methods的添加功能中提前生命了将DOM的值this赋值给vue的变量操作所以在addBrand()中使用自定义变量调用的selectAll()方法

image.png

Servlet 代码优化

image.png
image.png
image.png
image.png

实现原理

  1. 原有Servlet是直接继承HttpServlet重写doGet()和doPost()方法
  2. 源码HttpServlet的doGet()和doPost()是初始方法是service方法
  3. 现自定义Servlet共用类继承HttpServlet直接重写service方法
  4. 将接口统一定义为一个servlet并将各个路径和对应方法名绑定

代码实现:

获取路径名

  1. 使用req.getRequestURI()获取请求路径的段路径
  2. 使用字符串lastIndexof(‘/‘)从后往前数获取该字符串的索引
  3. 在使用substring()传递该字符串索引切割后,留下后面的字符串
  4. 最终得到路径名

image.png
image.pngimage.pngimage.png

获取方法名

  1. 获取方法使用反射特性getClass()
  2. 因为不是获取特定的servlet而是要根据谁调用了这个service方法而反射哪个servlet
  3. 所以使用this这个关键字指向调用该service
    1. this:谁(this所在的方法)调用我,我(this)就是谁
    2. 所直接对this使用getClass()放射方法获得对应的Class对象
  4. 获得Class对象后调用该文件字节码的Method方法对象
  5. 使用反射中的invoke传入方法名,以及方法需要的参数

image.png
image.pngimage.png
image.pngimage.png

实现方法

  1. 创建总业务层Servlet继承定义了方法路径绑定的BaseServlet
  2. 更改路径使用业务层+通配符*
  3. 将之前Servlet的代码复制到对应的方法名下
  4. 更改页面axios路径

image.png
image.png

批量删除

image.png
后端:
image.png
前端:
image.png
代码实现:

后端代码

  1. Dao层对应的Mapper创建deletByIds(int[] ids)方法
    1. 因为是传入一个数组,所以在对应的xml文件中使用动态sql语句
    2. 批量删除语句delet * from tb_brand where id in (?,?,?)
    3. 使用标签循环遍历的id数组然后传递给sql语句的id
    4. 其中collction 属性是集合,item是遍历后获得的属性值
    5. open和close是开始标签和结束标签,separator是分隔符

image.pngimage.png

  1. 在Service层定义接口方法void deletByIds(int[] ids)
    1. 并在Impl实现层封装Mapper方法
    2. 增删改需要提交事务

image.png

  1. 在BrandServlet层定义删除方法接口为方法名
    1. 传入对应的HttpServletRequest request, HttpServletResponse response
    2. 不能使用getParameters,接收定义JSON数组必须使用字符输入流
    3. 使用JSON.parseObject传入对应的int[]类型数组对象
    4. 调用service层删除方法并响应数据

image.png

前端代码

  1. Dom层代码绑定点击事件与填报表格中复选框点击事件联动
    1. 前端代码创建批量删除点击事件
    2. 获取填报表格中的复选框点击事件的回调函数

image.png

  1. Data数据模型创建id数组

image.png

  1. methods方法
    1. 创建批量删除功能方法deletByIds
    2. 添加提示框内容确认提交后遍历复选框数组并传给定义的id模型数组
    3. 可以直接使用遍历后的索引给对应的id模型赋值
    4. 也可以直接使用push方法传递给集合
    5. 最后发送ajax的post请求将id模型数组传递给后端
    6. 成功给出提示,并调用selectAll()方法刷新页面

image.png

分页查询

SQL查询 — LIMIT

image.png
不规定初始参数查询10条数据
image.png
从第五个索引开始,查询5条数据
image.png
分页查询LIMIT参数逻辑:

  1. 参数1: 开始索引是(当前页码-1)* 每页需要显示的条数
  2. 参数2: 每页需要查询的条数

image.png

实现逻辑

image.png

后端代码

image.png

  1. Dao层创建前端需要的数据对应的方法
    1. 当前页List数据 — selectByPage(begin,size)
      1. 对应的是Limit的SQL查询语句
      2. begin是索引,size是查询条目
      3. @Select(“select * from tb_brand limit #{begin},#{size}”)
    2. 查询总数 — selectTotalCount()
      1. 使用count(*)关键字
      2. @Select(“select count(*) from tb_brand”)
    3. 创建PageBean对象创建字段封装这两个数据
  2. Service层在则封装Dao层方法
    1. 创建分页查询方法,返回PageBean对象,
      1. 参数值1: 当前页面(客户端)
      2. 参数值1: 每页查询数量(客户端)
    2. 实现层Impl实现该方法
      1. 常规获取sqlSession对象
      2. 客户端传入的当前页码currentPage
        1. 需要使用SQL固定分页方法
        2. 分页查询第一个参数是(当前页-1)* 每页显示记录数
        3. 所以定义变量 int begin = (currentPage -1)* pageSize
      3. 调用mapper定义的selectByPage该方法的数据是当前页list数据
        1. 将定义的begin以及客户端传入的pageSize传入该方法中
        2. 获取查每页数据
      4. 调用mapper定义的另一个方法selectTotalCount()
      5. 将调用后的mapper方法后的变量封装到PageBean对象中
      6. 最后释放资源,返回PageBean对象
  3. Servlet层添加接口方法
    1. 获取前端传递的两个参数request.getParameter
      1. 当前页面使用
      2. 每页展示条数
      3. 使用Interger.parseInt转移为int类型
    2. 将获取的两个参数
      1. 传递到service层的方法selectByPage中获取每页展示数据
      2. 并且封装成PageBean对象
      3. 使用JSON.toJSONString序列化对象
      4. 响应该JSON对象到客户端
    3. 测试接口

image.pngimage.png

前端代码

分页工具条:

  1. 前端传递后端回调函数
    1. handleCurrentChange是当前页数回调
      1. 需要作为currentPage参数传递给后端
      2. 是LIMIT的SQL语句的第一个参数
    2. handleSizeChange是每页显示行数
      1. 需要作为pageSize参数传递给后端
      2. 是LIMIT的SQL语句的第二个参数
    3. 前端Dom组件
      1. v-bind 简化成:
      2. current-page 当前页
      3. page-size 每页显示数据行
      4. total 总页数

image.png
mounted生命周期:

  1. 前端页面加载后
  2. 加载异步请求调用selectByPage方法

image.png
定义data数据模型以及methods方法

  1. data数据模型:

image.png

  1. methods方法:

image.png

条件查询

SQL查询

and limit

image.png
image.png

后端代码

image.png

  1. Dao层逻辑代码提供两个方法
    1. selectByPageAndCondition(begin,size,band)
      1. 分页方法需要传递:
        1. begin当前页索引
        2. size当前页显示条目数据
      2. band是条件查询
        1. 因为条件是满足对应查询的brand对象
        2. mapper中使用@Param指向brand对象
        3. brand对象封装了需要调用的成员变量
        4. 在xml的动态sql中需要使用brand去调用其成员变量
    2. selectTotalCount(brand)
      1. 同样条件是满足条件查询的brand对象
      2. 所以需要将满足条件的brand对象封装
      3. 因为没有指定@Param对象所以可以直接使用其成员变量
    3. TIPS: 在多参数指定@Param是用于区别参数对象的
      1. SQL语句可能会存在多个对象
      2. @Param注解用于区别,当SQL语句含有多个对象
        1. 例如@Param(“brand”)Brand brand,@Param(“user”)Brand user
        2. 可以在xml动态语言中调用对象对应的成员变量
        3. #{brand.brandName}和#{user.name}

image.png
1.1 Dao层逻辑代码XML

  1. selectByPageAndCondition(begin,size,band) —xml
  2. selectTotalCount(brand) —xml

`image.png

  1. Servkce层创建业务方法
    1. 在实现层写条件分页查询方法
      1. PageBean selectByPageAndCondition(int currentPage, int pageSize, Brand brand);
    2. 返回值是之前定义接收分页查询方法的对象PageBean
    3. 参数:currentPage当前页
    4. 参数:pageSize 每页显示条数
    5. 参数:brand带有条件的对象

2.2 Service实现层,调用mapper方法并封装该方法

  1. 获取sqlSession对象,反射对应的类
  2. 浏览器传入的pageSize创建记录索引
  3. 需要将浏览器传入的brand的JSON对象进行处理
    1. 判断对应的brand的成员变量是否存在
    2. 存在则设置为字符串模糊查询(”%”+xxx+”%”)
  4. 调用模糊查询的封装类对象 根据brand数量调用查询的总数
  5. 将页面索引,查询条目数,条件对象传入到selectByPageAndCondition方法中
  6. 创建对象封装满足条件当前页数据以及条件对象总数目

image.png

  1. Servlet 层创建业务方法
    1. 获取前端url中携带人currentPage以及pageSize参数
      1. 使用request.getParameter()
      2. 将获取的url参数转换为integer对象
    2. 前端页面post和get同时携带的数据以及url数据
    3. 因为获取的是JSON对象(满足条件的brand对象)
      1. 不能使用getParameter()
      2. 使用字符流接收对象
      3. 并使用JSON.parseObject(xx,xx.Class)反序列化对象
    4. 将获取的currentPage和pageSize以及反序列化后的brand对象传入service方法
    5. 将获取的对象重新使用JSON.toJSONString序列化响应到页面

image.png

前端代码

image.png
image.png

  1. 页面加载后mounted异步请求加载一下不含条件的对象
  2. 点击按钮后携带当前页,每页显示条数,以及符合条件的对象传入到后端
  3. 后端调用servlet方法后,将封装好的pageBean对象序列化为JSON响应到客户端
  4. 原理页面更改原有分页查询数据改为条件查询数据
    1. 不添加任何条件则是分页查询数据
    2. 将currentPage,pageSize以url方式传入
    3. 更改提交方法为post将数据模型brand发送给服务器
    4. 更改回调函数then(funtion(resp){xxx})方法为箭头函数then(resp=>{xxx})
    5. 更改箭头函数后可以直接使用this将vue模型数据指向服务器数据
  5. 在查询按钮方法中直接调用分页查询方法

image.png