ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

day71(添加类别--持久层,添加类别--业务逻辑层)

2022-06-11 22:00:13  阅读:164  来源: 互联网

标签:category product cn -- 添加 csmall 类别 import id


day71(添加类别--持久层,添加类别--业务逻辑层)

1.类别管理--添加类别--持久层

1.配置

续前日,无新增

2.规划需要执行的SQL语句

续前日,无新增

3.接口与抽象方法

此前需要执行的SQL语句大致是

select id from pms_category where name=?

1.创建CategorySimpleVO类

在csmall-pojo的根包下创建vo.CategorySimpleVO类,用于封装以上查询结果:

@Data
public class CategorySimpleVO implements Serializable {
   private Long id;
}

2.添加抽象方法(在csmall-product-webapiCategoryMapper接口中)

CategorySimpleVO getByName(String name);

4.配置SQL语句

在csmall-product-webapi的CategoryMapper.xml中添加配置:

<!-- CategorySimpleVO getByName(String name); -->
<select id="getByName" resultMap="SimpleResultMap">
   select id from pms_category where name=#{name}
</select>

<resultMap id="SimpleResultMap" type="cn.tedu.csmall.pojo.vo.CategorySimpleVO">
   <id column="id" property="id" />
</resultMap>

5.测试

1.创建insert_data.sql文件(用于插入数据测试)

csmall-product-webapisrc\test\resources下创建insert_data.sql文件

insert into pms_category (name) value ('类别001'), ('类别002');

2.在CategoryMapperTests中添加测试方法:

@Test
@Sql({"classpath:truncate.sql","classpath:insert_data.sql"})
public void testGetByNameSuccessfully(){
   //测试数据
   String name="类别001";
   //断言不会抛出异常
   assertDoesNotThrow(()->{
       //执行查询
       CategorySimpleVO category=mapper.getByName(name);
       //断言查询结果为null
       assertNotNull(category);
  });
}
@Test
@Sql("classpath:truncate.sql")
public void testGetByNameFailBecauseNotFound(){
   //测试数据
   String name ="类别999";
   //断言不会抛出异常
   assertDoesNotThrow(()->{
       //执行查询
       CategorySimpleVO category=mapper.getByName(name);
       //断言查询结果为null
       assertNull(category);
  });
}

3.执行整个测试类

2.类别管理--添加类别--业务逻辑层

1.接口与抽象方法

1.建立专门存放业务逻辑层的接口的Module(名为:csmall-product-service)

2.配置(新Module下的pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <!-- 父级项目 -->
   <parent>
       <groupId>cn.tedu</groupId>
       <artifactId>csmall-product</artifactId>
       <version>0.0.1-SNAPSHOT</version>
   </parent>

   <!-- 当前项目的信息 -->
   <groupId>cn.tedu</groupId>
   <artifactId>csmall-product-service</artifactId>
   <version>0.0.1-SNAPSHOT</version>

   <!-- 当前项目需要使用的依赖项 -->
   <dependencies>
       <!-- Csmall POJO -->
       <dependency>
           <groupId>cn.tedu</groupId>
           <artifactId>csmall-pojo</artifactId>
       </dependency>
   </dependencies>

</project>

3.在csmall-product的pom.xml中补充子级Module

<!-- 当前Project的各子级Module -->
<modules>
   <module>csmall-product-webapi</module>
   <module>csmall-product-service</module> <!-- 新增 -->
</modules>

4.删除不必要文件

  • 启动类

  • src\main\resources及其下的配置文件

  • src\test

5.创建接口并添加抽象方法

1.方法的参数应该是封装的对象(因为一个StringLong等简单数据不足以完成添加类别的操作)

2.创建dto.CategoryAddNewDTO类(在csmall-pojo的根包下)

package cn.tedu.csmall.pojo.dto;

import lombok.Data;

import java.io.Serializable;

@Data
public class CategoryAddNewDTO implements Serializable {

   private String name;
   private Long parentId;
   private String keywords;
   private Integer sort;
   private String icon;
   private Integer isDisplay;

}

3.创建接口(CategoryService接口)

csmall-product-service中,在cn.tedu.csmall.product.service下创建ICategoryService接口:

public interface ICategoryService {
   void addNew(CategoryAddNewDTO categoryAddNewDTO);
}

2.实现

1.方法

  1. 因为在csmall-product-service中只能存放业务逻辑层的接口

  2. 业务逻辑层的实现类仍在csmall-product-webapi中。

  3. 因此,需要在csmall-product-webapi中依赖csmall-product-service

2.步骤

1.在Project的pom.xml中添加对csmall-product-service的依赖管理:

<!-- ===== 原有其它代码 ===== -->

<!-- 依赖管理,主要管理各依赖项的版本,使得子级Module添加依赖时不必指定版本 -->
<dependencyManagement>
   <dependencies>
       <!-- Csmall Product Service -->
       <dependency>
           <groupId>cn.tedu</groupId>
           <artifactId>csmall-product-service</artifactId>
           <version>${csmall.version}</version>
       </dependency>
       
       <!-- ===== 原有其它代码 ===== -->

2.在csmall-product-webapi中添加依赖:

<!-- ===== 原有其它代码 ===== -->

<!-- 当前项目需要使用的依赖项 -->
<dependencies>
   <!-- Csmall Product Service -->
   <dependency>
       <groupId>cn.tedu</groupId>
       <artifactId>csmall-product-service</artifactId>
   </dependency>
   
   <!-- ===== 原有其它代码 ===== -->

3.创建service.CategoryServiceImpl类:实现ICategoryService接口,添加

@Service注解(在cn.tedu.csmall.product.webapi下)

package cn.tedu.csmall.product.webapi.service;

import cn.tedu.csmall.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.service.ICategoryService;
import org.springframework.stereotype.Service;

@Service
public class CategoryServiceImpl implements ICategoryService {
   
   @Override
   public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
  }
   
}

4.业务分析

@Autowired
private CategoryMapper categoryMapper;
//注意:需要在categoryMapper中补充getById()方法,至少返回depthd
//注意:需要创建异常
public void addNew(CategoryAddNewDTO categoryAddNewDTO){
   //从参数中尝试获取添加的类别的名称
   //在category中调用getByName方法,判断是否为null
   //是,抛出异常serviceException
   
   //从参数中取出父级类别id:parentId
   //判断parentId是否为0
   //是,那么不存在父级,则为一级类别,当前depth=1
   //否,那么存在父级,调用categoryMapper.getById()方法查询父级类别的信息
 
   //判断查询结果是否为null
   //是:抛出异常:serviceException
   //否:当前depth=>父级depth+1
   //创建category对象
   //调用beanUtils.copyProperties()将参数对象中的属性值复制到category对象中
   // 补全Category对象中的属性值:depth >>> 前序运算结果
   // 补全Category对象中的属性值:enable >>> 1(默认即启用)
   // 补全Category对象中的属性值:isParent >>> 0
   // 补全Category对象中的属性值:gmtCreate, gmtModified >>> LocalDateTime.now()
   //调用categoryMapper.insert(category)插入数据,返回受影响的行数
   //判断行数是否不为1
   //是:抛出异常serviceException
   
}
1.实现(根据id查询类别信息)
  1. 要实现以上业务,需要先在持久层完成“根据id查询类别信息”的功能,则在CategorySimpleVO中添加private Integer depth;属性(原getByName()方法对应的查询也作对应的修改,虽然不是必须的)。

  2. 添加private Integer isParent;属性(在CategorySimpleVO中),并且,必须在接下的查询中,查出此值。

  3. CategeoryMapper接口中添加:

    CategorySimpleVO getById(Long id);
  4. CategoryMapper.xml中配置以上方法映射的SQL:

    <!-- CategorySimpleVO getById(Long id); -->
    <select id="getById" resultMap="SimpleResultMap">
       select id, depth from pms_category where id=#{id}
    </select>
  5. 测试(CategoryMapperTests)

    @Test
    @Sql({"classpath:truncate.sql", "classpath:insert_data.sql"})
    public void testGetByIdSuccessfully() {
       // 测试数据
       Long id = 1L;
       // 断言不会抛出异常
       assertDoesNotThrow(() -> {
           // 执行查询
           CategorySimpleVO category = mapper.getById(id);
           // 断言查询结果不为null
           assertNotNull(category);
      });
    }

    @Test
    @Sql({"classpath:truncate.sql"})
    public void testGetByIdFailBecauseNotFound() {
       // 测试数据
       Long id = -1L;
       // 断言不会抛出异常
       assertDoesNotThrow(() -> {
           // 执行查询
           CategorySimpleVO category = mapper.getById(id);
           // 断言查询结果为null
           assertNull(category);
      });
    }
  6. CategoryMapper接口中添加:

    int updateIsParentById(@Param("id") Long id, @Param("isParent") Integer isParent);
  7. CategoryMapper.xml中配置以上方法映射的SQL:

    <!-- int updateIsParentById(@Param("id") Long id, @Param("isParent") Integer isParent); -->
    <update id="updateIsParentById">
       update pms_category set is_parent=#{isParent} where id=#{id}
    </update>
  8. 测试(CategoryMapperTests)

    @Test
    @Sql({"classpath:truncate.sql", "classpath:insert_data.sql"})
    public void testUpdateIsParentByIdSuccessfully() {
       // 测试数据
       Long id = 1L;
       Integer isParent = 1;
       // 断言不会抛出异常
       assertDoesNotThrow(() -> {
           // 执行测试
           int rows = mapper.updateIsParentById(id, isParent);
           // 断言受影响的行数为1
           assertEquals(1, rows);
      });
    }

    @Test
    @Sql({"classpath:truncate.sql"})
    public void testUpdateIsParentByIdFailBecauseNotFound() {
       // 测试数据
       Long id = -1L;
       Integer isParent = 1;
       // 断言不会抛出异常
       assertDoesNotThrow(() -> {
           // 执行测试
           int rows = mapper.updateIsParentById(id, isParent);
           // 断言受影响的行数为0
           assertEquals(0, rows);
      });
    }

5.自定义异常类型(创建csmall-commonModule)

原因:

由于后续还有不少需要被多个Module共同使用的类、接口等,所以,此异常类型和后续可能被共用的类、接口都应该放在一个公共的Module中,则在Project下创建csmall-common这个新的Module,创建成功后,需要:

  • csmall-common中,修改pom.xml中的父项目

  • csmall-common中,在pom.xml删除依赖项

  • csmall-common中,在pom.xml删除<build>配置

  • csmall-common中,删除src/test

  • csmall-common中,删除src/main/resources

  • csmall-common中,删除启动类

  • 在Project的pom.xml中,添加<module>

  • 在Project的pom.xml中,添加对新Module的依赖管理

  • csmall-product-webapi中的pom.xml中,添加对csmall-common的依赖

1.创建ex.ServiceException类
public class ServiceException extends RuntimeException {
// 暂时不加构造方法
}

6.实现业务(在csmall-product-webapi中的CategoryServiceImpl)

package cn.tedu.csmall.product.webapi.service;

import cn.tedu.csmall.common.ex.ServiceException;
import cn.tedu.csmall.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.pojo.entity.Category;
import cn.tedu.csmall.pojo.vo.CategorySimpleVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.webapi.mapper.CategoryMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class CategoryServiceImpl implements ICategoryService {

   @Autowired
   CategoryMapper categoryMapper;

   @Override
   public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
       // 从参数中取出尝试添加的类别的名称
       String name = categoryAddNewDTO.getName();
       // 调用categoryMapper.getByName()方法查询
       CategorySimpleVO queryResult = categoryMapper.getByName(name);
       // 判断查询结果是否不为null
       if (queryResult != null) {
           // 是:抛出ServiceException
           throw new ServiceException();
      }

       // 从参数中取出父级类别的id:parentId
       Long parentId = categoryAddNewDTO.getParentId();
       // 判断parentId是否为0,当前尝试新增的类别的depth默认为1
       Integer depth = 1;
       CategorySimpleVO parentCategory = null;
       if (parentId != 0) {
           // 否:此次尝试添加的不是一级类别,则应该存在父级类别,调用categoryMapper.getById()方法查询父级类别的信息
           parentCategory = categoryMapper.getById(parentId);
           // -- 判断查询结果是否为null
           if (parentCategory == null) {
               // -- 是:抛出ServiceException
               throw new ServiceException();
          }
           // -- 否:当前depth >>> 父级depth + 1
           depth = parentCategory.getDepth() + 1;
      }

       // 创建Category对象
       Category category = new Category();
       // 调用BeanUtils.copyProperties()将参数对象中的属性值复制到Category对象中
       BeanUtils.copyProperties(categoryAddNewDTO, category);
       // 补全Category对象中的属性值:depth >>> 前序运算结果
       category.setDepth(depth);
       // 补全Category对象中的属性值:enable >>> 1(默认即启用)
       category.setEnable(1);
       // 补全Category对象中的属性值:isParent >>> 0
       category.setIsParent(0);
       // 补全Category对象中的属性值:gmtCreate, gmtModified >>> LocalDateTime.now()
       LocalDateTime now = LocalDateTime.now();
       category.setGmtCreate(now);
       category.setGmtModified(now);
       // 调用categoryMapper.insert(Category)插入类别数据,获取返回的受影响的行数
       int rows = categoryMapper.insert(category);
       // 判断返回的受影响的行数是否不为1
       if (rows != 1) {
           // 是:抛出ServiceException
           throw new ServiceException();
      }

       // 判断父级类别的isParent是否为0
       // 以下判断条件有部分多余,但不会报错
       if (parentId != 0 && parentCategory != null && parentCategory.getIsParent() == 0) {
           // 是:调用categoryMapper.updateIsParentById()方法,将父级类别的isParent修改为1,获取返回的受影响的行数
           rows = categoryMapper.updateIsParentById(parentId, 1);
           // 判断返回的受影响的行数是否不为1
           if (rows != 1) {
               // 是:抛出ServiceException
               throw new ServiceException();
          }
      }
  }

}

7.测试(在src/test/java下的根包下创建service.CategoryServiceTests测试类)

package cn.tedu.csmall.product.webapi.service;

import cn.tedu.csmall.common.ex.ServiceException;
import cn.tedu.csmall.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.service.ICategoryService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringBootTest
public class CategoryServiceTests {

   @Autowired
   ICategoryService service;

   @Test
   @Sql("classpath:truncate.sql")
   public void testAddNewSuccessfully() {
       // 测试数据
       CategoryAddNewDTO category = new CategoryAddNewDTO();
       category.setName("大屏智能手机");
       category.setParentId(0L);
       category.setIcon("未上传类别图标");
       category.setKeywords("未设置关键字");
       category.setSort(88);
       category.setIsDisplay(1);
       // 断言不会抛出异常
       assertDoesNotThrow(() -> {
           // 执行测试
           service.addNew(category);
      });
  }

   @Test
   @Sql({"classpath:truncate.sql", "classpath:insert_data.sql"})
   public void testAddNewFailBecauseNameDuplicate() {
       // 测试数据
       CategoryAddNewDTO category = new CategoryAddNewDTO();
       category.setName("类别001");
       // 断言不会抛出异常
       assertThrows(ServiceException.class, () -> {
           // 执行测试
           service.addNew(category);
      });
  }

   @Test
   @Sql({"classpath:truncate.sql"})
   public void testAddNewFailBecauseParentNotFound() {
       // 测试数据
       CategoryAddNewDTO category = new CategoryAddNewDTO();
       category.setName("类别001");
       category.setParentId(-1L);
       // 断言不会抛出异常
       assertThrows(ServiceException.class, () -> {
           // 执行测试
           service.addNew(category);
      });
  }

}
 

标签:category,product,cn,--,添加,csmall,类别,import,id
来源: https://www.cnblogs.com/xiaoyezilei/p/16366924.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有