Skip to content

springboot项目学习笔记3 分类模块

仲灏2022-04-09约 1 分钟

<div style="display: none;" hidden="true" aria-hidden="true" data-nosnippet>Are you an LLM? You can read better optimized documentation at /pages/2d5f32.md for this page in Markdown format</div>

分类

后台添加分类

  • 创建controller,CategoryController

    java
    @Controller
    public class CategoryController {
    
        @Autowired
        CategoryService categoryService;
    
        // 后台添加目录
        @PostMapping("/admin/category/add")
        @ResponseBody
        public ApiRestResponse addCategory(HttpSession session, @RequestBody AddCategoryReq addCategoryReq) {
    
        }
    }
    • 单独创建类:model/request/AddCategory

      java
      package com.izhaong.mall.model.request;
      
      public class AddCategoryReq {
              private String name;
      
              private Integer type;
      
              private Integer parentId;
      
              private Integer orderNum;
      
              public String getName() {
                      return name;
              }
      
              public void setName(String name) {
                      this.name = name;
              }
      
              public Integer getType() {
                      return type;
              }
      
              public void setType(Integer type) {
                      this.type = type;
              }
      
              public Integer getParentId() {
                      return parentId;
              }
      
              public void setParentId(Integer parentId) {
                      this.parentId = parentId;
              }
      
              public Integer getOrderNum() {
                      return orderNum;
              }
      
              public void setOrderNum(Integer orderNum) {
                      this.orderNum = orderNum;
              }
      }
    • 创建selectByName mapper

      java
      public interface CategoryMapper {
      		...
          Category selectByName(String name);
        	...
      }
      xml
        <select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap">
          select
          <include refid="Base_Column_List" />
          from imooc_mall_category
          where name = #{name,jdbcType=VARCHAR}
        </select>

创建service接口及实现类CategoryService,CategoryServiceImpl

java
package com.izhaong.mall.service.impl;


import com.izhaong.mall.exception.MallException;
import com.izhaong.mall.exception.MallExceptionEnum;
import com.izhaong.mall.model.dao.CategoryMapper;
import com.izhaong.mall.model.pojo.Category;
import com.izhaong.mall.model.request.AddCategoryReq;
import com.izhaong.mall.service.CategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


@Service
public class CategoryServiceImpl implements CategoryService {

    CategoryMapper categoryMapper;

    @Override
    public void add(AddCategoryReq addCategoryReq) {
        // 判断是否重名
        Category category = new Category();
        BeanUtils.copyProperties(addCategoryReq, category);

        Category oldCate = categoryMapper.selectByName(addCategoryReq.getName());

//        是抛出异常 不添加
        if (oldCate != null) {
            throw new MallException(MallExceptionEnum.NAME_EXISTED);
        } else {
            //        不是重名就插入数据
            int count = categoryMapper.insertSelective(category);
            if (count == 0) {
                throw new MallException(MallExceptionEnum.INSERT_FAILED);
            }
        }
    }
}
  • 添加参数校验

    image-20220410195955166

    • 在全局异常中处理

      java
      		@ExceptionHandler(MethodArgumentNotValidException.class)
          @ResponseBody
          public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
              logger.error("MethodArgumentNotValidException:", e);
              return handleBindingResult(e.getBindingResult());
          }
      
          private ApiRestResponse handleBindingResult(BindingResult result) {
              //把异常处理为对外暴露的提示
              List<String> list = new ArrayList<>();
              if (result.hasErrors()) {
                  List<ObjectError> allErrors = result.getAllErrors();
                  // itli
                  for (ObjectError objectError : allErrors) {
                      String message = objectError.getDefaultMessage();
                      list.add(message);
                  }
              }
              if (list.size() == 0) {
                  return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR);
              }
              return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
          }

swagger 整合

  • 引入依赖

    xml
    				<dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.9.2</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.9.2</version>
            </dependency>
  • 在mainApplication 中开启使用

    java
    @EnableSwagger2
    public class MallApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MallApplication.class, args);
        }
    
    }
  • 添加配置文件

    java
    // com.izhaong.mall/config/SpringFoxConfig
    
    public class SpringFoxConfig {
        //访问http://localhost:8083/swagger-ui.html可以看到API文档
        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(PathSelectors.any())
                    .build();
        }
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("生鲜")
                    .description("")
                    .termsOfServiceUrl("")
                    .build();
        }
    }
    • 配置地址映射

      java
      @Configuration
      public class MallWebMvcConfig implements WebMvcConfigurer {
      
          @Override
          public void addResourceHandlers(ResourceHandlerRegistry registry) {
              registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
              registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
          }
      }
  • 添加注解使用

    java
    // 后台添加目录
        @ApiOperation("后台添加目录")
        @PostMapping("/admin/category/add")
        @ResponseBody
        public ApiRestResponse addCategory(HttpSession session, @Valid @RequestBody AddCategoryReq addCategoryReq) {
          ...
        }
  • 启动访问 http://localhost:8088/swagger-ui.html

更新分类

注意点:

更新时需要对名称做校验

java
// service
		@Override
    public void update(Category updateCategory) {
        if (updateCategory.getName() != null) {
            Category categoryOld = categoryMapper.selectByName(updateCategory.getName());
            if (categoryOld != null && categoryOld.getId().equals(updateCategory.getId())) {
                throw new MallException(MallExceptionEnum.NAME_EXISTED);
            }
        }
        int count = categoryMapper.updateByPrimaryKeySelective(updateCategory);
        if (count == 0) {
            throw new MallException(MallExceptionEnum.UPDATE_FAILD);
        }
    }

封装管理员校验过滤器

  • 创建过滤器 AdminFilter

    java
    package com.izhaong.mall.filter;
    
    public class AdminFilter implements Filter {
    	...
    }
  • 引入重写javax.servlet Filter

    java
    public class AdminFilter implements Filter {
    
        @Autowired
        UserService userService;
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
    		@Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpSession session = request.getSession();
            User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
            if (currentUser == null) {
                PrintWriter out = new HttpServletResponseWrapper(
                        (HttpServletResponse) servletResponse).getWriter();
                out.write("{\n"
                        + "    \"status\": 10007,\n"
                        + "    \"msg\": \"NEED_LOGIN\",\n"
                        + "    \"data\": null\n"
                        + "}");
                out.flush();
                out.close();
                return;
            }
            //校验是否是管理员
            boolean adminRole = userService.checkAdminRole(currentUser);
            if (adminRole) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                PrintWriter out = new HttpServletResponseWrapper(
                        (HttpServletResponse) servletResponse).getWriter();
                out.write("{\n"
                        + "    \"status\": 10009,\n"
                        + "    \"msg\": \"NEED_ADMIN\",\n"
                        + "    \"data\": null\n"
                        + "}");
                out.flush();
                out.close();
            }
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
  • 过滤器配置

    java
    package com.imooc.mall.config;
    
    import com.imooc.mall.filter.AdminFilter;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * 描述:     Admin过滤器的配置
     */
    @Configuration
    public class AdminFilterConfig {
    
        @Bean
        public AdminFilter adminFilter() {
            return new AdminFilter();
        }
    
        @Bean(name = "adminFilterConf")
        public FilterRegistrationBean adminFilterConfig() {
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
            filterRegistrationBean.setFilter(adminFilter());
            filterRegistrationBean.addUrlPatterns("/admin/category/*");
            filterRegistrationBean.addUrlPatterns("/admin/product/*");
            filterRegistrationBean.addUrlPatterns("/admin/order/*");
            filterRegistrationBean.setName("adminFilterConf");
            return filterRegistrationBean;
        }
    }
  • 在删除功能中测试

    • controller

      java
      package com.izhaong.mall.contraoller;
      ...
      		@ApiOperation("后台删除目录")
          @DeleteMapping("/admin/category/delete")
          @ResponseBody
          public ApiRestResponse updateCategory(@RequestParam Integer id) {
              categoryService.delete(id);
              return ApiRestResponse.success();
          }
    • service

      java
      package com.izhaong.mall.service.impl;
      ...
      		@Override
          public void delete(Integer id) {
              if (categoryMapper.selectByPrimaryKey(id) == null) {
                  throw new MallException(MallExceptionEnum.DELETE_FAILED);
              }
              int i = categoryMapper.deleteByPrimaryKey(id);
              if (i == 0) {
                  throw new MallException(MallExceptionEnum.DELETE_FAILED);
              }
          }

后台目录列表

  • controller

    java
        @ApiOperation("后台目录列表")
        @GetMapping("/admin/category/list")
        @ResponseBody
        public ApiRestResponse listCategory(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
            PageInfo pageinfo = categoryService.listForAdmin(pageNum, pageSize);
            return ApiRestResponse.success(pageinfo);
        }
  • service

    java
        @Override
        public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
    			...
        }
    • 引入分页依赖

      xml
              <dependency>
                  <groupId>com.github.pagehelper</groupId>
                  <artifactId>pagehelper-spring-boot-starter</artifactId>
                  <version>1.2.13</version>
              </dependency>
    • 使用分页

      java
          @Override
          public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
              PageHelper.startPage(pageNum, pageSize, "type,order_num");
              List<Category> list = categoryMapper.selectList();
              return new PageInfo(list);
          }
    • 添加list mapper

      java
      @Mapper
      public interface CategoryMapper {
        ...
        List<Category> selectList();
        ...
      }
      xml
        <select id="selectList" resultMap="BaseResultMap">
          select
          <include refid="Base_Column_List" />
          from imooc_mall_category
        </select>

前台列表

  • controller

    java
        @ApiOperation("前台目录列表")
        @GetMapping("/category/list")
        @ResponseBody
        public ApiRestResponse listCategory() {
            List<CategoryVO> list = categoryService.listForCustomer();
            return ApiRestResponse.success(list);
        }
  • service

    java
        @Override
        public List<CategoryVO> listForCustomer() {
            return recursSelectList(0);
        }
    
        public List<CategoryVO> recursSelectList(Integer parentId) {
            List<CategoryVO> categoryVOList = new ArrayList<>();
            List<Category> list = categoryMapper.selectByParentId(parentId);
            if (!CollectionUtils.isEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    Category category = list.get(i);
                    CategoryVO categoryVO = new CategoryVO();
                    BeanUtils.copyProperties(category, categoryVO);
                    categoryVOList.add(categoryVO);
                    categoryVO.setChildCategory(recursSelectList(categoryVO.getId()));
                }
            }
            return categoryVOList;
        }
  • mapper

    java
    @Repository
    public interface CategoryMapper {
      ...
    	List<Category> selectCategoriesByParentId(Integer parentId);
      ...
    }
    xml
      <select id="selectByParentId" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from imooc_mall_category
        where parent_id = #{parentId,jdbcType=INTEGER}
      </select>
  • 新建vo包,经过转换之后返回给前端的类

    java
    package com.izhaong.mall.model.vo;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    public class CategoryVO {
    
        private Integer id;
    
        private String name;
    
        private Integer type;
    
        private Integer parentId;
    
        private Integer orderNum;
    
        private List<CategoryVO> childCategory = new ArrayList<>();
    
        private Date createTime;
    
        private Date updateTime;
    
        public List<CategoryVO> getChildCategory() {
            return childCategory;
        }
    
        public void setChildCategory(List<CategoryVO> childCategory) {
            this.childCategory = childCategory;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        public Integer getType() {
            return type;
        }
    
        public void setType(Integer type) {
            this.type = type;
        }
    
        public Integer getParentId() {
            return parentId;
        }
    
        public void setParentId(Integer parentId) {
            this.parentId = parentId;
        }
    
        public Integer getOrderNum() {
            return orderNum;
        }
    
        public void setOrderNum(Integer orderNum) {
            this.orderNum = orderNum;
        }
    
        public Date getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    
        public Date getUpdateTime() {
            return updateTime;
        }
    
        public void setUpdateTime(Date updateTime) {
            this.updateTime = updateTime;
        }
    }

redis 提高缓存

sprintboot集成redis

  • 引入依赖

    xml
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
  • 配置redis 连接

    properties
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    spring.redis.password=redispassword
  • main注入 打开缓存功能

    java
    @EnableCaching
    public class MallApplication {
        public static void main(String[] args) {
            SpringApplication.run(MallApplication.class, args);
        }
    }
  • 缓存配置

    java
    package com.izhaong.mall.config;
    
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.cache.RedisCacheWriter;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    
    import java.time.Duration;
    
    /**
     * 描述:     缓存的配置类
     */
    @Configuration
    @EnableCaching
    public class CachingConfig {
    
        @Bean
        public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
            
            RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
            RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
            cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(30));
    
            RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
            return redisCacheManager;
        }
    }
  • 使用,序列化class

    java
    package com.imooc.mall.service.impl;
    ...
    		@Override
        @Cacheable(value = "listForCustomer")
        public List<CategoryVO> listForCustomer() {
            return recursSelectList(0);
        }
    ...
    java
    package com.izhaong.mall.model.vo;
    
    import java.io.Serializable;
    ...
    public class CategoryVO implements Serializable {
      ...
    }
    ...