0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

写一个比ChatGPT还牛的CRUD代码生成器

jf_ro2CN3Fa 来源:稀土掘金 2023-02-20 13:58 次阅读

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

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

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

思考

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

代码都自动生成出来

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

9418f320-b04f-11ed-bfe3-dac502259ad0.jpg

自动生成业务代码

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

使用演示

下面给大家演示一下

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

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

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

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

942cbaea-b04f-11ed-bfe3-dac502259ad0.jpg

完成表信息编辑

高潮的地方来了

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

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

943eb524-b04f-11ed-bfe3-dac502259ad0.gif

代码全都帮我们生成好了

这是什么概念呢

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

CRUD

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

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

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

94ecd6c2-b04f-11ed-bfe3-dac502259ad0.jpg

业务代码生成器

通用性的思考

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

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

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

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

95017136-b04f-11ed-bfe3-dac502259ad0.jpg

代码模版

代码生成的原理

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

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

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

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

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

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

举个简单的栗子:

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

/**
*$table_desc$Model模型
*Createdby创建人on$current_time$.
*/
publicclass$table_name_hump_A$ModelextendsToString{
}

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

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

/**
*商品订单Model模型
*Createdby创建人on2023-02-051732.
*/
publicclassGoodsOrderModelextendsToString{
}

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

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

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

代码模版参考

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

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

建表SQL模版

CREATETABLE`$table_name$`(
$create_table_field_list$
PRIMARYKEY(`$primary_key$`)
)ENGINE=$db_engine$DEFAULTCHARSET=$db_encoded$;

实体类模版

主体

/**
*$table_desc$DTO模型
*Createdby创建人on$current_time$.
*/
publicclass$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$;
}

publicvoidset$field_name_hump_A$($field_type_java$$field_name_hump$){
this.$field_name_hump$=$field_name_hump$;
}

接口类模版(DB层)

importorg.apache.ibatis.annotations.Mapper;
importorg.apache.ibatis.annotations.Param;

importjava.util.List;
importjava.util.Map;

/**
*$table_desc$DB接口
*Createdby创建人on$current_time$
*/
@Mapper
publicinterface$table_name_hump_A$DAO{

/**
*添加
*@paramdata
*return影响行数
*/
intinsert($table_name_hump_A$DOdata);

/**
*修改
*@paramdata
*return影响行数
*/
intupdate($table_name_hump_A$DOdata);

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

/**
*查询count
*@paramparam
*returncount条数
*/
LongpageQueryCount(Mapparam);

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

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

CRUD SQL模版


 




INSERTINTO$table_name$($insert_field_name_list$)
VALUES($insert_field_value_list$);



UPDATE$table_name$SET
$update_field_list$
WHERE$primary_key$=#{$primary_key_hump$};



SELECT$select_field_list$FROM$table_name$
WHERE1=1
$while_field_list$

ORDERBY$primary_key$DESC


LIMIT#{offset},#{rows}




SELECTCOUNT(1)astotalFROM$table_name$
WHERE1=1
$while_field_list$



SELECT$select_field_list$FROM$table_name$
WHERE$primary_key$=#{$primary_key_hump$};



SELECT$select_field_list$FROM$table_name$
WHERE$primary_key$=#{$primary_key_hump$}FORUPDATE;



模型转换器模版

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

importorg.springframework.util.CollectionUtils;

importjava.util.ArrayList;
importjava.util.List;

/**
*$table_desc$模型转换器
*Createdby创建人on$current_time$
*/
publicclass$table_name_hump_A$Converter{

/**
*dto转do
*@paramsource
*returndo模型
*/
publicstatic$table_name_hump_A$DOtoDo($table_name_hump_A$DTOsource){
$table_name_hump_A$DOtarget=new$table_name_hump_A$DO();
$converter_source_to_target_params_list$
returntarget;
}

/**
*do转dto
*@paramsource
*returndto模型
*/
publicstatic$table_name_hump_A$DTOtoDto($table_name_hump_A$DOsource){
$table_name_hump_A$DTOtarget=new$table_name_hump_A$DTO();
$converter_source_to_target_params_list$
returntarget;
}

/**
*dolist转dto
*@paramdata
*returnlistdto模型
*/
publicstaticList<$table_name_hump_A$DTO>toDtoList(List<$table_name_hump_A$DO>data){
if(CollectionUtils.isEmpty(data)){
returnnull;
}
List<$table_name_hump_A$DTO>list=newArrayList<>();
for($table_name_hump_A$DOitem:data){
list.add($table_name_hump_A$Converter.toDto(item));
}
returnlist;
}
}

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

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

业务接口实现类模版

importcom.alibaba.fastjson.JSONObject;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.stereotype.Service;

/**
*$table_desc$业务实现
*Createdby创建人on$current_time$
*/
@Service
publicclass$table_name_hump_A$ServiceImplimplements$table_name_hump_A$Service{

privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger($table_name_hump_A$ServiceImpl.class);

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

@Override
publicCommonResultcreate(JSONObjectrequest){

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

//参数校验
$biz_check_required_params$

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

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

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

@Override
publicCommonResultmodify(JSONObjectrequest){

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

//参数校验
$biz_check_required_params$

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

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

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

@Override
publicCommonResultpageQuery(JSONObjectrequest){

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

//分页信息校验
PaginationDOpagination=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数据
longcount=$table_name_hump$DAO.pageQueryCount(request);

//空返回
if(CollectionUtils.isEmpty(dbResult)){
returnnewCommonResult(newPaginationResult(null,request,count));
}

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

//返回分页结果
returnnewCommonResult(newPaginationResult(list,request,count));
}

@Override
publicCommonResultqueryById(JSONObjectrequest){

//取入参
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$DOdbResult=$table_name_hump$DAO.queryById($primary_key_hump$);

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

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

//返回结果对象
returnnewCommonResult(result);
}
}

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

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

Controller模版

importcom.alibaba.fastjson.JSONObject;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.web.bind.annotation.*;

importjavax.annotation.Resource;

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

privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger($table_name_hump_A$Controller.class);

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

/**
*创建
*@paramrequest
*@return
*/
@RequestMapping(value="create.json",method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
publicObjectcreate(@RequestBodyJSONObjectrequest){
returnCommonTemplate.run(LOGGER,newCommonTemplate(){
@Override
protectedObjectbusiness(){
return$table_name_hump$Service.create(request);
}
},request);
}

/**
*修改
*@paramrequest
*@return
*/
@RequestMapping(value="modify.json",method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
publicObjectmodify(@RequestBodyJSONObjectrequest){
returnCommonTemplate.run(LOGGER,newCommonTemplate(){
@Override
protectedObjectbusiness(){
return$table_name_hump$Service.modify(request);
}
},request);
}

/**
*分页查询
*@paramrequest
*@return
*/
@RequestMapping(value="pageQuery.json",method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
publicObjectpageQuery(@RequestBodyJSONObjectrequest){
returnCommonTemplate.run(LOGGER,newCommonTemplate(){
@Override
protectedObjectbusiness(){
return$table_name_hump$Service.pageQuery(request);
}
},request);
}

/**
*通过主键查询
*@paramrequest
*@return
*/
@RequestMapping(value="queryById.json",method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
publicObjectqueryById(@RequestBodyJSONObjectrequest){
returnCommonTemplate.run(LOGGER,newCommonTemplate(){
@Override
protectedObjectbusiness(){
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, 输出(会自动换行,会携带以下缩进):


ANDid=#{id}


ANDgoods_name=#{goodsName}


ANDprice=#{price}

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

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

`id`INT(11)NOTNULLAUTO_INCREMENT,
`goods_name`VARCHAR(128)NOTNULLDEFAULT'NULL',
`price`DECIMAL(10,2)NOTNULLDEFAULT'NULL'

当前时间 $current_time$

自动获取当前时间,格式:yyyy-MM-DD hhss,示例值:2023-02-05 1718

自动根据数据类型,匹配断言方法 $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*/
privateIntegerid;
/**商品名称*/
privateStringgoodsName;
/**商品价格*/
privateStringprice;

GetSet方法列表 $get_set_method_list$

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

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

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

publicvoidset$field_name_hump_A$($field_type_java$$field_name_hump$){
this.$field_name_hump$=$field_name_hump$;
}

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

publicIntegergetId(){
returnid;
}

publicvoidsetId(Integerid){
this.id=id;
}

publicStringgetGoodsName(){
returngoodsName;
}

publicvoidsetGoodsName(StringgoodsName){
this.goodsName=goodsName;
}

publicStringgetPrice(){
returnprice;
}

publicvoidsetPrice(Stringprice){
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不可空");






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 转换器
    +关注

    关注

    27

    文章

    8207

    浏览量

    141850
  • SQL
    SQL
    +关注

    关注

    1

    文章

    738

    浏览量

    43462
  • 代码生成器
    +关注

    关注

    0

    文章

    25

    浏览量

    8996

原文标题:非低代码,我写了一个比ChatGPT还牛的CRUD代码生成器

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    应用程序生成器

    我在生成应用程序的时候,右键点击程序生成规范,点击新建,只有源代码发布和web两项,没有应用程序,安装程序以及DLL和ZIP等,是因为我没有应用程序生成器的问题吗?那去哪可以整
    发表于 09-04 09:19

    求LabVIEW C代码生成器2014版,谢谢

    虚心请教。本人使用的是NI Labview2014版,想要把VI转换成C代码,目前在官网中找到的LabVIEW C代码生成器最高版本是2013版,请问有没有LabVIEW C代码
    发表于 09-10 16:26

    AllJoyn C++代码生成器

    AllJoyn 团队非常激动地向广大开发商宣布,款新工具已经问世——代码生成器。如果您拥有定义的 AllJoyn 服务接口规范,即可通过运行此代码
    发表于 09-19 18:11

    怎么使用代码生成器进行外部唤醒源配置

    大家好,我正在使用板, 5.2.1我想配置WKUP [2]引脚号:PA [1]作为外部唤醒源,我没有找到使用代码生成器唤醒的任何回调函数代码生成,我期待应该有
    发表于 11-28 10:31

    介绍下ABOV提供的代码生成器

    的开发,下面介绍下ABOV提供的代码生成器,丝毫不输CUBEMX,且ABOV单片机基本都支持keil开发环境。。2. ABOV的代码生成器
    发表于 11-19 08:06

    python生成器

    了,但是函数并没有结束请看如下代码,我定义了 generator_factory 函数,当我执行 gen = generator_factory() 时,gen 就是
    发表于 02-24 15:56

    利用LabVIEW代码生成器简化应用项目

    利用LabVIEW代码生成器简化应用项目
    发表于 02-26 14:01 24次下载
    利用LabVIEW<b class='flag-5'>代码</b><b class='flag-5'>生成器</b>简化应用项目

    LED段码生成器

    本文提供的LED段码生成器,希望对你的学习有所帮助!
    发表于 06-03 15:19 96次下载

    代码生成器的应用

    jeesite框架代码生成器,可以很方便的生成代码,挺不错的。
    发表于 01-14 15:19 0次下载

    数码管代码生成器

    数码管代码生成器,迅速生成数码管的相应代码
    发表于 04-25 10:54 40次下载

    STM32库函数代码自动生成器V1.2

    stm32库函数代码自动生成器是STM32学习的小工具。 stm32库函数代码自动生成器可以根据你的配置生成相应的库函数
    发表于 06-17 17:55 0次下载

    STM32库函数代码自动生成器正式版

    STM32库函数代码自动生成器正式版,感兴趣的可以看看。
    发表于 07-13 16:55 0次下载

    STM32库函数代码自动生成器正式版

    STM32库函数代码自动生成器正式版 STM32库函数代码自动生成器正式版
    发表于 07-25 18:52 0次下载

    python生成器是什么

    python生成器 1. 什么是生成器生成器(英文名 Generator ),是一个可以像迭代器那样使用for循环来获取元素的函数。 生成器的出现(Python 2.2 +),实现
    的头像 发表于 02-24 15:53 3084次阅读

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目
    发表于 01-11 19:00 0次下载
    将使用<b class='flag-5'>代码</b><b class='flag-5'>生成器</b><b class='flag-5'>生成</b>的项目移植到与智能配置器一起使用的项目