项目总体样式如下:

重点功能:模糊条件分页查询功能:


PageBean实体类:
- package com.itheima.pojo;
-
- import java.util.List;
-
- /**
- * PageBean: 分页查询功能用来封装数据传递给前端的
- */
- public class PageBean<T> { // 这里自定义一个泛型
-
- // 总商品数
- private int totalCount;
-
- // 当前页数据 ( 把当前页查询出来的数据以List集合的形式封装到属性当中传递给前端 )
- private List<T> rows;
- /**
- * 这里用自定义的泛型T : 因为以后开发项目的时候 我们有可能有Brand实体类,也有可能有User实体类等。
- * 我们自定义好泛型之后,以后谁new 这个PageBean类 这个泛型里面就是谁
- */
-
-
- // getter and setter
-
- public int getTotalCount() {
- return totalCount;
- }
-
- public void setTotalCount(int totalCount) {
- this.totalCount = totalCount;
- }
-
- public List<T> getRows() {
- return rows;
- }
-
- public void setRows(List<T> rows) {
- this.rows = rows;
- }
- }
- package com.itheima.mapper;
- import com.itheima.pojo.Brand;
- import org.apache.ibatis.annotations.*;
-
- import java.util.List;
-
- public interface BrandMapper {
-
- /**
- * 1、查询所有商品功能
- *
- */
-
- @Select("select * from tb_brand")
- @ResultMap("brandResultMap")
- List<Brand> selectAll();
-
- /**
- * 2、添加商品功能
- */
- @Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
- void add(Brand brand);
-
- /**
- * 3、批量删除功能
- *
- * 批量删除:因为我们不知道客户端会传过来几个删除id,因此这里我们要用动态sql 并且不能用注解的形式了
- */
-
- void deleteByIds(int[] ids);
-
- /**
- * 4、 查询当前页的数据功能
- * 思路: 拿到客户端请求的 ”第几页页数“ 和 “每页展示数据数”,我们拿到之后,再把这页的数据全部查询出来展示给客户端
- */
- @Select("select * from tb_brand limit #{begin},#{size}")
- @ResultMap("brandResultMap")
- List<Brand> selectByPage(@Param("begin") int begin, @Param("size") int size);
-
- /**
- * 5、查询数据库商品总数功能
- * 把数据库商品的总个数查询出来响应给前端
- */
- @Select("select count(*) from tb_brand")
- int selectTotalCount();
-
-
- /**
- * 6、分页模糊条件查询功能
- *
- * 接收前端请求的“页码数”和“每页展示数据数”和“模糊查询的数据请求”(在前端页面看:客户端模糊查询请求的数据只有三个:当前状态、企业名称、品牌名称)
- *
- * (因为模糊条件查询:比如说客户端就请求了一个企业名称:“阿里巴巴”,但是我们数据库当中会有什么不同的关于“阿里巴巴”的数据,
- * 因为是模糊查询所以会查出来很多的数据,前端呢因为怕查询出来的数据太多了所以想分页,所以我们后端接收到前端请求的 “当前页码”,
- * “每页展示数据个数” 和“模糊查询的数据” 进行模糊分页查询就可以了
- * 就是按一页几条数据来进行查询响应给前端即可了 )
- *
- *
- * begin: 当前页码
- * size: 每页展示数据个数
- * brand对象: 模糊查询的前端数据请求
- *
- * 注意:@Param("") 里面的数据对应的是SQL语句的参数占位符 也就是SQL语句中 #{} 内的数据
- *
- * @return
- */
-
- List<Brand> selectByPageAndCondition(@Param("begin") int begin, @Param("size") int size, @Param("brand") Brand brand);
-
- /**
- * 7、查询模糊查询出来的总商品数量功能
- * 因为这里面就一个brand对象 所以对象的属性名就相对应着SQL语句的 #{"参数占位数"}
- */
-
- int selectTotalCountByCondition(Brand brand);
-
-
- }
BrandMapper.xml:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.itheima.mapper.BrandMapper">
-
- <resultMap id="brandResultMap" type="brand">
- <result property="brandName" column="brand_name" />
- <result property="companyName" column="company_name" />
- </resultMap>
-
-
-
- <delete id="deleteByIds">
- delete from tb_brand where id in
- <foreach collection="ids" item="id" separator="," open="(" close=")">
- #{id}
- </foreach>
-
-
- </delete>
- <!-- where brand_name = #{brand.brandName}-->
- <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 = #{brand.status}
- </if>
-
- </where>
-
- limit #{begin} , #{size}
-
- </select>
- <select id="selectTotalCountByCondition" resultType="java.lang.Integer">
-
- select count(*)
- from tb_brand
- <where>
- <if test="brandName != null and brandName != '' ">
- and brand_name like #{brandName}
- </if>
-
- <if test="companyName != null and companyName != '' ">
- and company_name like #{companyName}
- </if>
-
- <if test="status != null">
- and status = #{status}
- </if>
-
- </where>
-
- </select>
-
- </mapper>
BrandService接口:(基本上和代理接口代码是一样的)
- package com.itheima.service;
- import com.itheima.pojo.Brand;
- import com.itheima.pojo.PageBean;
- import org.apache.ibatis.annotations.Param;
- import org.apache.ibatis.annotations.ResultMap;
- import org.apache.ibatis.annotations.Select;
-
- import java.util.List;
- public interface BrandService {
-
- /**
- * 1、查询所有商品
- *
- * @return
- */
- List<Brand> selectAll();
-
- /**
- * 2、添加商品
- *
- * @param brand
- */
- void add(Brand brand);
-
- /**
- * 3、批量删除
- */
-
- void deleteByIds(int[] ids);
-
- /**
- * 4、查询当前页数据功能 & 查询数据库商品的总个数
- *
- * @param begin : 当前页数
- * @param size : 每一页的展示数据个数
- * @return
- */
-
- PageBean<Brand> selectByPage(int begin, int size);
-
-
-
- /**
- * 6、分页模糊条件查询功能 & 模糊查询出总商品数功能
- * @return
- */
-
- PageBean<Brand> selectByPageAndCondition( int begin, int size, Brand brand);
-
-
-
-
- }
BrandServiceImpl:(实现BrandService接口)【该BrandServiceImpl实现了BrandService接口中的所有方法,因为BrandService接口中写的代码逻辑基本上和mapper层的代理接口一样,所以我们在BrandServiceImpl类中做业务逻辑同样相当于以前单独的一个BrandService类中的形式是一样的。】
细节1:使用BrandServiceImpl类实现BrandService接口做业务逻辑作用:降低了service层和web层的耦合度
细节2:所有的逻辑基本上就在业务逻辑层做处理,比如模糊查询需要用到%%,把查询的数据封装到对象属性中等、
- package com.itheima.service.impl;
- import com.itheima.mapper.BrandMapper;
- import com.itheima.pojo.Brand;
- import com.itheima.pojo.PageBean;
- import com.itheima.service.BrandService;
- import com.itheima.util.SqlSessionFactoryUtils;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
-
- import java.util.List;
-
- /**
- * 用这个类实现接口(BrandService)的最终目的:
- * 降低service业务逻辑层和web层的servlet之间的耦合度
- *
- * 原因: 以前的BrandService类(业务逻辑层)里面是用的方法,把增删改查等全部写成了方法返回到servlet层的
- * 现在是把这些增删改查的方法单独写到了实现BrandService接口的这个类当中了,降低了耦合度
- */
-
- public class BrandServiceImpl implements BrandService {
- // 1. 创建工厂对象
- SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
-
- /**
- * 1、查询所有商品
- *
- * @return
- */
- @Override
- public List<Brand> selectAll() {
- // 2. 获取Session
- SqlSession sqlSession = factory.openSession();
- // 3. 映射出BrandMapper接口
- BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
-
- // 4. 调用BrandMapper接口中的查询所有的方法
- List<Brand> brands = brandMapper.selectAll();
-
- // 释放资源
- sqlSession.close();
- return brands;
- }
-
-
- /**
- * 2、添加商品
- *
- * @param brand
- */
- @Override
- public void add(Brand brand) {
- // 2. 获取Session
- SqlSession sqlSession = factory.openSession();
- // 3. 映射出BrandMapper接口
- BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
-
- // 4. 调用BrandMapper接口中的查询所有的方法
- brandMapper.add(brand);
-
- // 5. 提交事务
- sqlSession.commit();
- // 6. 释放资源
- sqlSession.close();
-
- }
-
-
- /**
- * 3、批量删除
- */
- @Override
- public void deleteByIds(int[] ids) {
-
- // 2. 获取Session
- SqlSession sqlSession = factory.openSession();
- // 3. 映射出BrandMapper接口
- BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
-
- // 4. 调用BrandMapper接口中的批量删除的方法
- brandMapper.deleteByIds(ids);
-
- // 5. 提交事务
- sqlSession.commit();
- // 6. 释放资源
- sqlSession.close();
-
- }
-
-
- /**
- * 4、查询当前页数据功能 & 查询数据库商品的总个数
- *
- * 思路: 把查询出来的当前页数据和数据库商品的总个数 封装到PageBean对象的属性当中,然后把PageBean对象返回给前端
- *
- * @param begin : 当前页数
- * @param size : 每一页的展示数据个数
- */
- @Override
- public PageBean<Brand> selectByPage(int begin,int size) {
- // 4.2. 获取Session
- SqlSession sqlSession = factory.openSession();
- // 4.3. 映射出BrandMapper接口
- BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
-
- /**
- * 重点: 在这里进行一下SQL语句分页查询的计算
- * 如: select * from emp limit 0,8; # 计算公式:起始索引(页数)从0开始 起始索引 =(当前查询的页数-1)*每页展示数据数
- * 我们拿到的客户端请求的页数是第begin页,那么我们的SQL查询起始索引就是(begin-1)* size
- */
-
- // 4.4、计算起始索引
- int begin1 =(begin-1)*size;
-
- // 4.5、计算每页展示的数据个数
- int size1 =size;
-
- /**
- * 4.6、调用BrandMapper接口的查询当前页数据的功能
- */
- List<Brand> brands =brandMapper.selectByPage(begin1,size1);
-
- /**
- * 4.7、调用BrandMapper接口的查询数据库商品总数的功能
- */
- int totalCount =brandMapper.selectTotalCount();
-
- /**
- * 4.8、
- * 把 6、7 查询出来的数据封装到PageBean对象的属性当中 返回给前端
- */
- PageBean<Brand> pageBean =new PageBean<>();
- // 把数据封装到PageBean对象属性当中
- pageBean.setRows(brands);
- pageBean.setTotalCount(totalCount);
-
- /**
- * 4.9、把pageBean对象返回给前端(属性中已经封装好查询出来的数据咯)
- */
- sqlSession.close();
- return pageBean;
-
- }
-
- /**
- * 5、 分页模糊条件查询功能 & 模糊查询出总商品数功能
- * @param begin :当前页数
- * @param size : 每页中展示的数据数
- * @param brand : 模糊条件查询的数据
- * @return
- */
-
- @Override
- public PageBean<Brand> selectByPageAndCondition(int begin, int size, Brand brand) {
- // 5.2. 获取Session
- SqlSession sqlSession = factory.openSession();
- // 5.3. 映射出BrandMapper接口
- BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
-
-
- /**
- * 5.4、 调用BrandMapper接口中的 "分页模糊条件查询功能" ( 把模糊查询的结果按分页的形式查询出来,等会响应给前端 )
- *
- * 注意:这里传参之前要把brand对象当中各属性加上 ”%属性名%“ (因为brand对象属性当中封装了前端模糊查询的请求数据,
- * 又因为模糊查询SQL语句是: like %数据% 所以要处理属性)
- *
- * // !!!! 1、这里要进行一下判断 不判断的话 如果有为null的 那下面模糊处理 就成了 %null% 就会使SQL语句错误了
- * // !!!! 2、还要进行分页查询的计算
- */
- // 处理模糊表达式
- String brandName =brand.getBrandName();
- if (brandName!=null && brandName.length() >0){ // 这里要进行一下判断 不判断的话 如果有为null的 那下面模糊处理 就成了 %null% 就会使SQL语句错误了
-
- brand.setBrandName("%" +brandName+ "%"); // 再把客户端请求的数据做一下模糊表达式处理(如:"%华为%")),然后再封装到属性当中 传给代理接口进行SQL语句查询
- System.out.println(brand.getBrandName());
- }
-
- String companyName =brand.getCompanyName();
- if (companyName!=null && companyName.length() >0){ // 不为null 说明前端请求的有值
- brand.setCompanyName("%" +companyName+ "%"); // 再把客户端请求的数据做一下模糊表达式处理(如:"%华为%")),然后再封装到属性当中 传给代理接口进行SQL语句查询
- }
-
- // 分页计算
- int begin1 =(begin-1)*size;
- int size1 =size;
-
-
- List<Brand> brands =brandMapper.selectByPageAndCondition(begin1,size1,brand); // 这里再传的对象属性就是进行过模糊处理的属性数据
-
- /**
- * 5.5、 调用BrandMapper接口中的查询 "模糊查询出来的总商品数量" 功能方法 ( 把模糊查询查询出来的总商品数量查询出来,等会响应给前端 )
- */
- int counts =brandMapper.selectTotalCountByCondition(brand);
-
- /**
- * 5.6、 把 5.4、5.5 查询出来的结果 封装到PageBean对象属性当中,传递响应给前端
- */
-
- PageBean<Brand> pageBean =new PageBean<>();
- // 封装数据到属性当中
- pageBean.setTotalCount(counts);
- pageBean.setRows(brands);
-
-
- // 释放资源,返回PageBean对象
- sqlSession.close();
- return pageBean;
-
- }
- }
-
-
(使用优化后的servlet。 作用:减少了servlet的个数,以前我们做增删改查的时候就要写增删改查的servlet,需要写4个,太繁琐 ,优化后把每个servlet写成对象方法了 直接调用即可)
可以说因为BsaeServlet继承了HttpServlet,又BrandServlet继承了BsaeServlet,BrandServlet头上又写了访问的路径,所以可以说BrandServlet继承了HttpServlet并自带访问路径地址,可以说和以前的doGet、doPost使用方法又一样了
BsaeServlet:
这个类继承了HttpServlet,能继承service()方法 【可以理解为该方法是doPost,doGet他爹】
- package com.itheima.web.servlet;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- 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 {
- // 1. 获取请求路径
- String url =req.getRequestURI();
-
- // 获取最后一段路径(方法名)
- int index =url.lastIndexOf("/"); // 从路径后面数 第一次出现“/”的位置
- String methodName =url.substring(index+1); // 获取到从“/”开始截取的后面的路径 (这里我们不要/ 所以+1)
- // System.out.println(methodName);
-
- // 2. 执行BrandServlet对象中的selectAll方法
-
- // 2.1 获取BrandServlet 字节码对象 Class (映射)
- Class<? extends BaseServlet> cls =this.getClass();
- /**
- * 注意:这个 this代表的是谁?
- * 因为BrandServlet继承了该BaseServlet,所以可以说BrandServlet类当中也有BaseServlet类当中的
- * service()方法,当客户端请求路径 @WebServlet("/brand/*") 格式的时候,会进入到BaseServlet资源
- * 路径下,会自动调用该service()方法,所以谁调用该方法,this就代表哪个对象
- * 因为实际上是BrandServlet类中调用的service()方法 所以this代表BrandServlet对象
- */
-
- // 2.2 获取方法 Method对象(映射)
- try {
-
- Method method =cls.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
-
-
- // 2.3 调用该方法 (映射)
- method.invoke(this,req,resp); // 把客户端的请求数据传到service方法参数中
-
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
-
-
- }
- }
BrandServlet: (继承了BsaeServlet类):
- package com.itheima.web.servlet;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.itheima.pojo.Brand;
- import com.itheima.pojo.PageBean;
- import com.itheima.service.BrandService;
- import com.itheima.service.impl.BrandServiceImpl;
- import javax.servlet.ServletException;
- 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.List;
-
- /**
- * BrandServlet 继承父类BaseServlet
- * 父类中继承了HttpServlet 所以还是相当于BrandServlet继承了HttpServlet
- *
- * 父类BaseServlet中有service方法 (该方法当客户端访问相对应路径时自动调用该方法中)
- * 子类继承了父类 也就是说:这个BrandServlet中实际上也有个service方法 当访问该 @WebServlet("/brand/*")路径时
- * 其实调用的是BrandServlet类当中的service()方法
- *
- */
-
- @WebServlet("/brand/*")
- public class BrandServlet extends BaseServlet{
-
- // 获取业务逻辑层对象
- private BrandService brandService =new BrandServiceImpl();
-
- /**
- * 1、 查询所有商品功能
- */
- public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
-
- // 1. 调用BrandServiceImpl完成查询所有功能
- List<Brand> brands =brandService.selectAll();
-
- // 2. 将Java对象数据转换成JSON格式数据,响应给前端
- response.setContentType("text/json;charset=utf-8"); // 中文乱码问题
- String toString = JSON.toJSONString(brands);
-
- // 3. 响应给前端数据
- response.getWriter().write(toString);
- }
-
- /**
- * 2、 添加商品功能
- */
- public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
-
- // 1. 通过抓包拿到前端请求过来的数据(演示的是前端的数据为JSON格式)
- BufferedReader bufferedReader =request.getReader();
- String rl =bufferedReader.readLine(); // 拿到前端请求的JSON数据
-
- // 2. 将JSON数据转换成Java数据 (也就是说将JSON数据转换成Brand对象类型,将数据封装到对象属性中了)
- Brand brand =JSON.parseObject(rl,Brand.class);
-
- // 3. 调用BrandService接口中的添加商品方法
- brandService.add(brand);
-
- // 4. 响应给前端success的标识信号
- response.getWriter().write("success");
- }
-
- /**
- * 3、批量删除商品功能
- * 思路:把客户端请求的删除id 封装到int数组里面 然后传递给代理接口 供SQL语句使用 (SQL语句要用增强for 遍历该数组删除数据即可)
- */
-
- public void deleteByIds(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
-
- // 1、抓包 ( 前端是以JSON数据格式请求数据的,所以需要先抓包 )
- BufferedReader bufferedReader =request.getReader();
- String params =bufferedReader.readLine();
- // System.out.println(params); // 拿到前端请求的JSON数据格式: [1,2,3,4,5]
-
- // 2、把JSON数据转换成Java的数组格式
- int[] ids =JSON.parseObject(params,int[].class);
-
- // 3、调用业务逻辑层的批量删除方法 (将数组传到sql语句当中去)
- brandService.deleteByIds(ids);
-
- // 4、删除完成后,响应给前端成功的标识
- response.getWriter().write("success");
-
-
- }
-
- /**
- * 4、查询当前页码数据功能 & 查询数据库商品的总个数
- */
- public void selectByPage(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
-
-
- // 1、接收前端请求过来的 ”当前页码数“ 和 “每页展示的数据个数”
-
- // 假设:前端的访问类型:url?currentPage=1&pageSize=5 (表示:第一页,每一页有五条数据)
- // 因为前端不是以JSON格式数据请求的,所以用request域当中的方法就可以获取前端的请求(和doPost doGet方法一样)
- String _currentPage =request.getParameter("currentPage");
- String _pageSize =request.getParameter("pageSize");
-
- // 2、把String字符串类型转换成int类型
- int currentPage =Integer.parseInt(_currentPage);
- int pageSize =Integer.parseInt(_pageSize);
-
- // 3、调用查询方法 (把 ”当前页码“ 和 “每页展示的数据个数” 传递过去)
- PageBean<Brand> o =brandService.selectByPage(currentPage,pageSize);
-
- // 4. 将Java对象数据转换成JSON格式数据,响应给前端
- response.setContentType("text/json;charset=utf-8"); // 中文乱码问题
- String toString = JSON.toJSONString(o);
-
- // 5. 响应给前端数据
- response.getWriter().write(toString);
- }
-
-
- /**
- * 4、分页模糊条件查询功能 & 模糊查询出总商品数功能
- */
- public void selectByPageAndCondition(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
- // 解决POST乱码问题
- request.setCharacterEncoding("UTF-8");
-
- // 1、接收前端请求过来的 ”当前页码数“ 和 “每页展示的数据个数” 和”模糊条件查询请求的数据参数“ (模糊条件查询请求的数据参数:前端是以JSON数据请求过来的)
-
- String _currentPage =request.getParameter("currentPage");
- String _pageSize =request.getParameter("pageSize");
-
- // 2、把String字符串类型转换成int类型
- int currentPage =Integer.parseInt(_currentPage);
- int pageSize =Integer.parseInt(_pageSize);
-
- // 3、获取前端模糊条件查询的请求参数
- // 3.1、先抓包
- BufferedReader bufferedReader =request.getReader();
- // 3.2、读一行
- String params =bufferedReader.readLine(); // 拿到前端模糊查询请求参数的JSON数据格式
-
- // 3.3、将JSON数据 转换成 Java对象形式
- Brand brand =JSON.parseObject(params,Brand.class); // brand对象属性中封装好了前端模糊请求的数据
-
- // 4、 调用 分页模糊条件查询功能
- PageBean<Brand> o =brandService.selectByPageAndCondition(currentPage,pageSize,brand);
-
- String jsonString = JSON.toJSONString(o);
- // 5、 将查询出来的Java对象数据转换成JSON格式数据,响应给前端
- response.setContentType("text/json;charset=utf-8"); // 中文乱码问题
- // 6、 响应给前端数据
- response.getWriter().write(jsonString);
-
- }
- }
其他代码找我要即可~