美文网首页
pigx开发示范之旅:客户模块开发

pigx开发示范之旅:客户模块开发

作者: 技术帮 | 来源:发表于2019-06-05 11:03 被阅读0次

    本文在

    https://www.jianshu.com/p/d614ac030e7c: 在pigx-visual之外构建微服务

    https://www.jianshu.com/p/353793d668ab: pigx数据库操作示例

    https://www.jianshu.com/p/bd81ad89035a:pigx开发示范之旅:项目规划

    基础上开始,本模块主要示范多对多的开发。

    一、用 代码生成工具 生成客户模块相关表文件

    客户模块涉及三张表,cst_customer、bas_qualification、cst_customer_qualification

    其中:cst_customer、cst_customer_qualification属于customer模块,bas_qualification属于base模块,它们分别对应目录结构中的customer及base目录。

    生成三张表的文件后,将生成的后端代码复制到相应目录,注意还有mpper.xml文件。

    二、修改 实体 类

    由于表的主键采用UUID,所以需要修改实体类的Id属性,如下

    原来为:

    @TableId

    private Stringid;

    改为:

    @TableId(value="id",type=IdType.UUID)

    private Stringid;

    这里只修改customer、qualification实体

    三、客户模块功能设计

    实现客户的增删改查

    增加实现客户和客户的资质一起增加,即客户表和客户的资质表一起保存,增加是时,如果客户id、客户名称已存在,则提示:客户已存在,保存失败!

    删除实现客户和客户的资质一起删除

    修改实现客户和客户的资质一起修改,如果修改后的客户名称已存在,则提示:客户名称重复,更新失败!

    查询实现按关键字匹配客户名称、资质名称,同时资质表在前端作为下拉查询条件匹配资质名称

    四、值对象设计

    从需求来看,客户对象包含客户资质对象,在customer实体中只有cst_customer表的字段属性,由于customer实体是自动生成的,考虑需求变化对表结构的影响,因此不在customer实体中添加对客户资质对象的引用,单独建立一个值对象CustomerVO来负责与前端交互,增删改查操作的对象都将是CustomerVO。

    package com.mycompany.mydemo.customer.vo;

    import com.mycompany.mydemo.base.entity.Qualification;

    import lombok.Data;

    import java.io.Serializable;

    import java.util.List;

    @Data

    public class CustomerVO  implements Serializable {

        private static final long serialVersionUID = 1L;

        /**

        * 主键

        */

        private String id;

        /**

        * 客户名称

        */

        private String name;

        /**

        * 资质列表

        */

        private List<Qualification> qualificationList;

    }

    在客户查询这个需求上,有两个查询条件,一个是关键字、另一个是资质名称,在前端会以对象的形式传到后端,因此后端需要一个对象接收,为保持单一性,特建立一个CustomerRVO的类来接收前端的查询条件数据。

    package com.mycompany.mydemo.customer.vo;

    import lombok.Data;

    import java.io.Serializable;

    /**

    * 查询客户的查询条件VO

    */

    @Data

    public class CustomerRVO  implements Serializable {

        private static final long serialVersionUID = 1L;

        /**

        * 关键字

        */

        private String keyWord;

        /**

        * 资质名称

        */

        private String qualificationName;

    }

    五、Service与Controller设计

    在生成的代码中,已有三张表的Service、Controller,但在项目中,从前端操作来看,只会有客户及资质的概念,而客户资质属于客户,因此,对三个Service、Controller的职责做如下界定:

    1:接入前端只有CustomerController 和 QualificationController,它们各自负责客户及资质的交互,CustomerQualificationController删除掉。

    2:对于CustomerQualificationService,只负责关系表的增删改的操作,并且是批量操作,这些操作由CustomerService调用。

    3:Controller只负责中转请求和返回Service执行的结果(包括异常),每一个请求后调用Service的一个方法,Service负责业务规则、业务逻辑的检查、计算及抛出异常,特别注意:如果抛出自定义异常,这个异常类必须继承RuntimeException,不能继承于Exception,否则Controller捕获不到异常,无法将异常消息以R对象的形式返回给前端。

    CustomerService示例代码

    package com.mycompany.mydemo.customer.service.impl;

    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

    import com.mycompany.common.exception.BussinessException;

    import com.mycompany.mydemo.customer.entity.Customer;

    import com.mycompany.mydemo.customer.mapper.CustomerMapper;

    import com.mycompany.mydemo.customer.service.CustomerService;

    import com.mycompany.mydemo.customer.service.CustomerQualificationService;

    import com.mycompany.mydemo.customer.vo.CustomerRVO;

    import com.mycompany.mydemo.customer.vo.CustomerVO;

    import lombok.AllArgsConstructor;

    import lombok.SneakyThrows;

    import org.springframework.beans.BeanUtils;

    import org.springframework.stereotype.Service;

    import org.springframework.transaction.annotation.Transactional;

    import java.io.Serializable;

    import java.util.List;

    /**

    *

    *

    * @author pigx code generator

    * @date 2019-05-29 14:41:33

    */

    @Service

    @AllArgsConstructor

    public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {

        private final CustomerQualificationService customerQualificationService;

        //region 自定义的方法块

        /**

        * 按关键字查询客户

        * @param keyWord

        * @return

        */

        @SneakyThrows

        public List<CustomerVO> getCustomerListByKeyWord(String keyWord){

            return baseMapper.getCustomerListByKeyWord(keyWord);

        }

        /**

        * 查询客户列表

        * @param customerRVO

        * @return

        */

        @SneakyThrows

        public List<CustomerVO> getCustomerList(CustomerRVO customerRVO){

            return baseMapper.getCustomerList(customerRVO);

        }

        /**

        * 新增客户及客户资质

        * @param customerVO

        * @return

        */

        @SneakyThrows

        @Transactional(rollbackFor = Exception.class)

        public boolean addCustomer(CustomerVO customerVO) {

            if (baseMapper.selectById(customerVO.getId()) != null){

                throw new BussinessException("客户已存在,保存失败!");

            }

            Customer customer = new Customer();

            //复制属性值

            BeanUtils.copyProperties(customerVO, customer);

            baseMapper.insert(customer);

            //保存客户资质表

            return customerQualificationService.saveCustomerQualification(customerVO);

        }

        /**

        * 更新客户及客户资质

        * @param customerVO

        * @return

        */

        @SneakyThrows

        @Transactional(rollbackFor = Exception.class)

        public boolean updateCustomer(CustomerVO customerVO) {

            Customer customer = baseMapper.selectById(customerVO.getId());

            if (customer == null) {

                throw new BussinessException("客户不存在,更新失败!");

            }

            //复制属性值

            BeanUtils.copyProperties(customerVO, customer);

            baseMapper.updateById(customer);

            //保存客户资质表

            return customerQualificationService.saveCustomerQualification(customerVO);

        }

        //endregion

        //region 重载基类的方法块

        /**

        * 按 Id 删除客户及客户资质

        * @param id

        * @return

        */

        @Override

        @SneakyThrows

        @Transactional(rollbackFor = Exception.class)

        public boolean removeById(Serializable id){

            //删除客户资质

            customerQualificationService.deleteByCustomerId(id);

            return super.removeById(id);

        }

        //endregion

    }

    CustomerQualificationService示例

    package com.mycompany.mydemo.customer.service.impl;

    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

    import com.mycompany.mydemo.customer.entity.CustomerQualification;

    import com.mycompany.mydemo.customer.mapper.CustomerQualificationMapper;

    import com.mycompany.mydemo.customer.service.CustomerQualificationService;

    import com.mycompany.mydemo.customer.vo.CustomerVO;

    import org.springframework.stereotype.Service;

    import java.io.Serializable;

    import java.util.List;

    import java.util.stream.Collectors;

    /**

    *

    *

    * @author pigx code generator

    * @date 2019-05-29 15:02:09

    */

    @Service

    public class CustomerQualificationServiceImpl extends ServiceImpl<CustomerQualificationMapper, CustomerQualification> implements CustomerQualificationService {

        //region 自定义的方法块

        /**

        * 保存客户资质

        * @param customerVO

        * @return

        */

        public boolean saveCustomerQualification(CustomerVO customerVO){

            //先删除再添加

            this.deleteByCustomerId(customerVO.getId());

            //保存客户资质表

            List<CustomerQualification> customerQualificationList = customerVO.getQualificationList()

                    .stream().map(qualification -> {

                        CustomerQualification customerQualification = new CustomerQualification();

                        customerQualification.setCustomerId(customerVO.getId());

                        customerQualification.setQualificationId(qualification.getId());

                        return customerQualification;

                    }).collect(Collectors.toList());

            return this.saveBatch(customerQualificationList);

        }

        /**

        * 按客户Id 删除客户资质

        * @param customerId

        * @return

        */

        public boolean deleteByCustomerId(Serializable customerId){

            return baseMapper.deleteByCustomerId(customerId);

        }

        //endregion

    }

    六、Mapper映射

    CustomerMapper.xml

    <?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="com.mycompany.mydemo.customer.mapper.CustomerMapper">

        <resultMap id="customerVoMap" type="com.mycompany.mydemo.customer.vo.CustomerVO">

            <id property="id" column="id"/>

            <result property="name" column="name"/>

            <collection property="qualificationList" ofType="com.mycompany.mydemo.base.entity.Qualification">

                <id property="id" column="qualification_id"/>

                <result property="name" column="qualification_name"/>

            </collection>

        </resultMap>

        <sql id="customerQualificationSql">

            select ta.id, ta.name, tc.id as qualification_id, tc.name as qualification_name

            from cst_customer as ta

            left join cst_customer_qualification as tb on ta.id = tb.customer_id

            left join bas_qualification as tc on tb.qualification_id = tc.id

        </sql>

        <select id="getCustomerListByKeyWord" resultMap="customerVoMap">

            <include refid="customerQualificationSql"/>

            where ta.name LIKE CONCAT('%',#{keyWord},'%') or tc.name LIKE CONCAT('%',#{keyWord},'%')

        </select>

        <select id="getCustomerList" resultMap="customerVoMap">

            <include refid="customerQualificationSql"/>

            <where>

                <if test="query.keyWord != null and query.keyWord != ''">

                    and ta.name LIKE CONCAT('%',#{query.keyWord},'%') or tc.name LIKE CONCAT('%',#{query.keyWord},'%')

                </if>

                <if test="query.qualificationName != null and query.qualificationName != ''">

                    and tc.name = #{query.qualificationName}

                </if>

            </where>

        </select>

    </mapper>

    CustomerQualificationMapper.xml

    <?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="com.mycompany.mydemo.customer.mapper.CustomerQualificationMapper">

        <resultMap id="customerQualificationMap" type="com.mycompany.mydemo.customer.entity.CustomerQualification">

            <result property="customerId" column="customer_id"/>

            <result property="qualificationId" column="qualification_id"/>

        </resultMap>

        <!--根据客户Id删除该客户的资质关系-->

        <delete id="deleteByCustomerId">

    DELETE FROM cst_customer_qualification WHERE customer_id = #{customerId}

    </delete>

    </mapper>

    相关文章

      网友评论

          本文标题:pigx开发示范之旅:客户模块开发

          本文链接:https://www.haomeiwen.com/subject/rjbrxctx.html