电商后台项目 + 源码

项目总体样式如下:

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

 

 一、前期准备

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;
    }
}

二、代码如下

2.1、mapper层 (BrandMapper)

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>

 

2.2、service业务逻辑层

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;

    }
}


2.3、web层 

(使用优化后的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);

    }
}

其他代码找我要即可~

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值