pull/3/head
litingting 11 months ago
parent 43e821a4b4
commit a645aca4a3

@ -4,13 +4,28 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* SnailmallCategoryServiceApplicationSpring Boot
* mainSpring BootWebTomcat
* 使Spring BootSpring Cloud
*/
@SpringBootApplication
// 这是一个组合注解,相当于同时使用了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。
// @Configuration表示该类是一个配置类可用于定义一些Spring的Bean或者配置相关的属性等
// @EnableAutoConfiguration用于启用Spring Boot的自动配置功能会根据项目依赖自动配置各种组件比如数据源、Web相关配置等
// @ComponentScan用于指定Spring扫描组件如带有@Component、@Service、@Controller等注解的类的基础包路径默认会扫描当前类所在的包及其子包下的组件。
@EnableDiscoveryClient
// 该注解用于开启服务发现客户端功能使得应用可以注册到服务注册中心比如Eureka、Consul等并且可以从注册中心发现其他服务方便实现微服务之间的调用和协作。
public class SnailmallCategoryServiceApplication {
/**
* mainJavaSpringApplicationrunSpring Boot
* ClassSnailmallCategoryServiceApplication.classargs
* Spring Boot使
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(SnailmallCategoryServiceApplication.class, args);
}
}
}

@ -1,6 +1,5 @@
package com.njupt.swg.common.exception;
import com.njupt.swg.common.constants.Constants;
import com.njupt.swg.common.resp.ServerResponse;
import lombok.extern.slf4j.Slf4j;
@ -9,25 +8,41 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* ExceptionHandlerAdvice
* @Author swg.
* @Date 2019/1/1 13:21
* @CONTACT 317758022@qq.com
* @DESC
*/
@ControllerAdvice
// 表示该类中处理异常的方法返回的结果会直接作为响应体返回给客户端,而不是进行视图解析等操作。
@ResponseBody
// 使用Slf4j注解方便进行日志记录简化日志输出的代码编写。
@Slf4j
public class ExceptionHandlerAdvice {
/**
* Exception
* 便
* 使Constants
* @param e Exception
* @return ServerResponse
*/
@ExceptionHandler(Exception.class)
public ServerResponse handleException(Exception e){
log.error(e.getMessage(),e);
return ServerResponse.createByErrorCodeMessage(Constants.RESP_STATUS_INTERNAL_ERROR,"系统异常,请稍后再试");
public ServerResponse handleException(Exception e) {
log.error(e.getMessage(), e);
return ServerResponse.createByErrorCodeMessage(Constants.RESP_STATUS_INTERNAL_ERROR, "系统异常,请稍后再试");
}
/**
* SnailmallException
*
*
* @param e SnailmallException
* @return ServerResponse
*/
@ExceptionHandler(SnailmallException.class)
public ServerResponse handleException(SnailmallException e){
log.error(e.getMessage(),e);
return ServerResponse.createByErrorCodeMessage(e.getExceptionStatus(),e.getMessage());
public ServerResponse handleException(SnailmallException e) {
log.error(e.getMessage(), e);
return ServerResponse.createByErrorCodeMessage(e.getExceptionStatus(), e.getMessage());
}
}
}

@ -4,22 +4,38 @@ import com.njupt.swg.common.resp.ResponseEnum;
import lombok.Getter;
/**
* SnailmallExceptionRuntimeExceptionSnailmall
* RuntimeException便
* @Author swg.
* @Date 2019/1/1 13:18
* @CONTACT 317758022@qq.com
* @DESC
*/
@Getter
public class SnailmallException extends RuntimeException{
// 使用lombok的@Getter注解自动生成获取exceptionStatus属性值的get方法方便外部获取该异常状态码。
public class SnailmallException extends RuntimeException {
// 定义一个表示异常状态码的属性初始值设置为从ResponseEnum.ERROR中获取的状态码通常用于表示默认的错误状态码情况。
private int exceptionStatus = ResponseEnum.ERROR.getCode();
public SnailmallException(String msg){
/**
* msgSnailmallException
* RuntimeExceptionmsg使ResponseEnum.ERROR.getCode()
* 使
* @param msg
*/
public SnailmallException(String msg) {
super(msg);
}
public SnailmallException(int code,String msg){
/**
* codemsg
* RuntimeExceptionmsgcodeexceptionStatus
*
* @param code
* @param msg
*/
public SnailmallException(int code, String msg) {
super(msg);
exceptionStatus = code;
}
}
}

@ -3,23 +3,36 @@ package com.njupt.swg.common.resp;
import lombok.Getter;
/**
* ResponseEnum
* 便使
* @Author swg.
* @Date 2018/12/31 20:15
* @CONTACT 317758022@qq.com
* @DESC
*/
@Getter
// 使用lombok的@Getter注解自动为枚举中的code和desc属性生成对应的获取方法方便外部获取这些属性值。
public enum ResponseEnum {
SUCCESS(0,"SUCCESS"),
ERROR(1,"ERROR"),
ILLEGAL_ARGUMENTS(2,"ILLEGAL_ARGUMENTS"),
NEED_LOGIN(10,"NEED_LOGIN");
// 表示成功的返回状态状态码为0对应的描述信息为"SUCCESS",用于标识业务操作成功完成的情况。
SUCCESS(0, "SUCCESS"),
// 表示出现错误的返回状态状态码为1对应的描述信息为"ERROR",可用于一般性的错误情况,较为笼统地表示操作未成功。
ERROR(1, "ERROR"),
// 表示参数非法的返回状态状态码为2对应的描述信息为"ILLEGAL_ARGUMENTS",用于客户端传入的参数不符合要求等情况。
ILLEGAL_ARGUMENTS(2, "ILLEGAL_ARGUMENTS"),
// 表示需要登录的返回状态状态码为10对应的描述信息为"NEED_LOGIN",用于提示客户端当前操作需要先进行登录认证的场景。
NEED_LOGIN(10, "NEED_LOGIN");
private int code;
private String desc;
ResponseEnum(int code,String desc){
/**
*
* SUCCESSERRORcodedesc
* @param code
* @param desc 便
*/
ResponseEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
}
}

@ -4,75 +4,168 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* ServerResponse
* <T>便
* @Author swg.
* @Date 2018/12/31 20:11
* @CONTACT 317758022@qq.com
* @DESC
*/
@Getter
// 使用lombok的@Getter注解自动生成获取status、msg、data属性值的方法方便外部获取这些成员变量的值。
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
// 通过该注解配置Jackson序列化时的行为这里表示只序列化非空的属性避免返回包含大量空值的JSON数据给客户端节省网络传输和客户端解析成本。
public class ServerResponse<T> implements Serializable {
// 表示响应的状态码,用于客户端判断请求的处理结果状态,通常会对应一些预定义的状态码值,比如成功、失败等情况。
private int status;
// 表示响应的提示消息,用于向客户端传达一些关于请求处理结果的文字描述信息,便于客户端展示给用户知晓具体情况。
private String msg;
// 泛型成员变量,用于承载具体的业务数据,其类型根据实际业务场景而定,可以是对象、集合等各种数据结构类型。
private T data;
public ServerResponse(){}
public ServerResponse() {
}
public ServerResponse(int status){
/**
* ServerResponse
*
* @param status
*/
public ServerResponse(int status) {
this.status = status;
}
public ServerResponse(int status,String msg){
/**
* ServerResponse
*
* @param status
* @param msg
*/
public ServerResponse(int status, String msg) {
this.status = status;
this.msg = msg;
}
public ServerResponse(int status,T data){
/**
* ServerResponse
*
* @param status
* @param data
*/
public ServerResponse(int status, T data) {
this.status = status;
this.data = data;
}
public ServerResponse(int status,String msg,T data){
/**
* ServerResponse
*
* @param status
* @param msg
* @param data
*/
public ServerResponse(int status, String msg, T data) {
this.status = status;
this.msg = msg;
this.data = data;
}
/**
* JSONJSON
* ResponseEnum.SUCCESS
* 便
* @return truefalse
*/
@JsonIgnore
public boolean isSuccess(){
public boolean isSuccess() {
return this.status == ResponseEnum.SUCCESS.getCode();
}
/**
*
* 便ServerResponse
*/
public static <T>ServerResponse<T> createBySuccess(){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),ResponseEnum.SUCCESS.getDesc());
}
public static <T>ServerResponse<T> createBySuccessMessage(String message){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),message);
}
public static <T>ServerResponse<T> createBySuccess(T data){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),data);
}
public static <T>ServerResponse<T> createBySuccess(String message,T data){
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(),message,data);
/**
* ServerResponse使ResponseEnum.SUCCESS
*
* @param <T> ServerResponse
* @return ServerResponse
*/
public static <T> ServerResponse<T> createBySuccess() {
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getDesc());
}
/**
*
* ServerResponse使
*
* @param <T> ServerResponse
* @param message
* @return ServerResponse
*/
public static <T>ServerResponse<T> createByError(){
return new ServerResponse<>(ResponseEnum.ERROR.getCode(),ResponseEnum.ERROR.getDesc());
public static <T> ServerResponse<T> createBySuccessMessage(String message) {
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(), message);
}
public static <T>ServerResponse<T> createByErrorMessage(String msg){
return new ServerResponse<>(ResponseEnum.ERROR.getCode(),msg);
/**
* ServerResponse使ResponseEnum.SUCCESS
*
* @param <T> ServerResponse
* @param data
* @return ServerResponse
*/
public static <T> ServerResponse<T> createBySuccess(T data) {
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(), data);
}
public static <T>ServerResponse<T> createByErrorCodeMessage(int code,String msg){
return new ServerResponse<>(code,msg);
/**
* ServerResponse使
*
* @param <T> ServerResponse
* @param message
* @param data
* @return ServerResponse
*/
public static <T> ServerResponse<T> createBySuccess(String message, T data) {
return new ServerResponse<>(ResponseEnum.SUCCESS.getCode(), message, data);
}
/**
* 便ServerResponse
*/
/**
* ServerResponse使ResponseEnum.ERROR
*
* @param <T> ServerResponse
* @return ServerResponse
*/
public static <T> ServerResponse<T> createByError() {
return new ServerResponse<>(ResponseEnum.ERROR.getCode(), ResponseEnum.ERROR.getDesc());
}
}
/**
* ServerResponse使
*
* @param <T> ServerResponse
* @param msg
* @return ServerResponse
*/
public static <T> ServerResponse<T> createByErrorMessage(String msg) {
return new ServerResponse<>(ResponseEnum.ERROR.getCode(), msg);
}
/**
* ServerResponse
*
* @param <T> ServerResponse
* @param code
* @param msg
* @return ServerResponse
*/
public static <T> ServerResponse<T> createByErrorCodeMessage(int code, String msg) {
return new ServerResponse<>(code, msg);
}
}

@ -7,8 +7,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* CategoryControllerSpringRestController
* 使访TODO
* @Author swg.
* @Date 2019/1/2 12:57
* @CONTACT 317758022@qq.com
@ -18,55 +19,69 @@ import org.springframework.web.bind.annotation.RestController;
//TODO 这里首先实现业务 关于这里重复的鉴权,后面将会移植到网关中统一去做
//TODO 先开放GET请求
@RestController
// 表明该类是一个Spring RESTful风格的控制器其内部的方法返回值会直接序列化为JSON格式并返回给客户端无需额外配置视图解析等。
@RequestMapping("/manage/category/")
// 定义该控制器处理请求的基础路径,所有该控制器下的接口请求路径都以此为前缀。
public class CategoryController {
@Autowired
// 使用Spring的依赖注入功能自动注入ICategoryService的实现类实例以便在控制器方法中调用对应的业务逻辑方法。
private ICategoryService categoryService;
/**
* ()
* ()
* categoryIdInteger0
* categoryServicegetCategoryServerResponse
*
*/
@RequestMapping("get_category.do")
public ServerResponse getCategory(@RequestParam(value = "categoryId",defaultValue = "0") Integer categoryId){
public ServerResponse getCategory(@RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId) {
ServerResponse response = categoryService.getCategory(categoryId);
return response;
}
/**
*
*
* categoryNameStringparentIdint0
* IDcategoryServiceaddCategory
* ServerResponse
*/
@RequestMapping("add_category.do")
public ServerResponse addCategory(String categoryName, @RequestParam(value = "parentId",defaultValue = "0")int parentId){
ServerResponse response = categoryService.addCategory(categoryName,parentId);
public ServerResponse addCategory(String categoryName, @RequestParam(value = "parentId", defaultValue = "0") int parentId) {
ServerResponse response = categoryService.addCategory(categoryName, parentId);
return response;
}
/**
*
*
* categoryNameStringcategoryIdIntegerID
* categoryServiceupdateCategoryNameServerResponse<String>
* <String>
*/
@RequestMapping("set_category_name.do")
public ServerResponse<String> set_category_name(String categoryName,Integer categoryId){
return categoryService.updateCategoryName(categoryName,categoryId);
public ServerResponse<String> set_category_name(String categoryName, Integer categoryId) {
return categoryService.updateCategoryName(categoryName, categoryId);
}
/**
*
*
* categoryIdInteger0
* categoryServiceselectCategoryAndDeepChildrenByIdServerResponse
* 便
*/
@RequestMapping("get_deep_category.do")
public ServerResponse get_deep_category(@RequestParam(value = "categoryId",defaultValue = "0") Integer categoryId){
public ServerResponse get_deep_category(@RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId) {
return categoryService.selectCategoryAndDeepChildrenById(categoryId);
}
/**
*
*
* categoryIdIntegerID
* categoryServicegetCategoryDetailServerResponse
* 便使
*/
@RequestMapping("get_category_detail.do")
public ServerResponse get_category_detail(Integer categoryId){
public ServerResponse get_category_detail(Integer categoryId) {
return categoryService.getCategoryDetail(categoryId);
}
}
}

@ -1,24 +1,79 @@
package com.njupt.swg.dao;
import com.njupt.swg.entity.Category;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* CategoryMapperMyBatisMapper
* CategoryMyBatisXMLSQL
*
* @MapperMyBatisMapperSpringMyBatis
* 便
*/
@Mapper
public interface CategoryMapper {
/**
* idIntegerid
* 11
* MyBatis<delete>SQL
* @param id
* @return
*/
int deleteByPrimaryKey(Integer id);
/**
* CategoryCategoryrecord
* 11
* MyBatisSQL<insert>
* @param record Category
* @return
*/
int insert(Category record);
/**
* CategoryCategoryrecord
* insertrecordnullnull
* MyBatisSQL<insertSelective>
* @param record Categorynull
* @return
*/
int insertSelective(Category record);
/**
* idCategoryIntegerid
* Categorynull
* MyBatisSQL<select><resultMap>Category
* @param id
* @return Categorynull
*/
Category selectByPrimaryKey(Integer id);
/**
* CategoryCategoryrecord
* recordnull
* MyBatisSQL<updateByPrimaryKeySelective>
* @param record Categorynull
* @return
*/
int updateByPrimaryKeySelective(Category record);
/**
* CategoryCategoryrecord
* record
* MyBatisSQL<updateByPrimaryKey>
* @param record Category
* @return
*/
int updateByPrimaryKey(Category record);
/**
* categoryIdIntegercategoryId
* List<Category>Category
* MyBatisSQL<selectCategoryChildrenByParentId>
* Category
* @param categoryId
* @return Category
*/
List<Category> selectCategoryChildrenByParentId(Integer categoryId);
}

@ -1,6 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?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标签定义了MyBatis的映射文件namespace属性指定了对应的Mapper接口的全限定名
用于将XML中的SQL语句与Java代码中的Mapper接口方法关联起来 -->
<mapper namespace="com.njupt.swg.dao.CategoryMapper" >
<!-- 定义了一个名为BaseResultMap的结果映射用于将从数据库查询结果映射到Java中的com.njupt.swg.entity.Category实体类对象。
通过<constructor>标签内的<idArg><arg>元素来指定构造函数参数与数据库表字段的对应关系,
包括字段名、JDBC类型以及对应的Java类型等信息 -->
<resultMap id="BaseResultMap" type="com.njupt.swg.entity.Category" >
<constructor >
<idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
@ -12,111 +18,136 @@
<arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
</constructor>
</resultMap>
<!-- 定义了一个名为Base_Column_List的SQL片段包含了要从数据库表中查询的列名列表
后续其他SQL语句可以通过<include>标签引用这个片段,方便复用代码 -->
<sql id="Base_Column_List" >
id, parent_id, name, status, sort_order, create_time, update_time
</sql>
<!-- 定义了一个名为selectByPrimaryKey的查询语句用于根据主键id查询记录。
resultMap属性指定了使用前面定义的BaseResultMap来映射查询结果parameterType指定了传入参数的类型为Integer对应主键的类型
SQL语句通过<include>标签引用了Base_Column_List片段来获取指定列的数据并根据传入的主键值进行筛选查询 -->
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
select
<include refid="Base_Column_List" />
from mmall_category
where id = #{id,jdbcType=INTEGER}
</select>
<!-- 定义了一个名为deleteByPrimaryKey的删除语句用于根据主键id删除记录parameterType指定了传入参数的类型为Integer对应主键的类型
SQL语句指定了从mmall_category表中删除满足id条件的记录 -->
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from mmall_category
where id = #{id,jdbcType=INTEGER}
</delete>
<!-- 定义了一个名为insert的插入语句用于向mmall_category表中插入一条完整的记录parameterType指定了传入参数的类型为com.njupt.swg.entity.Category实体类
SQL语句明确列出了要插入的列名以及对应的通过#{属性名,jdbcType=类型}方式获取实体类属性值来插入数据对于create_time和update_time使用了数据库函数now()来获取当前时间插入 -->
<insert id="insert" parameterType="com.njupt.swg.entity.Category" >
insert into mmall_category (id, parent_id, name,
status, sort_order, create_time,
update_time)
values (#{id,jdbcType=INTEGER}, #{parentId,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{status,jdbcType=BIT}, #{sortOrder,jdbcType=INTEGER}, now(),
now())
insert into mmall_category (id, parent_id, name,
status, sort_order, create_time,
update_time)
values (#{id,jdbcType=INTEGER}, #{parentId,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{status,jdbcType=BIT}, #{sortOrder,jdbcType=INTEGER}, now(),
now())
</insert>
<!-- 定义了一个名为insertSelective的插入语句相比于insert语句更加灵活它会根据传入的com.njupt.swg.entity.Category实体类对象中属性是否为null来决定是否插入对应的列数据。
通过<trim>标签结合<if>条件判断来动态构建插入语句的列名和对应的值部分避免插入不必要的null值到数据库表中 -->
<insert id="insertSelective" parameterType="com.njupt.swg.entity.Category" >
insert into mmall_category
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
<if test="id!= null" >
id,
</if>
<if test="parentId != null" >
<if test="parentId!= null" >
parent_id,
</if>
<if test="name != null" >
<if test="name!= null" >
name,
</if>
<if test="status != null" >
<if test="status!= null" >
status,
</if>
<if test="sortOrder != null" >
<if test="sortOrder!= null" >
sort_order,
</if>
<if test="createTime != null" >
<if test="createTime!= null" >
create_time,
</if>
<if test="updateTime != null" >
<if test="updateTime!= null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
<if test="id!= null" >
#{id,jdbcType=INTEGER},
</if>
<if test="parentId != null" >
<if test="parentId!= null" >
#{parentId,jdbcType=INTEGER},
</if>
<if test="name != null" >
<if test="name!= null" >
#{name,jdbcType=VARCHAR},
</if>
<if test="status != null" >
<if test="status!= null" >
#{status,jdbcType=BIT},
</if>
<if test="sortOrder != null" >
<if test="sortOrder!= null" >
#{sortOrder,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
<if test="createTime!= null" >
now(),
</if>
<if test="updateTime != null" >
<if test="updateTime!= null" >
now(),
</if>
</trim>
</insert>
<!-- 定义了一个名为updateByPrimaryKeySelective的更新语句根据传入的com.njupt.swg.entity.Category实体类对象中属性是否为null来决定是否更新对应的列数据。
通过<set>标签结合<if>条件判断来动态构建更新语句的列赋值部分只更新有值变化的列避免不必要的全列更新最后根据主键id来定位要更新的记录 -->
<update id="updateByPrimaryKeySelective" parameterType="com.njupt.swg.entity.Category" >
update mmall_category
<set >
<if test="parentId != null" >
<if test="parentId!= null" >
parent_id = #{parentId,jdbcType=INTEGER},
</if>
<if test="name != null" >
<if test="name!= null" >
name = #{name,jdbcType=VARCHAR},
</if>
<if test="status != null" >
<if test="status!= null" >
status = #{status,jdbcType=BIT},
</if>
<if test="sortOrder != null" >
<if test="sortOrder!= null" >
sort_order = #{sortOrder,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
<if test="createTime!= null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
<if test="updateTime!= null" >
update_time = now(),
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<!-- 定义了一个名为updateByPrimaryKey的更新语句用于根据传入的com.njupt.swg.entity.Category实体类对象来更新mmall_category表中对应主键id的记录的所有列数据
直接列出了要更新的列名和对应从实体类获取的属性值最后根据主键id来定位要更新的记录 -->
<update id="updateByPrimaryKey" parameterType="com.njupt.swg.entity.Category" >
update mmall_category
set parent_id = #{parentId,jdbcType=INTEGER},
name = #{name,jdbcType=VARCHAR},
status = #{status,jdbcType=BIT},
sort_order = #{sortOrder,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = now()
name = #{name,jdbcType=VARCHAR},
status = #{status,jdbcType=BIT},
sort_order = #{sortOrder,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = now()
where id = #{id,jdbcType=INTEGER}
</update>
<!-- 定义了一个名为selectCategoryChildrenByParentId的查询语句用于根据父节点的categoryId查询其对应的子节点记录。
parameterType指定了传入参数的类型为int对应categoryId的类型resultMap指定了使用前面定义的BaseResultMap来映射查询结果
SQL语句通过<include>标签引用了Base_Column_List片段来获取指定列的数据并根据传入的父节点categoryId值进行筛选查询 -->
<select id="selectCategoryChildrenByParentId" parameterType="int" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List"/> from mmall_category where parent_id = #{categoryId}
</select>

@ -3,24 +3,32 @@ package com.njupt.swg.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* Category
* 使LombokGetter/Setter
* Java
*/
@Data
// 使用Lombok的@Data注解会自动为类中的所有非静态、非final属性生成Getter、Setter方法同时还会生成toString、equals、hashCode等方法方便对象的操作和比较等。
@AllArgsConstructor
// 使用Lombok的@AllArgsConstructor注解会自动生成一个包含所有属性的构造函数方便在创建对象时一次性传入所有属性值进行初始化。
@NoArgsConstructor
// 使用Lombok的@NoArgsConstructor注解会自动生成一个无参构造函数在一些框架如MyBatis在实例化对象等场景可能需要使用无参构造函数的情况下很有用。
public class Category {
// 对应数据库表中品类记录的唯一标识字段用于区分不同的品类类型为Integer。
private Integer id;
// 表示品类的父节点ID用于构建品类之间的层级关系类型为Integer通过该字段可以知道某个品类所属的上级品类若为顶级品类则可能为特定的默认值如0等表示无父节点
private Integer parentId;
// 品类的名称类型为String用于直观地标识和区分不同的品类例如“电子产品”“服装”等具体的品类名称。
private String name;
// 表示品类的状态类型为Boolean可用于标记品类是否有效、是否启用等业务状态例如true表示该品类正常可用false表示已停用等情况。
private Boolean status;
// 用于指定品类在展示、排序等场景下的顺序类型为Integer数值越小可能表示在排序中越靠前等方便对多个品类进行顺序排列。
private Integer sortOrder;
// 记录品类创建的时间类型为Date用于记录该品类首次被添加到系统中的时间点方便后续进行时间相关的查询、统计等操作。
private Date createTime;
// 记录品类最后一次更新的时间类型为Date每次对品类的相关信息如名称、状态等进行修改操作后会更新该时间字段便于追踪品类信息的变更情况。
private Date updateTime;
}

@ -4,40 +4,45 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
/**
* UserJava
* 使LombokGetter/SettertoString
* Serializable便
* @Author swg.
* @Date 2018/12/31 21:01
* @CONTACT 317758022@qq.com
* @DESC
*/
@Data
// 使用Lombok的@Data注解会自动为类中的所有非静态、非final属性生成Getter、Setter方法同时还会生成toString、equals、hashCode等方法方便对用户对象进行操作、比较以及以字符串形式展示等操作。
@NoArgsConstructor
// 使用Lombok的@NoArgsConstructor注解会自动生成一个无参构造函数在一些框架初始化对象或者通过反射创建对象等场景中可能会需要使用无参构造函数。
@AllArgsConstructor
// 使用Lombok的@AllArgsConstructor注解会自动生成一个包含所有属性的构造函数方便在创建用户对象时一次性传入所有属性值来进行初始化操作。
@ToString
// 使用Lombok的@ToString注解会自动重写toString方法使得在调用该方法时能够以一种比较友好的格式输出用户对象的各个属性值便于调试和查看对象内容。
public class User implements Serializable {
// 用户在系统中的唯一标识通常由数据库自动生成或者按照一定规则分配类型为Integer用于区分不同的用户个体。
private Integer id;
// 用户登录系统时使用的用户名类型为String要求具有唯一性一般情况下方便用户进行身份识别和登录操作。
private String username;
// 用户登录系统时使用的密码类型为String通常会经过加密处理后存储以保障用户账户的安全性。
private String password;
// 用户的电子邮箱地址类型为String可用于接收系统发送的通知、验证邮件等也是一种常用的用户联系方式和身份验证方式之一。
private String email;
// 用户的手机号码类型为String同样可用于接收短信通知、作为登录验证的一种方式等是重要的用户联系方式。
private String phone;
// 用户设置的密保问题类型为String用于在用户忘记密码等情况下进行身份验证辅助找回密码等操作。
private String question;
// 用户针对密保问题设置的答案类型为String必须与密保问题相对应用于验证用户身份的合法性。
private String answer;
//角色0-管理员,1-普通用户
// 用于标识用户在系统中的角色类型为Integer0表示管理员角色拥有较高的系统操作权限1表示普通用户角色权限相对受限只能进行一些常规的业务操作。
private Integer role;
// 记录用户账号创建的时间类型为Date便于后续查询用户注册时间、统计不同时间段的注册人数等与时间相关的业务操作。
private Date createTime;
// 记录用户账号信息最后一次更新的时间类型为Date比如用户修改密码、更新联系方式等操作后会更新该时间字段方便追踪用户信息的变更情况。
private Date updateTime;
}

@ -16,115 +16,165 @@ import java.util.List;
import java.util.Set;
/**
* CategoryServiceImplICategoryService
* CategoryMapperSnailmallException
* 使ServerResponse
* @Author swg.
* @Date 2019/1/2 12:54
* @CONTACT 317758022@qq.com
* @DESC
*/
@Service
// 该注解表明这个类是Spring框架中的一个服务层组件Spring会自动扫描并管理这个类使其可以被注入到其他需要使用的地方。
@Slf4j
public class CategoryServiceImpl implements ICategoryService{
// 使用lombok的@Slf4j注解自动生成一个名为log的日志记录对象方便在类中记录日志信息便于后续调试和查看业务执行情况。
public class CategoryServiceImpl implements ICategoryService {
@Autowired
// 使用Spring的依赖注入功能自动注入CategoryMapper的实例以便调用其定义的数据库操作方法实现与数据库的交互。
private CategoryMapper categoryMapper;
/**
* ID
*
* @param categoryId IDnull
* @return ServerResponse
*/
@Override
public ServerResponse getCategory(Integer categoryId) {
//1.校验参数
if(categoryId == null){
// 1.校验参数
if (categoryId == null) {
// 如果品类ID为null说明参数不符合要求抛出SnailmallException异常提示“未找到该品类”由全局异常处理机制进行处理。
throw new SnailmallException("未找到该品类");
}
//2.根据父亲id获取这个父亲下一级所有子ID
// 2.根据父亲id获取这个父亲下一级所有子ID
List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
if(CollectionUtils.isEmpty(categoryList)){
if (CollectionUtils.isEmpty(categoryList)) {
// 如果获取到的子品类列表为空,说明该节点下没有任何子节点,记录相应的日志信息供后续查看。
log.info("该节点下没有任何子节点");
}
return ServerResponse.createBySuccess(categoryList);
}
/**
* ID
*
* @param categoryName
* @param parentId ID0
* @return ServerResponse
*/
@Override
public ServerResponse addCategory(String categoryName, int parentId) {
//1.校验参数
if(StringUtils.isBlank(categoryName)){
// 1.校验参数
if (StringUtils.isBlank(categoryName)) {
// 如果品类名称为空字符串说明参数不符合要求抛出SnailmallException异常提示“品类名字不能为空”由全局异常处理机制进行处理。
throw new SnailmallException("品类名字不能为空");
}
//2.创建类目
// 2.创建类目
Category category = new Category();
category.setName(categoryName);
category.setParentId(parentId);
category.setStatus(true);
int resultCount = categoryMapper.insert(category);
if(resultCount > 0){
if (resultCount > 0) {
// 如果数据库插入操作影响的行数大于0说明插入成功返回包含“添加品类成功”提示消息的成功响应。
return ServerResponse.createBySuccessMessage("添加品类成功");
}
return ServerResponse.createByErrorMessage("添加品类失败");
}
/**
* ID
*
* @param categoryName
* @param categoryId ID
* @return ServerResponse<String>
* <String>
*/
@Override
public ServerResponse<String> updateCategoryName(String categoryName, Integer categoryId) {
//1.校验参数
if(StringUtils.isBlank(categoryName)){
// 1.校验参数
if (StringUtils.isBlank(categoryName)) {
// 如果品类名称为空字符串说明参数不符合要求抛出SnailmallException异常提示“品类名字不能为空”由全局异常处理机制进行处理。
throw new SnailmallException("品类名字不能为空");
}
//2.根据id获取品类
// 2.根据id获取品类
Category tmpCat = categoryMapper.selectByPrimaryKey(categoryId);
if(tmpCat == null){
if (tmpCat == null) {
// 如果根据ID没有查询到对应的品类说明品类不存在抛出SnailmallException异常提示“品类不存在”由全局异常处理机制进行处理。
throw new SnailmallException("品类不存在");
}
//3.更新品类名称
// 3.更新品类名称
Category category = new Category();
category.setId(categoryId);
category.setName(categoryName);
int resultCount = categoryMapper.updateByPrimaryKeySelective(category);
if(resultCount > 0){
if (resultCount > 0) {
// 如果数据库更新操作影响的行数大于0说明更新成功返回包含“更新品类名称成功”提示消息的成功响应。
return ServerResponse.createBySuccessMessage("更新品类名称成功");
}
return ServerResponse.createByErrorMessage("更新品类名称失败");
}
/**
* IDID
*
* @param categoryId IDnull
* @return ServerResponseIDID
*/
@Override
public ServerResponse selectCategoryAndDeepChildrenById(Integer categoryId) {
//1、创建一个空Set用来存放不重复的品类对象--去重
// 1、创建一个空Set用来存放不重复的品类对象--去重
Set<Category> categorySet = Sets.newHashSet();
//2、递归获取所有的子节点儿子、孙子、等等包括自己也添加进去
findChildCategory(categorySet,categoryId);
//3、将递归获取到的品类id取出来放进list中
// 2、递归获取所有的子节点儿子、孙子、等等包括自己也添加进去
findChildCategory(categorySet, categoryId);
// 3、将递归获取到的品类id取出来放进list中
List<Integer> categoryIdList = new ArrayList<>();
if(categoryId != null){
for(Category category:categorySet){
if (categoryId!= null) {
for (Category category : categorySet) {
categoryIdList.add(category.getId());
}
}
return ServerResponse.createBySuccess(categoryIdList);
}
private Set<Category> findChildCategory(Set<Category> categorySet,Integer categoryId){
//4、如果自己不为空的话首先把自己添加进去如果自己为空这个递归分支就结束所以也是一个停止条件
/**
* selectCategoryAndDeepChildrenByIdSet
*
* @param categorySet Set
* @param categoryId IDnull
* @return Set便
*/
private Set<Category> findChildCategory(Set<Category> categorySet, Integer categoryId) {
// 4、如果自己不为空的话首先把自己添加进去如果自己为空这个递归分支就结束所以也是一个停止条件
Category category = categoryMapper.selectByPrimaryKey(categoryId);
if(category != null){
if (category!= null) {
categorySet.add(category);
}
//5、根据父亲id获取下一级所有品类即先获取儿子们
// 5、根据父亲id获取下一级所有品类即先获取儿子们
List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
//6、根据每一个儿子再获取儿子的儿子们递归下去
for(Category categoryItem:categoryList){
findChildCategory(categorySet,categoryItem.getId());
// 6、根据每一个儿子再获取儿子的儿子们递归下去
for (Category categoryItem : categoryList) {
findChildCategory(categorySet, categoryItem.getId());
}
return categorySet;
}
/**
* ID
*
* @param categoryId IDnull
* @return ServerResponse
*/
@Override
public ServerResponse getCategoryDetail(Integer categoryId) {
if(categoryId == null){
if (categoryId == null) {
return ServerResponse.createByErrorMessage("参数不能为空");
}
Category category = categoryMapper.selectByPrimaryKey(categoryId);
if(category == null){
if (category == null) {
return ServerResponse.createByErrorMessage("品类不存在");
}
return ServerResponse.createBySuccess(category);
}
}
}

@ -4,6 +4,9 @@ import com.njupt.swg.common.resp.ServerResponse;
import com.njupt.swg.entity.Category;
/**
* ICategoryService
* CategoryServiceImpl便
*
* @Author swg.
* @Date 2019/1/2 12:54
* @CONTACT 317758022@qq.com
@ -11,19 +14,50 @@ import com.njupt.swg.entity.Category;
*/
public interface ICategoryService {
/** 根据类目id获取其下面所有的一级子类目 **/
/**
* id
* ID使ServerResponse便
* @param categoryId ID
* @return ServerResponse
*/
ServerResponse getCategory(Integer categoryId);
/** 新建一个商品类目 **/
/**
*
* ID使ServerResponse
*
* @param categoryName
* @param parentId ID0
* @return ServerResponse
*/
ServerResponse addCategory(String categoryName, int parentId);
/** 更新品类名称 **/
/**
*
* ID使ServerResponse<String>
* <String>
* @param categoryName
* @param categoryId
* @return ServerResponse<String>
*/
ServerResponse<String> updateCategoryName(String categoryName, Integer categoryId);
/** 递归查询出所有品类 **/
/**
*
* ID使ServerResponse便
*
* @param categoryId null
* @return ServerResponseID
*/
ServerResponse selectCategoryAndDeepChildrenById(Integer categoryId);
/** 被其他服务调用的接口 **/
/**
*
* ID使ServerResponse便
* 使
* @param categoryId ID
* @return ServerResponse
*/
ServerResponse getCategoryDetail(Integer categoryId);
}
}
Loading…
Cancel
Save