springboot项目学习笔记3 分类模块
# 分类
# 后台添加分类
创建controller,CategoryController
@Controller public class CategoryController { @Autowired CategoryService categoryService; // 后台添加目录 @PostMapping("/admin/category/add") @ResponseBody public ApiRestResponse addCategory(HttpSession session, @RequestBody AddCategoryReq addCategoryReq) { } }
1
2
3
4
5
6
7
8
9
10
11
12
13单独创建类:model/request/AddCategory
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44创建selectByName mapper
public interface CategoryMapper { ... Category selectByName(String name); ... }
1
2
3
4
5<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>
1
2
3
4
5
6
创建service接口及实现类CategoryService,CategoryServiceImpl
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);
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
添加参数校验
在全局异常中处理
@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()); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# swagger 整合
引入依赖
<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>
1
2
3
4
5
6
7
8
9
10在mainApplication 中开启使用
@EnableSwagger2 public class MallApplication { public static void main(String[] args) { SpringApplication.run(MallApplication.class, args); } }
1
2
3
4
5
6
7
8添加配置文件
// 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(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22配置地址映射
@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/"); } }
1
2
3
4
5
6
7
8
9
添加注解使用
// 后台添加目录 @ApiOperation("后台添加目录") @PostMapping("/admin/category/add") @ResponseBody public ApiRestResponse addCategory(HttpSession session, @Valid @RequestBody AddCategoryReq addCategoryReq) { ... }
1
2
3
4
5
6
7启动访问 http://localhost:8088/swagger-ui.html
# 更新分类
注意点:
更新时需要对名称做校验
// 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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 封装管理员校验过滤器
创建过滤器 AdminFilter
package com.izhaong.mall.filter; public class AdminFilter implements Filter { ... }
1
2
3
4
5
6引入重写javax.servlet Filter
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(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50过滤器配置
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29在删除功能中测试
controller
package com.izhaong.mall.contraoller; ... @ApiOperation("后台删除目录") @DeleteMapping("/admin/category/delete") @ResponseBody public ApiRestResponse updateCategory(@RequestParam Integer id) { categoryService.delete(id); return ApiRestResponse.success(); }
1
2
3
4
5
6
7
8
9service
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); } }
1
2
3
4
5
6
7
8
9
10
11
12
# 后台目录列表
controller
@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); }
1
2
3
4
5
6
7service
@Override public PageInfo listForAdmin(Integer pageNum, Integer pageSize) { ... }
1
2
3
4引入分页依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.13</version> </dependency>
1
2
3
4
5使用分页
@Override public PageInfo listForAdmin(Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum, pageSize, "type,order_num"); List<Category> list = categoryMapper.selectList(); return new PageInfo(list); }
1
2
3
4
5
6添加list mapper
@Mapper public interface CategoryMapper { ... List<Category> selectList(); ... }
1
2
3
4
5
6
7
8<select id="selectList" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from imooc_mall_category </select>
1
2
3
4
5
# 前台列表
controller
@ApiOperation("前台目录列表") @GetMapping("/category/list") @ResponseBody public ApiRestResponse listCategory() { List<CategoryVO> list = categoryService.listForCustomer(); return ApiRestResponse.success(list); }
1
2
3
4
5
6
7service
@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; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19mapper
@Repository public interface CategoryMapper { ... List<Category> selectCategoriesByParentId(Integer parentId); ... }
1
2
3
4
5
6<select id="selectByParentId" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from imooc_mall_category where parent_id = #{parentId,jdbcType=INTEGER} </select>
1
2
3
4
5
6新建vo包,经过转换之后返回给前端的类
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# redis 提高缓存
sprintboot集成redis
引入依赖
<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>
1
2
3
4
5
6
7
8配置redis 连接
spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=redispassword
1
2
3main注入 打开缓存功能
@EnableCaching public class MallApplication { public static void main(String[] args) { SpringApplication.run(MallApplication.class, args); } }
1
2
3
4
5
6缓存配置
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30使用,序列化class
package com.imooc.mall.service.impl; ... @Override @Cacheable(value = "listForCustomer") public List<CategoryVO> listForCustomer() { return recursSelectList(0); } ...
1
2
3
4
5
6
7
8package com.izhaong.mall.model.vo; import java.io.Serializable; ... public class CategoryVO implements Serializable { ... } ...
1
2
3
4
5
6
7
8
上次更新: 2022/06/05, 20:31:36