学习标签接口开发:完整CRUD开发流程详解

文章目录

  • 1.easyCode生成CRUD
  • 1.生成代码
  • 2.查看代码
  • 3.调整代码
  • 1.SubjectLabelDao.xml发现生成的select语句不带逗号!!!
  • 1.解决方法:
  • 2.entity.java.vm
  • 3.dao.java.vm
  • 4.Mapper.xml.vm
  • 2.重新生成代码
  • 3.SubjectLabelDao.java 删除Pageable相关代码
  • 4.SubjectLabelService.java 删除分页查询接口
  • 5.SubjectLabelServiceImpl.java 删除分页查询接口
  • 6.实体类SubjectLabel.java 使用lombok简化
  • 2.新增标签接口
  • 1.sun-club-application-controller
  • 1.编写SubjectLabelDTO.java
  • 2.SubjectLabelDTOConverter.java 编写基础转换器
  • 2.sun-club-domain
  • 1.SubjectLabelBO.java
  • 2.SubjectLabelConverter.java 编写基础转换器
  • 3.sun-club-domain
  • 1.service
  • 1.SubjectLabelDomainService.java 先编写一个新增标签的接口
  • 4.sun-club-application-controller
  • 1.SubjectLabelController.java
  • 5.sun-club-domain
  • 1.SubjectLabelDomainServiceImpl.java
  • 6.sun-club-infra
  • 1.SubjectLabelService.java
  • 2.SubjectLabelServiceImpl.java
  • 3.更新标签接口
  • 1.基本设计
  • 2.sun-club-application-controller
  • 1.SubjectLabelController.java
  • 3.sun-club-domain
  • 1.SubjectLabelDomainService.java
  • 2.SubjectLabelDomainServiceImpl.java
  • 4.sun-club-infra
  • 1.SubjectLabelService.java
  • 2.SubjectLabelServiceImpl.java
  • 4.删除标签接口
  • 1.基本设计
  • 2.sun-club-application-controller
  • 1.SubjectLabelController.java
  • 3.sun-club-domain
  • 1.SubjectLabelDomainService.java
  • 2.SubjectLabelDomainServiceImpl.java
  • 5.根据分类查询标签
  • 1.生成subject_mapping表的CRUD
  • 1.生成代码
  • 2.修改生成的SubjectMappingDao.java的位置为mapper下
  • 3.实体类SubjectMapping.java使用lombok简化
  • 4.SubjectMappingDao.java删除Pageable
  • 5.SubjectMappingService.java删除分页查询接口
  • 6.SubjectMappingServiceImpl.java删除分页查询实现类
  • 7.SubjectMappingService.java把新增和修改的返回值改为int,只返回影响的记录条数
  • 8.SubjectMappingServiceImpl.java也对新增和修改的实现类做相应调整
  • 2.SubjectLabelController.java
  • 3.sun-club-domain
  • 1.SubjectLabelDomainService.java
  • 2.SubjectLabelDomainServiceImpl.java
  • 4.sun-club-infra
  • 1.service
  • 1.SubjectMappingService.java
  • 2.SubjectLabelService.java
  • 3.SubjectMappingServiceImpl.java
  • 4.SubjectLabelServiceImpl.java
  • 2.mapper
  • 1.SubjectMappingDao.java
  • 2.SubjectLabelDao.java
  • 3.SubjectMappingDao.xml
  • 4.SubjectLabelDao.xml
  • 6.标签接口总体测试
  • 1.新增标签接口
  • 2.更新标签接口
  • 3.删除标签接口
  • 4.根据分类查询标签
  • 1.报错Parsing error was found in mapping #{categoryId, INTEGER}. Check syntax #{property|(expression), var1=value1, var2=value2, …}
  • 2.将SubjectMappingDao.xml里面指定类型时加上jdbcType属性即可
  • 3.再次请求,发现根据id批量查询的时候判断空的条件错了,将!去掉
  • 4.再次请求发现xml中的labelIdList参数没找到,原因是没有加@Param注解
  • 5.再次请求,成功查找到信息
  • 6.但是,在根据labelId进行批量查询的时候没有考虑逻辑删除,会将数据都查出来
  • 7.在SubjectLabelDao.xml的批量查询时加个条件即可
  • 1.easyCode生成CRUD

    1.生成代码

    image-20240525164022418

    2.查看代码

    image-20240525162249082

    3.调整代码
    1.SubjectLabelDao.xml发现生成的select语句不带逗号!!!
    1.解决方法:

    在easycode的设置里找到:

    1、Template下的 mapper.xml.vm脚本

    2、Global Config下的 mybatisSupport.vm脚本

    然后将这两个脚本里的 $velocityHasNext 替换成 $foreach.hasNext,然后保存设置。之后新生成的mapper.xml里就不会出现没有逗号间隔的问题了。

    2.entity.java.vm
    ##引入宏定义
    $!{define.vm}
     
    ##使用宏定义设置回调(保存位置与文件后缀)
    #save("/entity", ".java")
     
    ##使用宏定义设置包后缀
    #setPackageSuffix("entity")
     
    ##使用全局变量实现默认包导入
    $!{autoImport.vm}
    import java.io.Serializable;
     
    ##使用宏定义实现类注释信息
    #tableComment("实体类")
    public class $!{tableInfo.name} implements Serializable {
        private static final long serialVersionUID = $!tool.serial();
    #foreach($column in $tableInfo.fullColumn)
        #if(${column.comment})/**
         * ${column.comment}
         */#end
     
        private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
    #end
     
    #foreach($column in $tableInfo.fullColumn)
    ##使用宏定义实现get,set方法
    #getSetMethod($column)
    #end
     
    }
    
    3.dao.java.vm
    ##定义初始变量
    #set($tableName = $tool.append($tableInfo.name, "Dao"))
    ##设置回调
    $!callback.setFileName($tool.append($tableName, ".java"))
    $!callback.setSavePath($tool.append($tableInfo.savePath, "/dao"))
     
    ##拿到主键
    #if(!$tableInfo.pkColumn.isEmpty())
        #set($pk = $tableInfo.pkColumn.get(0))
    #end
     
    #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao;
     
    import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
    import org.apache.ibatis.annotations.Param;
    import org.springframework.data.domain.Pageable;
    import java.util.List;
     
    /**
     * $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层
     *
     * @author $!author
     * @since $!time.currTime()
     */
    public interface $!{tableName} {
     
        /**
         * 通过ID查询单条数据
         *
         * @param $!pk.name 主键
         * @return 实例对象
         */
        $!{tableInfo.name} queryById($!pk.shortType $!pk.name);
     
        /**
         * 查询指定行数据
         *
         * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件
         * @param pageable         分页对象
         * @return 对象列表
         */
        List<$!{tableInfo.name}> queryAllByLimit($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}), @Param("pageable") Pageable pageable);
     
        /**
         * 统计总行数
         *
         * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件
         * @return 总行数
         */
        long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
     
        /**
         * 新增数据
         *
         * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
         * @return 影响行数
         */
        int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
     
        /**
         * 批量新增数据(MyBatis原生foreach方法)
         *
         * @param entities List<$!{tableInfo.name}> 实例对象列表
         * @return 影响行数
         */
        int insertBatch(@Param("entities") List<$!{tableInfo.name}> entities);
     
        /**
         * 批量新增或按主键更新数据(MyBatis原生foreach方法)
         *
         * @param entities List<$!{tableInfo.name}> 实例对象列表
         * @return 影响行数
         * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
         */
        int insertOrUpdateBatch(@Param("entities") List<$!{tableInfo.name}> entities);
     
        /**
         * 修改数据
         *
         * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
         * @return 影响行数
         */
        int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
     
        /**
         * 通过主键删除数据
         *
         * @param $!pk.name 主键
         * @return 影响行数
         */
        int deleteById($!pk.shortType $!pk.name);
     
    }
    
    4.Mapper.xml.vm
    ##引入mybatis支持
    $!{mybatisSupport.vm}
     
    ##设置保存名称与保存位置
    $!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
    $!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))
     
    ##拿到主键
    #if(!$tableInfo.pkColumn.isEmpty())
        #set($pk = $tableInfo.pkColumn.get(0))
    #end
     
    <?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="$!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao">
     
        <resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map">
    #foreach($column in $tableInfo.fullColumn)
            <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
    #end
        </resultMap>
     
        <!--查询单个-->
        <select id="queryById" resultMap="$!{tableInfo.name}Map">
            select #allSqlColumn() 
            from $!tableInfo.obj.name
            where $!pk.obj.name = #{$!pk.name}
        </select>
     
        <!--查询指定行数据-->
        <select id="queryAllByLimit" resultMap="$!{tableInfo.name}Map">
            select  #allSqlColumn()
            from $!tableInfo.obj.name
            <where>
    #foreach($column in $tableInfo.fullColumn)
                <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                    and $!column.obj.name = #{$!column.name, $!column.ext.jdbcType}
                </if>
    #end
            </where>
            limit #{pageable.offset}, #{pageable.pageSize}
        </select>
     
        <!--统计总行数-->
        <select id="count" resultType="java.lang.Long">
            select count(1)
            from $!tableInfo.obj.name
            <where>
    #foreach($column in $tableInfo.fullColumn)
                <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                    and $!column.obj.name = #{$!column.name, $!column.ext.jdbcType}
                </if>
    #end
            </where>
        </select>
     
        <!--新增所有列-->
        <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
            insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)
            values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($foreach.hasNext), #end#end)
        </insert>
     
        <insert id="insertBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
            insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)
            values
            <foreach collection="entities" item="entity" separator=",">
            (
            #foreach($column in $tableInfo.otherColumn)
               <choose>
                    <when test="entity.${column.name} != null">
                     #{entity.$!{column.name}}#if($foreach.hasNext), #end
                    </when>
                    <otherwise>NULL#if($foreach.hasNext), #end</otherwise>
              </choose>
             #end
             )
            </foreach>
        </insert>
    
     
        <insert id="insertOrUpdateBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
            insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)
            values
            <foreach collection="entities" item="entity" separator=",">
                (#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($foreach.hasNext), #end#end)
            </foreach>
            on duplicate key update
            #foreach($column in $tableInfo.otherColumn)
             $!column.obj.name = values($!column.obj.name)#if($foreach.hasNext),
            #end#end
     
        </insert>
     
        <!--通过主键修改数据-->
        <update id="update">
            update $!{tableInfo.obj.name}
            <set>
    #foreach($column in $tableInfo.otherColumn)
                <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                    $!column.obj.name = #{$!column.name},
                </if>
    #end
            </set>
            where $!pk.obj.name = #{$!pk.name}
        </update>
     
        <!--通过主键删除-->
        <delete id="deleteById">
            delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
        </delete>
     
    </mapper>
    
    2.重新生成代码
    3.SubjectLabelDao.java 删除Pageable相关代码

    image-20240525164912586

    4.SubjectLabelService.java 删除分页查询接口

    image-20240525165147218

    5.SubjectLabelServiceImpl.java 删除分页查询接口

    image-20240525165209692

    6.实体类SubjectLabel.java 使用lombok简化

    image-20240525165354818

    2.新增标签接口

    1.sun-club-application-controller
    1.编写SubjectLabelDTO.java
    package com.sunxiansheng.subject.application.dto;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * 题目标签表(SubjectLabel)实体类
     */
    @Data
    public class SubjectLabelDTO implements Serializable {
        private static final long serialVersionUID = 965293549798069262L;
        /**
         * 主键
         */
        private Long id;
    
        /**
         * 标签分类
         */
        private String labelName;
    
        /**
         * 排序
         */
        private Integer sortNum;
    
        /**
         * 分类id
         */
        private String categoryId;
    
    }
    
    
    2.SubjectLabelDTOConverter.java 编写基础转换器
    package com.sunxiansheng.subject.application.convert;
    
    import com.sunxiansheng.subject.application.dto.SubjectLabelDTO;
    import com.sunxiansheng.subject.domain.entity.SubjectLabelBO;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    import java.util.List;
    
    /**
     * Description: DTO与BO转换
     * @Author sun
     * @Create 2024/5/24 9:40
     * @Version 1.0
     */
    @Mapper
    public interface SubjectLabelDTOConverter {
        SubjectLabelDTOConverter INSTANCE= Mappers.getMapper(SubjectLabelDTOConverter.class);
    
        // 将SubjectLabelDTO转换为SubjectLabelBO
        SubjectLabelBO convertDTOToSubjectLabel(SubjectLabelDTO subjectLabelDTO);
    
        // 将SubjectLabelBO转换为SubjectLabelDTO
        SubjectLabelDTO convertSubjectLabelToDto(SubjectLabelBO subjectLabelBO);
    
        // 将List<SubjectLabelDTO>转换为List<SubjectLabelBO>
        List<SubjectLabelBO> convertDTOToSubjectLabel(List<SubjectLabelDTO> subjectLabelDTOList);
    
        // 将List<SubjectLabelBO>转换为List<SubjectLabelDTO>
        List<SubjectLabelDTO> convertSubjectLabelToDto(List<SubjectLabelBO> subjectLabelBOList);
    }
    
    
    2.sun-club-domain
    1.SubjectLabelBO.java
    package com.sunxiansheng.subject.domain.entity;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/5/25 17:10
     * @Version 1.0
     */
    @Data
    public class SubjectLabelBO implements Serializable {
        private static final long serialVersionUID = 965293549798069262L;
        /**
         * 主键
         */
        private Long id;
    
        /**
         * 标签分类
         */
        private String labelName;
    
        /**
         * 排序
         */
        private Integer sortNum;
    
        /**
         * 分类id
         */
        private String categoryId;
    }
    
    
    2.SubjectLabelConverter.java 编写基础转换器
    package com.sunxiansheng.subject.domain.convert;
    
    import com.sunxiansheng.subject.domain.entity.SubjectLabelBO;
    import com.sunxiansheng.subject.infra.basic.entity.SubjectLabel;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    import java.util.List;
    
    /**
     * Description: 题目标签转换器
     * @Author sun
     * @Create 2024/5/24 9:18
     * @Version 1.0
     */
    @Mapper // mapstruct的注解
    public interface SubjectLabelConverter {
        SubjectLabelConverter INSTANCE = Mappers.getMapper(SubjectLabelConverter.class);
    
        // 将SubjectLabelBO转换为SubjectLabel
        SubjectLabel convertBoToSubjectLabel(SubjectLabelBO subjectLabelBO);
    
        // 将SubjectLabel转换为SubjectLabelBO
        SubjectLabelBO convertSubjectLabelToBo(SubjectLabel subjectLabel);
    
        // 将List<SubjectLabel>转换为List<SubjectLabelBO>
        List<SubjectLabelBO> convertSubjectLabelToBo(List<SubjectLabel> subjectLabelList);
    
        // 将List<SubjectLabelBO>转换为List<SubjectLabel>
        List<SubjectLabel> convertBoToSubjectLabel(List<SubjectLabelBO> subjectLabelBOList);
    
    }
    
    
    3.sun-club-domain
    1.service
    1.SubjectLabelDomainService.java 先编写一个新增标签的接口
    package com.sunxiansheng.subject.domain.service;
    
    import com.sunxiansheng.subject.domain.entity.SubjectLabelBO;
    
    /**
     * Description: 题目标签领域服务
     * @Author sun
     * @Create 2024/5/24 9:03
     * @Version 1.0
     */
    public interface SubjectLabelDomainService {
    
        // 新增标签
        Boolean add(SubjectLabelBO subjectLabelBO);
    }
    
    
    4.sun-club-application-controller
    1.SubjectLabelController.java
    package com.sunxiansheng.subject.application.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.google.common.base.Preconditions;
    import com.sunxiansheng.subject.application.convert.SubjectCategoryDTOConverter;
    import com.sunxiansheng.subject.application.convert.SubjectLabelDTOConverter;
    import com.sunxiansheng.subject.application.dto.SubjectCategoryDTO;
    import com.sunxiansheng.subject.application.dto.SubjectLabelDTO;
    import com.sunxiansheng.subject.common.eneity.Result;
    import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;
    import com.sunxiansheng.subject.domain.entity.SubjectLabelBO;
    import com.sunxiansheng.subject.domain.service.SubjectLabelDomainService;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    /**
     * Description: 题目标签controller
     * @Author sun
     * @Create 2024/5/25 16:54
     * @Version 1.0
     */
    @RestController
    @RequestMapping("/subject/label")
    @Slf4j
    public class SubjectLabelController {
        @Resource
        private SubjectLabelDomainService subjectLabelDomainService;
    
        @PostMapping("/add")
        public Result<Boolean> add(@RequestBody SubjectLabelDTO subjectLabelDTO) {
            try {
                // 打印日志
                if (log.isInfoEnabled()) {
                    log.info("SubjectLabelController add SubjectLabelDTO, subjectLabelDTO:{}", JSON.toJSONString(subjectLabelDTO));
                }
                // 参数校验
                Preconditions.checkArgument(!StringUtils.isBlank(subjectLabelDTO.getLabelName()), "标签名称不能为空");
                // 转换DTO为BO
                SubjectLabelBO subjectLabelBO = SubjectLabelDTOConverter.INSTANCE.convertDTOToSubjectLabel(subjectLabelDTO);
                // 调用领域服务
                Boolean result = subjectLabelDomainService.add(subjectLabelBO);
                return Result.ok(result);
            } catch (Exception e) {
                log.error("SubjectLabelController add error:{}", e.getMessage(), e);
                return Result.fail("新增标签失败");
            }
        }
    }
    
    
    5.sun-club-domain
    1.SubjectLabelDomainServiceImpl.java
    package com.sunxiansheng.subject.domain.service.impl;
    
    import com.alibaba.fastjson.JSON;
    import com.sunxiansheng.subject.common.enums.IsDeleteFlagEnum;
    import com.sunxiansheng.subject.domain.convert.SubjectLabelConverter;
    import com.sunxiansheng.subject.domain.entity.SubjectLabelBO;
    import com.sunxiansheng.subject.domain.service.SubjectLabelDomainService;
    import com.sunxiansheng.subject.infra.basic.entity.SubjectLabel;
    import com.sunxiansheng.subject.infra.basic.service.SubjectLabelService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/5/24 9:03
     * @Version 1.0
     */
    @Service
    @Slf4j
    public class SubjectLabelDomainServiceImpl implements SubjectLabelDomainService {
        @Resource
        private SubjectLabelService subjectLabelService;
    
        @Override
        public Boolean add(SubjectLabelBO subjectLabelBO) {
            // 打印日志
            if (log.isInfoEnabled()) {
                log.info("SubjectLabelDomainServiceImpl add SubjectLabelBO, SubjectLabelBO:{}", JSON.toJSONString(subjectLabelBO));
            }
            // 将BO转换为SubjectLabel
            SubjectLabel subjectLabel = SubjectLabelConverter.INSTANCE.convertBoToSubjectLabel(subjectLabelBO);
            // 设置逻辑删除
            subjectLabel.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
            // 插入数据
            int insert = subjectLabelService.insert(subjectLabel);
            return insert > 0;
        }
    }
    
    
    6.sun-club-infra
    1.SubjectLabelService.java
        /**
         * 新增数据
         *
         * @param subjectLabel 实例对象
         * @return 实例对象
         */
        int insert(SubjectLabel subjectLabel);
    
    2.SubjectLabelServiceImpl.java
        /**
         * 新增数据
         *
         * @param subjectLabel 实例对象
         * @return 实例对象
         */
        @Override
        public int insert(SubjectLabel subjectLabel) {
            return this.subjectLabelDao.insert(subjectLabel);
        }
    

    3.更新标签接口

    1.基本设计

    image-20240526133343998

    2.sun-club-application-controller
    1.SubjectLabelController.java
    /**
     * 更新标签
     * @param subjectLabelDTO
     * @return
     */
    @PostMapping("/update")
    public Result<Boolean> update(@RequestBody SubjectLabelDTO subjectLabelDTO) {
        try {
            // 打印日志
            if (log.isInfoEnabled()) {
                log.info("SubjectLabelController update SubjectLabelDTO, subjectLabelDTO:{}", JSON.toJSONString(subjectLabelDTO));
            }
            // 参数校验
            Preconditions.checkNotNull(subjectLabelDTO.getId(), "标签id不能为空");
            // 转换DTO为BO
            SubjectLabelBO subjectLabelBO = SubjectLabelDTOConverter.INSTANCE.convertDTOToSubjectLabel(subjectLabelDTO);
            // 调用领域服务
            Boolean result = subjectLabelDomainService.update(subjectLabelBO);
            return Result.ok(result);
        } catch (Exception e) {
            log.error("SubjectLabelController update error:{}", e.getMessage(), e);
            return Result.fail("更新标签失败");
        }
    }
    
    3.sun-club-domain
    1.SubjectLabelDomainService.java
        /**
         * 更新标签
         * @param subjectLabelBO
         * @return
         */
        Boolean update(SubjectLabelBO subjectLabelBO);
    
    2.SubjectLabelDomainServiceImpl.java
    @Override
    public Boolean update(SubjectLabelBO subjectLabelBO) {
        // 打印日志
        if (log.isInfoEnabled()) {
            log.info("SubjectLabelDomainServiceImpl update SubjectLabelBO, SubjectLabelBO:{}", JSON.toJSONString(subjectLabelBO));
        }
        // 将BO转换为SubjectLabel
        SubjectLabel subjectLabel = SubjectLabelConverter.INSTANCE.convertBoToSubjectLabel(subjectLabelBO);
        // 更新数据
        int update = subjectLabelService.update(subjectLabel);
        return update > 0;
    }
    
    4.sun-club-infra
    1.SubjectLabelService.java
        /**
         * 修改数据
         *
         * @param subjectLabel 实例对象
         * @return 实例对象
         */
        int update(SubjectLabel subjectLabel);
    
    2.SubjectLabelServiceImpl.java
        /**
         * 修改数据
         *
         * @param subjectLabel 实例对象
         * @return 实例对象
         */
        @Override
        public int update(SubjectLabel subjectLabel) {
            return this.subjectLabelDao.update(subjectLabel);
        }
    

    4.删除标签接口

    1.基本设计

    image-20240526135339866

    2.sun-club-application-controller
    1.SubjectLabelController.java
        /**
         * 删除标签
         * @param subjectLabelDTO
         * @return
         */
        @PostMapping("/delete")
        public Result<Boolean> delete(@RequestBody SubjectLabelDTO subjectLabelDTO) {
            try {
                // 打印日志
                if (log.isInfoEnabled()) {
                    log.info("SubjectLabelController delete SubjectLabelDTO, subjectLabelDTO:{}", JSON.toJSONString(subjectLabelDTO));
                }
                // 参数校验
                Preconditions.checkNotNull(subjectLabelDTO.getId(), "标签id不能为空");
                // 转换DTO为BO
                SubjectLabelBO subjectLabelBO = SubjectLabelDTOConverter.INSTANCE.convertDTOToSubjectLabel(subjectLabelDTO);
                // 调用领域服务
                Boolean result = subjectLabelDomainService.delete(subjectLabelBO);
                return Result.ok(result);
            } catch (Exception e) {
                log.error("SubjectLabelController delete error:{}", e.getMessage(), e);
                return Result.fail("删除标签失败");
            }
        }
    
    3.sun-club-domain
    1.SubjectLabelDomainService.java
    /**
     * 删除标签
     * @param subjectLabelBO
     * @return
     */
    Boolean delete(SubjectLabelBO subjectLabelBO);
    
    2.SubjectLabelDomainServiceImpl.java
        @Override
        public Boolean delete(SubjectLabelBO subjectLabelBO) {
            // 打印日志
            if (log.isInfoEnabled()) {
                log.info("SubjectLabelDomainServiceImpl delete SubjectLabelBO, SubjectLabelBO:{}", JSON.toJSONString(subjectLabelBO));
            }
            // 将BO转换为SubjectLabel
            SubjectLabel subjectLabel = SubjectLabelConverter.INSTANCE.convertBoToSubjectLabel(subjectLabelBO);
            // 设置逻辑删除
            subjectLabel.setIsDeleted(IsDeleteFlagEnum.DELETED.getCode());
            // 更新数据
            int delete = subjectLabelService.update(subjectLabel);
            return delete > 0;
        }
    

    5.根据分类查询标签

    1.生成subject_mapping表的CRUD
    1.生成代码

    image-20240526140504420

    2.修改生成的SubjectMappingDao.java的位置为mapper下

    image-20240526140852585

    3.实体类SubjectMapping.java使用lombok简化

    image-20240526141026599

    4.SubjectMappingDao.java删除Pageable

    image-20240526141106478

    5.SubjectMappingService.java删除分页查询接口

    image-20240526141212064

    6.SubjectMappingServiceImpl.java删除分页查询实现类
    7.SubjectMappingService.java把新增和修改的返回值改为int,只返回影响的记录条数

    image-20240526141622512

    8.SubjectMappingServiceImpl.java也对新增和修改的实现类做相应调整

    image-20240526141754714

    2.SubjectLabelController.java
        /**
         * 查询分类下的标签
         * @param subjectLabelDTO
         * @return
         */
        @PostMapping("/queryLabelByCategoryId")
        public Result<List<SubjectLabelDTO>> queryLabelByCategoryId(@RequestBody SubjectLabelDTO subjectLabelDTO) {
            try {
                // 打印日志
                if (log.isInfoEnabled()) {
                    log.info("SubjectLabelController queryLabelByCategoryId SubjectLabelDTO, subjectLabelDTO:{}", JSON.toJSONString(subjectLabelDTO));
                }
                // 参数校验
                Preconditions.checkNotNull(subjectLabelDTO.getCategoryId(), "分类id不能为空");
                // 转换DTO为BO
                SubjectLabelBO subjectLabelBO = SubjectLabelDTOConverter.INSTANCE.convertDTOToSubjectLabel(subjectLabelDTO);
                // 调用领域服务
                List<SubjectLabelBO> subjectLabelBOList =  subjectLabelDomainService.queryLabelByCategoryId(subjectLabelBO);
                // 将BO转换为DTO
                List<SubjectLabelDTO> subjectLabelDTOList = SubjectLabelDTOConverter.INSTANCE.convertSubjectLabelToDto(subjectLabelBOList);
                return Result.ok(subjectLabelDTOList);
            } catch (Exception e) {
                log.error("SubjectLabelController queryLabelByCategoryId error:{}", e.getMessage(), e);
                return Result.fail("查询分类下的标签失败");
            }
        }
    
    3.sun-club-domain
    1.SubjectLabelDomainService.java
    /**
     * 查询分类下标签
     * @param subjectLabelBO
     * @return
     */
    List<SubjectLabelBO> queryLabelByCategoryId(SubjectLabelBO subjectLabelBO);
    
    2.SubjectLabelDomainServiceImpl.java
        @Override
        public List<SubjectLabelBO> queryLabelByCategoryId(SubjectLabelBO subjectLabelBO) {
            // 打印日志
            if (log.isInfoEnabled()) {
                log.info("SubjectLabelDomainServiceImpl queryLabelByCategoryId SubjectLabelBO, SubjectLabelBO:{}", JSON.toJSONString(subjectLabelBO));
            }
            // 获取分类id
            String categoryId = subjectLabelBO.getCategoryId();
            SubjectMapping subjectMapping = new SubjectMapping();
            // 设置分类id
            subjectMapping.setCategoryId(Long.parseLong(categoryId));
            // 设置逻辑删除
            subjectMapping.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
            // 查询所有分类id对应的标签id
            List<SubjectMapping> mappingList = subjectMappingService.queryLabelId(subjectMapping);
            // 判断是否为空
            if (CollectionUtils.isEmpty(mappingList)) {
                return Collections.emptyList();
            }
            // 获取标签id
            List<Long> labelIds = mappingList.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
            // 对标签表进行批量查询
            List<SubjectLabel> subjectLabels = subjectLabelService.batchQueryById(labelIds);
            // 将SubjectLabel转换为BO
            List<SubjectLabelBO> collect = subjectLabels.stream().map(
                    subjectLabel -> {
                        // 创建一个SubjectLabelBO对象,用于存储转换后的数据
                        SubjectLabelBO subjectLabelBO1 = new SubjectLabelBO();
                        subjectLabelBO1.setId(subjectLabel.getId());
                        subjectLabelBO1.setLabelName(subjectLabel.getLabelName());
                        subjectLabelBO1.setSortNum(subjectLabel.getSortNum());
                        subjectLabelBO1.setCategoryId(subjectLabel.getCategoryId().toString());
                        return subjectLabelBO1;
                    }
            ).collect(Collectors.toList());
            return collect;
        }
    
    4.sun-club-infra
    1.service
    1.SubjectMappingService.java
        /**
         * 查询标签id
         * @param subjectMapping
         * @return
         */
        List<SubjectMapping> queryLabelId(SubjectMapping subjectMapping);
    
    2.SubjectLabelService.java
        /**
         * 批量查询标签
         * @param labelIds
         * @return
         */
        List<SubjectLabel> batchQueryById(List<Long> labelIds);
    
    3.SubjectMappingServiceImpl.java
        /**
         * 查询标签id
         * @param subjectMapping
         * @return
         */
        @Override
        public List<SubjectMapping> queryLabelId(SubjectMapping subjectMapping) {
            return this.subjectMappingDao.queryDistinctLabelId(subjectMapping);
        }
    
    4.SubjectLabelServiceImpl.java
        /**
         * 批量查询标签
         * @param labelIdList
         * @return
         */
        @Override
        public List<SubjectLabel> batchQueryById(List<Long> labelIdList) {
            if (!CollectionUtils.isEmpty(labelIdList)) {
                return Collections.emptyList();
            }
            return subjectLabelDao.batchQueryById(labelIdList);
        }
    
    2.mapper
    1.SubjectMappingDao.java
        /**
         * 查询标签id
         * @param subjectMapping
         * @return
         */
        List<SubjectMapping> queryDistinctLabelId(SubjectMapping subjectMapping);
    
    2.SubjectLabelDao.java
        /**
         * 批量查询标签
         * @param labelIdList
         * @return
         */
        List<SubjectLabel> batchQueryById(List<Long> labelIdList);
    
    3.SubjectMappingDao.xml
        <!--根据分类的id查询不重复的所有标签id-->
        <select id="queryDistinctLabelId" resultMap="SubjectMappingMap">
            select distinct label_id
            from subject_mapping
            <where>
                <if test="id != null">
                    and id = #{id, INTEGER}
                </if>
                <if test="subjectId != null">
                    and subject_id = #{subjectId, INTEGER}
                </if>
                <if test="categoryId != null">
                    and category_id = #{categoryId, INTEGER}
                </if>
                <if test="labelId != null">
                    and label_id = #{labelId, INTEGER}
                </if>
                <if test="createdBy != null and createdBy != ''">
                    and created_by = #{createdBy, VARCHAR}
                </if>
                <if test="createdTime != null">
                    and created_time = #{createdTime, TIMESTAMP}
                </if>
                <if test="updateBy != null and updateBy != ''">
                    and update_by = #{updateBy, VARCHAR}
                </if>
                <if test="updateTime != null">
                    and update_time = #{updateTime, TIMESTAMP}
                </if>
                <if test="isDeleted != null">
                    and is_deleted = #{isDeleted, INTEGER}
                </if>
            </where>
        </select>
    
    4.SubjectLabelDao.xml
        <!--根据标签id批量查询所有记录-->
        <select id="batchQueryById" resultMap="SubjectLabelMap">
            select id, label_name, sort_num, category_id, created_by, created_time, update_by, update_time, is_deleted
            from subject_label
            where id in
            <foreach collection="labelIdList" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </select>
    

    6.标签接口总体测试

    1.新增标签接口

    image-20240526161951349

    image-20240526161957036

    2.更新标签接口

    image-20240526162107145

    image-20240526162234821

    3.删除标签接口

    image-20240526162147401

    image-20240526162225511

    4.根据分类查询标签
    1.报错Parsing error was found in mapping #{categoryId, INTEGER}. Check syntax #{property|(expression), var1=value1, var2=value2, …}

    image-20240526163841120

    2.将SubjectMappingDao.xml里面指定类型时加上jdbcType属性即可

    image-20240526164511773

    3.再次请求,发现根据id批量查询的时候判断空的条件错了,将!去掉

    image-20240526164627922

    4.再次请求发现xml中的labelIdList参数没找到,原因是没有加@Param注解

    image-20240526164944888

    image-20240526165056361

    5.再次请求,成功查找到信息

    image-20240526165220356

    6.但是,在根据labelId进行批量查询的时候没有考虑逻辑删除,会将数据都查出来

    image-20240526165651472

    image-20240526165700075

    7.在SubjectLabelDao.xml的批量查询时加个条件即可

    image-20240526165853803

    image-20240526165954108

    作者:S-X-S

    物联沃分享整理
    物联沃-IOTWORD物联网 » 学习标签接口开发:完整CRUD开发流程详解

    发表回复