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

本文在

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 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 implements CustomerService {

    private final CustomerQualificationService customerQualificationService;

    //region 自定义的方法块

    /**

    * 按关键字查询客户

    * @param keyWord

    * @return

    */

    @SneakyThrows

    public List getCustomerListByKeyWord(String keyWord){

        return baseMapper.getCustomerListByKeyWord(keyWord);

    }

    /**

    * 查询客户列表

    * @param customerRVO

    * @return

    */

    @SneakyThrows

    public List 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 implements CustomerQualificationService {

    //region 自定义的方法块

    /**

    * 保存客户资质

    * @param customerVO

    * @return

    */

    public boolean saveCustomerQualification(CustomerVO customerVO){

        //先删除再添加

        this.deleteByCustomerId(customerVO.getId());

        //保存客户资质表

        List 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

   

       

       

       

           

           

       

   

   

        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

   

   

   

CustomerQualificationMapper.xml

   

       

       

   

   

   

DELETE FROM cst_customer_qualification WHERE customer_id = #{customerId}

你可能感兴趣的:(pigx开发示范之旅:客户模块开发)