⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7197237024972144697 「大鹅coding」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

缘起

大家好呀,我是架构师业余草。

最近在做一个项目,需要新建20多张表

相信大多数同学应该和我一样,都是比较讨厌创建新表这个工作的,因为每创建一张表,都要去创建实体类、创建增删改查的接口、编写增删改查的SQL代码等等,把这些事情做完,2个小时也就过去了

我就在思考啊,每一张表,就要耗费两个小时,20多张表,那就是40多个小时,一周的时间就这样过去了。

思考

这谁受得了呀,所以我打算写一个工具,把这些代码都自动生成出来!

代码都自动生成出来

在连续爆肝了5个晚上之后,我做出了这款自动生成业务代码的工具!

自动生成业务代码

我把它放在了我的工具站上,大家可以访问这个域名直接使用https://utilsbox.cn/?app=bizcode

使用演示

下面给大家演示一下

假设我们现在创建一个商品表

首先填写表名和表的中文名称

然后我们添加商品表对应的字段,这些操作和我们日常使用的数据库工具差不多

把字段填写好了之后,点击“一键生成代码”

完成表信息编辑

高潮的地方来了

DB层、业务层、甚至是controller层的代码,工具都帮我们自动生成了!

来看下代码,建表sql、增删改查sql、表对应的实体类、DB层的接口类、业务层的实体类、业务层的接口类、业务接口的实现类、业务层实体类和db层实体类的转换器,最后是controller层,这些代码全都帮我们生成好了。

代码全都帮我们生成好了

这是什么概念呢

现在我们只需要把这些代码拷贝到项目里,简单设置一下类的引用,增删改查这些基本功能,就已经可以直接给前端去调用了。

CRUD

很多同学可能会问,如果是现有的数据表,再来这里添加一次感觉太麻烦了

这个问题我也遇到了,所以我做了一个识别建表SQL的功能,常见的数据库工具对于已经创建好的表,都提供建表语句的复制功能,只需要把建表SQL粘贴到这个文本框里。

点击“识别”按钮,这个SQL的信息会自动识别过来,这时候只需要把表的中文名称填写上去,点击“一键生成代码”,就可以马上得到这个表的业务代码。

业务代码生成器

通用性的思考

不知道大家觉得怎么样哈,如果只是我自己用,我觉着已经非常好了,但既然是开放出来给大家用,通用性肯定还是不够的。

因为现在看到的这一套自动生成的代码,可能只是适合我,但不同的人、不同的公司,它们项目结构的分层、代码的细节,都是不一样的

所以,我还开发了代码模版配置的功能

点击“代码模版配置”按钮,在这个弹窗里,我们可以新增、删除代码的分类。同样的,也可以新增、删除和编辑具体的代码模版。

代码模版

代码生成的原理

在说代码模版具体怎么配置之前,先给大家讲一下代码自动生成的原理

它由代码模版和动态参数组成,核心就是匹配 - 替换

首先,工具提供了很多动态参数,这些动态参数,对应的是我们填写的表名、字段名等等这些信息的原始值,或者处理过后的值。

然后,代码模版由用户自行定义,在代码的关键位置,插入动态参数,即可形成一份代码模版。

最后,工具通过匹配和替换动态参数,最终生成了代码。

理论上,不论什么语言,你都可以配置专属于你自己的代码模版。

举个简单的栗子:

我们配置了一份这样的代码模版,如下:

/**
* $table_desc$Model模型
* Created by 创建人 on $current_time$.
*/
public class $table_name_hump_A$Model extends ToString{
}

可以看到,模版里分别使用了$table_desc$(表中文名)$current_time$(当前时间)$table_name_hump_A$(表名转首字母大写驼峰) 这三个动态参数。

当我们设置 表名 = goods_order、表中文名 = 商品订单 时,代码生成的结果如下所示:

/**
* 商品订单Model模型
* Created by 创建人 on 2023-02-05 17:12:32.
*/
public class GoodsOrderModel extends ToString{
}

动态参数部分,全部替换成了我们输入的表信息。

最后希望这个项目对大家有用,之后我会开发更多有意思的项目。

由于这个项目都是晚上加班肝出来的,可能会存在一些BUG,发现了我会尽快修复的,也请大家多多包涵。

代码模版参考

以下是当前工具里默认的代码模版,你可以通过参考这些模版,举一反三,配置出专属于你自己的代码模版。

工具提供了模版的导入和导出功能,如果你创建好了一份非常满意的模版,可以导出,然后发给你的同事直接使用,这样它就不用重复创建了,你也可以忽悠你的同事来创建,然后分享给你。

建表SQL模版

CREATE TABLE `$table_name$` (
$create_table_field_list$
PRIMARY KEY (`$primary_key$`)
) ENGINE=$db_engine$ DEFAULT CHARSET=$db_encoded$;

实体类模版

主体

/**
* $table_desc$DTO模型
* Created by 创建人 on $current_time$.
*/
public class $table_name_hump_A$DO {
$member_param_list$
$get_set_method_list$
}

成员代码块 成员变量列表(member_param_list)

/** $field_comment$ */
private $field_type_java$ $field_name_hump$;

成员代码块 GetSet方法列表(get_set_method_list)

public $field_type_java$ get$field_name_hump_A$() {
return $field_name_hump$;
}

public void set$field_name_hump_A$($field_type_java$ $field_name_hump$) {
this.$field_name_hump$ = $field_name_hump$;
}

接口类模版(DB层)

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
* $table_desc$DB接口
* Created by 创建人 on $current_time$
*/
@Mapper
public interface $table_name_hump_A$DAO {

/**
* 添加
* @param data
* return 影响行数
*/
int insert($table_name_hump_A$DO data);

/**
* 修改
* @param data
* return 影响行数
*/
int update($table_name_hump_A$DO data);

/**
* 分页查询
* @param param
* return 结果列表
*/
List<$table_name_hump_A$DO> pageQuery(Map param);

/**
* 查询count
* @param param
* return count条数
*/
Long pageQueryCount(Map param);

/**
* 根据ID查询
* @param id
* return 结果DO对象
*/
$table_name_hump_A$DO queryById(@Param("$primary_key_hump$") $primary_key_type_java$ $primary_key_hump$);

/**
* 根据ID查询(带锁)
* @param id
* return 结果DO对象
*/
$table_name_hump_A$DO queryByIdLock(@Param("$primary_key_hump$") $primary_key_type_java$ $primary_key_hump$);
}

CRUD SQL模版

<?xml version="1.0" encoding="UTF-8"?>
<!-- $table_name_hump_A$Mapper.xml -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.$table_name_hump_A$DAO">

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO $table_name$($insert_field_name_list$)
VALUES ($insert_field_value_list$);
</insert>

<update id="update">
UPDATE $table_name$ SET
$update_field_list$
WHERE $primary_key$ = #{$primary_key_hump$};
</update>

<select id="pageQuery" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$
WHERE 1=1
$while_field_list$

ORDER BY $primary_key$ DESC

<if test="pageIndex != null and pageSize != null">
LIMIT #{offset},#{rows}
</if>
</select>

<select id="pageQueryCount" resultType="java.lang.Long">
SELECT COUNT(1) as total FROM $table_name$
WHERE 1=1
$while_field_list$
</select>

<select id="queryById" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$
WHERE $primary_key$ = #{$primary_key_hump$};
</select>

<select id="queryByIdLock" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$
WHERE $primary_key$ = #{$primary_key_hump$} FOR UPDATE;
</select>

</mapper>

模型转换器模版

不同层级间,可能会有不同的实体类,那么它们相互之间的数据转换,也是一个重复且浪费时间的工作,所以也可以配置一个模版。

import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
* $table_desc$模型转换器
* Created by 创建人 on $current_time$
*/
public class $table_name_hump_A$Converter {

/**
* dto转do
* @param source
* return do模型
*/
public static $table_name_hump_A$DO toDo($table_name_hump_A$DTO source){
$table_name_hump_A$DO target = new $table_name_hump_A$DO();
$converter_source_to_target_params_list$
return target;
}

/**
* do转dto
* @param source
* return dto模型
*/
public static $table_name_hump_A$DTO toDto($table_name_hump_A$DO source){
$table_name_hump_A$DTO target = new $table_name_hump_A$DTO();
$converter_source_to_target_params_list$
return target;
}

/**
* do list 转 dto
* @param data
* return list dto模型
*/
public static List<$table_name_hump_A$DTO> toDtoList(List<$table_name_hump_A$DO> data){
if (CollectionUtils.isEmpty(data)){
return null;
}
List<$table_name_hump_A$DTO> list = new ArrayList<>();
for ($table_name_hump_A$DO item : data){
list.add($table_name_hump_A$Converter.toDto(item));
}
return list;
}
}

成员代码块 模型转换器参数列表(converter_source_to_target_params_list)

target.set$field_name_hump_A$(source.get$field_name_hump_A$());

业务接口实现类模版

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
* $table_desc$业务实现
* Created by 创建人 on $current_time$
*/
@Service
public class $table_name_hump_A$ServiceImpl implements $table_name_hump_A$Service {

private static final Logger LOGGER = LoggerFactory.getLogger($table_name_hump_A$ServiceImpl.class);

@Resource
private $table_name_hump_A$DAO $table_name_hump$DAO;

@Override
public CommonResult create(JSONObject request) {

// 入参转成对应类型
CommonAssert.isNoEmptyObj(request, "请求参数不可空");
$table_name_hump_A$DTO dto = JSON.toJavaObject(request, $table_name_hump_A$DTO.class);

// 参数校验
$biz_check_required_params$

// 转成do模型
$table_name_hump_A$DO dataDo = $table_name_hump_A$Converter.toDo(dto);

// 落库
int count = $table_name_hump$DAO.insert(dataDo);
CommonAssert.isTrue(count > 0, "创建失败,请重试");

// 返回创建成功的ID数据
return new CommonResult(dataDo.get$primary_key_hump_A$());
}

@Override
public CommonResult modify(JSONObject request) {

// 入参转成对应类型
CommonAssert.isNoEmptyObj(request, "请求参数不可空");
$table_name_hump_A$DTO dto = JSON.toJavaObject(request, $table_name_hump_A$DTO.class);

// 参数校验
$biz_check_required_params$

// 转成do模型
$table_name_hump_A$DO dataDo = $table_name_hump_A$Converter.toDo(dto);

// 落库
int count = $table_name_hump$DAO.update(dataDo);
CommonAssert.greaterThanZero(count, "修改失败,请重试");

// 返回修改成功的ID数据
return new CommonResult(dataDo.get$primary_key_hump_A$());
}

@Override
public CommonResult pageQuery(JSONObject request) {

// 入参基本校验
CommonAssert.isNoEmptyObj(request, "请求参数不可空");

// 分页信息校验
PaginationDO pagination = PaginationDO.setRequestOffsetAndRows(request);
CommonAssert.isNoEmptyObj(pagination, "分页参数 $pageIndex、$pageSize 不可空");
CommonAssert.isTrue(pagination.getPageSize() <= 100, "单次查询条数不可超过100条");

// 取分页列表数据
List<$table_name_hump_A$DO> dbResult = $table_name_hump$DAO.pageQuery(request);

// 取count数据
long count = $table_name_hump$DAO.pageQueryCount(request);

// 空返回
if (CollectionUtils.isEmpty(dbResult)){
return new CommonResult(new PaginationResult(null, request, count));
}

// 模型转换
List<$table_name_hump_A$DTO> list = $table_name_hump_A$Converter.toDtoList(dbResult);

// 返回分页结果
return new CommonResult(new PaginationResult(list, request, count));
}

@Override
public CommonResult queryById(JSONObject request) {

// 取入参
CommonAssert.isNoEmptyObj(request, "请求参数不可空");

// 根据ID获取数据
$primary_key_type_java$ $primary_key_hump$ = request.get$primary_key_type_java$("$primary_key_hump$");
CommonAssert.isNoEmptyObj($primary_key_hump$, "参数错误,无法执行查询");
$table_name_hump_A$DO dbResult = $table_name_hump$DAO.queryById($primary_key_hump$);

// 未查询到结果,返回
if (null == dbResult){
return new CommonResult();
}

// 模型转换
$table_name_hump_A$DTO result = $table_name_hump_A$Converter.toDto(dbResult);

// 返回结果对象
return new CommonResult(result);
}
}

成员代码块 必填项业务校验(biz_check_required_params)

CommonAssert.$java_type_adapter_assert_method$(dto.get$field_name_hump_A$(), "$field_comment$不可空");

Controller模版

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
* $table_desc$HTTP请求控制器
* Created by 创建人 on $current_time$.
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/$table_name_hump$/")
public class $table_name_hump_A$Controller {

private static final Logger LOGGER = LoggerFactory.getLogger($table_name_hump_A$Controller.class);

@Resource
private $table_name_hump_A$Service $table_name_hump$Service;

/**
* 创建
* @param request
* @return
*/
@RequestMapping(value = "create.json", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Object create(@RequestBody JSONObject request){
return CommonTemplate.run(LOGGER, new CommonTemplate() {
@Override
protected Object business() {
return $table_name_hump$Service.create(request);
}
}, request);
}

/**
* 修改
* @param request
* @return
*/
@RequestMapping(value = "modify.json", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Object modify(@RequestBody JSONObject request){
return CommonTemplate.run(LOGGER, new CommonTemplate() {
@Override
protected Object business() {
return $table_name_hump$Service.modify(request);
}
}, request);
}

/**
* 分页查询
* @param request
* @return
*/
@RequestMapping(value = "pageQuery.json", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Object pageQuery(@RequestBody JSONObject request){
return CommonTemplate.run(LOGGER, new CommonTemplate() {
@Override
protected Object business() {
return $table_name_hump$Service.pageQuery(request);
}
}, request);
}

/**
* 通过主键查询
* @param request
* @return
*/
@RequestMapping(value = "queryById.json", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Object queryById(@RequestBody JSONObject request){
return CommonTemplate.run(LOGGER, new CommonTemplate() {
@Override
protected Object business() {
return $table_name_hump$Service.queryById(request);
}
}, request);
}
}

动态参数

原始表名 $table_name$

用户输入的表名,不做任何处理。

表名驼峰首字母小写 $table_name_hump$

用户输入的表名,经过驼峰处理。例如输入:goods_order ,输出:goodsOrder

表名驼峰首字母大写 $table_name_hump_A$

用户输入的表名,经过驼峰处理。例如输入:goods_order ,输出:GoodsOrder

原始字段名 $field_name$

用户输入的表字段名,不做任何处理。

字段名驼峰首字母小写 $field_name_hump$

用户输入的表字段名,经过驼峰处理。例如输入:order_number ,输出:orderNumber

字段名驼峰首字母大写 $field_name_hump_A$

用户输入的表字段名,经过驼峰处理。例如输入:order_number ,输出:OrderNumber

字段说明 $field_comment$

用户输入的表字段说明,不做任何处理。

字段数据类型(对应DB)$field_type_db$

用户选择的表字段类型,不做任何处理。

字段数据类型(对应Java)$field_type_java$

用户选择的表字段类型,会自动匹配对应的Java类型。例如输入:VARCHAR(),输出:String

主键字段名 $primary_key$

用户选择的主键字段,不做任何处理。例如用户定义的主键是id,那么输出就是:id

主键字段名驼峰首字母小写 $primary_key_hump$

用户选择的主键字段,经过驼峰处理。例如输入:order_number ,输出:orderNumber

主键字段名驼峰首字母大写 $primary_key_hump_A$

用户选择的主键字段,经过驼峰处理。例如输入:order_number ,输出:OrderNumber

主键字段数据类型(对应Java)$primary_key_type_java$

用户选择的主键字段类型,会自动匹配对应的Java类型。例如输入:VARCHAR(),输出:String

插入数据sql,字段名列表 $insert_field_name_list$

例如表中有三个字段:id(主键)、goods_name、price,输出:goods_name,price 。会自动排除主键 不仅插入数据时可用,任何需要排除ID,然后使用英文逗号拼接表所有字段信息的地方,都可以使用它

插入数据sql,字段值列表 $insert_field_value_list$

例如表中有三个字段:id(主键)、goods_name、price,输出:#{goodsName},#{price} 。会自动排除主键 不仅插入数据时可用,任何需要排除ID,然后使用英文逗号拼接表所有字段信息的地方,都可以使用它

修改数据sql,字段名列表 $update_field_list$

例如表中有三个字段:id(主键)、goods_name、price 输出(会自动换行,会携带以下缩进,会自动排除主键):

goods_name = #{goodsName},
price = #{price}

查询数据sql,字段名列表 $select_field_list$

例如表中有三个字段:id(主键)、goods_name、price,输出:id,goods_name,price 。带主键

whele字段条件sql,字段名列表 $whele_field_list$

例如表中有三个字段:id(主键)、goods_name、price, 输出(会自动换行,会携带以下缩进):

<if test="id != null">
AND id = #{id}
</if>
<if test="goodsName != null">
AND goods_name = #{goodsName}
</if>
<if test="price != null">
AND price = #{price}
</if>

创建表-表字段列表 $create_table_field_list$

例如表中有三个字段:id(自增主键)、goods_name、price 输出(会自动换行,会携带以下缩进):

`id` INT(11) NOT NULL AUTO_INCREMENT,
`goods_name` VARCHAR(128) NOT NULL DEFAULT 'NULL',
`price` DECIMAL(10,2) NOT NULL DEFAULT 'NULL'

当前时间 $current_time$

自动获取当前时间,格式:yyyy-MM-DD hh:mm:ss,示例值:2023-02-05 17:31:18

自动根据数据类型,匹配断言方法 $java_type_adapter_assert_method$

对于Java数据类型等于String的字段,使用isNoBlankStr方法,其他的类型都使用isNoEmptyObj方法 这是一个定制化很高的动态参数,可忽略它。

动态代码块

动态代码块由用户自行定义,代码块中也可以设置动态参数,目前仅提供4种明确的动态代码块

成员变量列表 $member_param_list$

例如表中有三个字段:id(主键)、goods_name、price

假设用户定义了如下代码块内容:

/** $field_comment$ */
private $field_type_java$ $field_name_hump$;

输出(会自动根据字段数量,累加输出自定义代码块内容):

/** id */
private Integer id;
/** 商品名称 */
private String goodsName;
/** 商品价格 */
private String price;

GetSet方法列表 $get_set_method_list$

例如表中有三个字段:id(主键)、goods_name、price

假设用户定义了如下代码块内容:

public $field_type_java$ get$field_name_hump_A$() {
return $field_name_hump$;
}

public void set$field_name_hump_A$($field_type_java$ $field_name_hump$) {
this.$field_name_hump$ = $field_name_hump$;
}

输出(会自动根据字段数量,累加输出自定义代码块内容):

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getGoodsName() {
return goodsName;
}

public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}

模型转换器参数列表 $converter_source_to_target_params_list$

例如表中有三个字段:id(主键)、goods_name、price

假设用户定义了如下代码块内容:

target.set$field_name_hump_A$(source.get$field_name_hump_A$());

输出(会自动根据字段数量,累加输出自定义代码块内容):

target.setId(source.getId());
target.setGoodsName(source.getGoodsName());
target.setPrice(source.getPrice());

必填项业务校验 $biz_check_required_params$

例如表中有三个字段:id(主键)、goods_name、price

假设用户定义了如下代码块内容:

CommonAssert.$java_type_adapter_assert_method$(dto.get$field_name_hump_A$(), "$field_comment$不可空");

输出(会自动根据字段数量,累加输出自定义代码块内容):

CommonAssert.isNoBlankStr(dto.getGoodsName(), "goodsName不可空");
CommonAssert.isNoBlankStr(dto.getPrice(), "price不可空");

以上思路希望大家都能喜欢,如有更好想法,欢迎评论区交流起来!

文章目录
  1. 1. 缘起
  2. 2. 使用演示
  3. 3. 通用性的思考
  4. 4. 代码生成的原理
  5. 5. 代码模版参考
    1. 5.0.1. 建表SQL模版
    2. 5.0.2. 实体类模版
    3. 5.0.3. 接口类模版(DB层)
    4. 5.0.4. CRUD SQL模版
    5. 5.0.5. 模型转换器模版
    6. 5.0.6. 业务接口实现类模版
    7. 5.0.7. Controller模版
  • 6. 动态参数
    1. 6.0.1. 原始表名 $table_name$
    2. 6.0.2. 表名驼峰首字母小写 $table_name_hump$
    3. 6.0.3. 表名驼峰首字母大写 $table_name_hump_A$
    4. 6.0.4. 原始字段名 $field_name$
    5. 6.0.5. 字段名驼峰首字母小写 $field_name_hump$
    6. 6.0.6. 字段名驼峰首字母大写 $field_name_hump_A$
    7. 6.0.7. 字段说明 $field_comment$
    8. 6.0.8. 字段数据类型(对应DB)$field_type_db$
    9. 6.0.9. 字段数据类型(对应Java)$field_type_java$
    10. 6.0.10. 主键字段名 $primary_key$
    11. 6.0.11. 主键字段名驼峰首字母小写 $primary_key_hump$
    12. 6.0.12. 主键字段名驼峰首字母大写 $primary_key_hump_A$
    13. 6.0.13. 主键字段数据类型(对应Java)$primary_key_type_java$
    14. 6.0.14. 插入数据sql,字段名列表 $insert_field_name_list$
    15. 6.0.15. 插入数据sql,字段值列表 $insert_field_value_list$
    16. 6.0.16. 修改数据sql,字段名列表 $update_field_list$
    17. 6.0.17. 查询数据sql,字段名列表 $select_field_list$
    18. 6.0.18. whele字段条件sql,字段名列表 $whele_field_list$
    19. 6.0.19. 创建表-表字段列表 $create_table_field_list$
    20. 6.0.20. 当前时间 $current_time$
    21. 6.0.21. 自动根据数据类型,匹配断言方法 $java_type_adapter_assert_method$
  • 7. 动态代码块
    1. 7.0.1. 成员变量列表 $member_param_list$
    2. 7.0.2. GetSet方法列表 $get_set_method_list$
    3. 7.0.3. 模型转换器参数列表 $converter_source_to_target_params_list$
    4. 7.0.4. 必填项业务校验 $biz_check_required_params$