最近在做一個(gè)項(xiàng)目,需要新建20多張表
相信大多數(shù)同學(xué)應(yīng)該和我一樣,都是比較討厭創(chuàng)建新表這個(gè)工作的,因?yàn)槊縿?chuàng)建一張表,都要去創(chuàng)建實(shí)體類、創(chuàng)建增刪改查的接口、編寫增刪改查的SQL代碼等等,把這些事情做完,2個(gè)小時(shí)也就過去了
我就在思考啊,每一張表,就要耗費(fèi)兩個(gè)小時(shí),20多張表,那就是40多個(gè)小時(shí),一周的時(shí)間就這樣過去了。
思考
這誰(shuí)受得了呀,所以我打算寫一個(gè)工具,把這些代碼都自動(dòng)生成出來!
代碼都自動(dòng)生成出來
在連續(xù)爆肝了5個(gè)晚上之后,我做出了這款自動(dòng)生成業(yè)務(wù)代碼的工具!
自動(dòng)生成業(yè)務(wù)代碼
我把它放在了我的工具站上,大家可以訪問這個(gè)域名直接使用https://utilsbox.cn/?app=bizcode
使用演示
下面給大家演示一下
假設(shè)我們現(xiàn)在創(chuàng)建一個(gè)商品表
首先填寫表名和表的中文名稱
然后我們添加商品表對(duì)應(yīng)的字段,這些操作和我們?nèi)粘J褂玫臄?shù)據(jù)庫(kù)工具差不多
把字段填寫好了之后,點(diǎn)擊“一鍵生成代碼”
完成表信息編輯
高潮的地方來了
DB層、業(yè)務(wù)層、甚至是controller層的代碼,工具都幫我們自動(dòng)生成了!
來看下代碼,建表sql、增刪改查sql、表對(duì)應(yīng)的實(shí)體類、DB層的接口類、業(yè)務(wù)層的實(shí)體類、業(yè)務(wù)層的接口類、業(yè)務(wù)接口的實(shí)現(xiàn)類、業(yè)務(wù)層實(shí)體類和db層實(shí)體類的轉(zhuǎn)換器,最后是controller層,這些代碼全都幫我們生成好了。
代碼全都幫我們生成好了
這是什么概念呢
現(xiàn)在我們只需要把這些代碼拷貝到項(xiàng)目里,簡(jiǎn)單設(shè)置一下類的引用,增刪改查這些基本功能,就已經(jīng)可以直接給前端去調(diào)用了。
CRUD
很多同學(xué)可能會(huì)問,如果是現(xiàn)有的數(shù)據(jù)表,再來這里添加一次感覺太麻煩了
這個(gè)問題我也遇到了,所以我做了一個(gè)識(shí)別建表SQL的功能,常見的數(shù)據(jù)庫(kù)工具對(duì)于已經(jīng)創(chuàng)建好的表,都提供建表語(yǔ)句的復(fù)制功能,只需要把建表SQL粘貼到這個(gè)文本框里。
點(diǎn)擊“識(shí)別”按鈕,這個(gè)SQL的信息會(huì)自動(dòng)識(shí)別過來,這時(shí)候只需要把表的中文名稱填寫上去,點(diǎn)擊“一鍵生成代碼”,就可以馬上得到這個(gè)表的業(yè)務(wù)代碼。
業(yè)務(wù)代碼生成器
通用性的思考
不知道大家覺得怎么樣哈,如果只是我自己用,我覺著已經(jīng)非常好了,但既然是開放出來給大家用,通用性肯定還是不夠的。
因?yàn)楝F(xiàn)在看到的這一套自動(dòng)生成的代碼,可能只是適合我,但不同的人、不同的公司,它們項(xiàng)目結(jié)構(gòu)的分層、代碼的細(xì)節(jié),都是不一樣的
所以,我還開發(fā)了代碼模版配置的功能
點(diǎn)擊“代碼模版配置”按鈕,在這個(gè)彈窗里,我們可以新增、刪除代碼的分類。同樣的,也可以新增、刪除和編輯具體的代碼模版。
代碼模版
代碼生成的原理
在說代碼模版具體怎么配置之前,先給大家講一下代碼自動(dòng)生成的原理
它由代碼模版和動(dòng)態(tài)參數(shù)組成,核心就是匹配 - 替換
首先,工具提供了很多動(dòng)態(tài)參數(shù),這些動(dòng)態(tài)參數(shù),對(duì)應(yīng)的是我們填寫的表名、字段名等等這些信息的原始值,或者處理過后的值。
然后,代碼模版由用戶自行定義,在代碼的關(guān)鍵位置,插入動(dòng)態(tài)參數(shù),即可形成一份代碼模版。
最后,工具通過匹配和替換動(dòng)態(tài)參數(shù),最終生成了代碼。
理論上,不論什么語(yǔ)言,你都可以配置專屬于你自己的代碼模版。
舉個(gè)簡(jiǎn)單的栗子:
我們配置了一份這樣的代碼模版,如下:
/** *$table_desc$Model模型 *Createdby創(chuàng)建人on$current_time$. */ publicclass$table_name_hump_A$ModelextendsToString{ }
可以看到,模版里分別使用了$table_desc$(表中文名)、$current_time$(當(dāng)前時(shí)間)、$table_name_hump_A$(表名轉(zhuǎn)首字母大寫駝峰) 這三個(gè)動(dòng)態(tài)參數(shù)。
當(dāng)我們?cè)O(shè)置 表名 = goods_order、表中文名 = 商品訂單 時(shí),代碼生成的結(jié)果如下所示:
/** *商品訂單Model模型 *Createdby創(chuàng)建人on2023-02-051732. */ publicclassGoodsOrderModelextendsToString{ }
動(dòng)態(tài)參數(shù)部分,全部替換成了我們輸入的表信息。
最后希望這個(gè)項(xiàng)目對(duì)大家有用,之后我會(huì)開發(fā)更多有意思的項(xiàng)目。
由于這個(gè)項(xiàng)目都是晚上加班肝出來的,可能會(huì)存在一些BUG,發(fā)現(xiàn)了我會(huì)盡快修復(fù)的,也請(qǐng)大家多多包涵。
代碼模版參考
以下是當(dāng)前工具里默認(rèn)的代碼模版,你可以通過參考這些模版,舉一反三,配置出專屬于你自己的代碼模版。
工具提供了模版的導(dǎo)入和導(dǎo)出功能,如果你創(chuàng)建好了一份非常滿意的模版,可以導(dǎo)出,然后發(fā)給你的同事直接使用,這樣它就不用重復(fù)創(chuàng)建了,你也可以忽悠你的同事來創(chuàng)建,然后分享給你。
建表SQL模版
CREATETABLE`$table_name$`( $create_table_field_list$ PRIMARYKEY(`$primary_key$`) )ENGINE=$db_engine$DEFAULTCHARSET=$db_encoded$;
實(shí)體類模版
主體
/** *$table_desc$DTO模型 *Createdby創(chuàng)建人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創(chuàng)建人on$current_time$ */ @Mapper publicinterface$table_name_hump_A$DAO{ /** *添加 *@paramdata *return影響行數(shù) */ intinsert($table_name_hump_A$DOdata); /** *修改 *@paramdata *return影響行數(shù) */ intupdate($table_name_hump_A$DOdata); /** *分頁(yè)查詢 *@paramparam *return結(jié)果列表 */ List<$table_name_hump_A$DO>pageQuery(Mapparam); /** *查詢count *@paramparam *returncount條數(shù) */ LongpageQueryCount(Mapparam); /** *根據(jù)ID查詢 *@paramid *return結(jié)果DO對(duì)象 */ $table_name_hump_A$DOqueryById(@Param("$primary_key_hump$")$primary_key_type_java$$primary_key_hump$); /** *根據(jù)ID查詢(帶鎖) *@paramid *return結(jié)果DO對(duì)象 */ $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$};
模型轉(zhuǎn)換器模版
不同層級(jí)間,可能會(huì)有不同的實(shí)體類,那么它們相互之間的數(shù)據(jù)轉(zhuǎn)換,也是一個(gè)重復(fù)且浪費(fèi)時(shí)間的工作,所以也可以配置一個(gè)模版。
importorg.springframework.util.CollectionUtils; importjava.util.ArrayList; importjava.util.List; /** *$table_desc$模型轉(zhuǎn)換器 *Createdby創(chuàng)建人on$current_time$ */ publicclass$table_name_hump_A$Converter{ /** *dto轉(zhuǎn)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轉(zhuǎn)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轉(zhuǎn)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; } }
成員代碼塊 模型轉(zhuǎn)換器參數(shù)列表(converter_source_to_target_params_list)
target.set$field_name_hump_A$(source.get$field_name_hump_A$());
業(yè)務(wù)接口實(shí)現(xiàn)類模版
importcom.alibaba.fastjson.JSONObject; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.stereotype.Service; /** *$table_desc$業(yè)務(wù)實(shí)現(xiàn) *Createdby創(chuàng)建人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){ //入?yún)⑥D(zhuǎn)成對(duì)應(yīng)類型 CommonAssert.isNoEmptyObj(request,"請(qǐng)求參數(shù)不可空"); $table_name_hump_A$DTOdto=JSON.toJavaObject(request,$table_name_hump_A$DTO.class); //參數(shù)校驗(yàn) $biz_check_required_params$ //轉(zhuǎn)成do模型 $table_name_hump_A$DOdataDo=$table_name_hump_A$Converter.toDo(dto); //落庫(kù) intcount=$table_name_hump$DAO.insert(dataDo); CommonAssert.isTrue(count>0,"創(chuàng)建失敗,請(qǐng)重試"); //返回創(chuàng)建成功的ID數(shù)據(jù) returnnewCommonResult(dataDo.get$primary_key_hump_A$()); } @Override publicCommonResultmodify(JSONObjectrequest){ //入?yún)⑥D(zhuǎn)成對(duì)應(yīng)類型 CommonAssert.isNoEmptyObj(request,"請(qǐng)求參數(shù)不可空"); $table_name_hump_A$DTOdto=JSON.toJavaObject(request,$table_name_hump_A$DTO.class); //參數(shù)校驗(yàn) $biz_check_required_params$ //轉(zhuǎn)成do模型 $table_name_hump_A$DOdataDo=$table_name_hump_A$Converter.toDo(dto); //落庫(kù) intcount=$table_name_hump$DAO.update(dataDo); CommonAssert.greaterThanZero(count,"修改失敗,請(qǐng)重試"); //返回修改成功的ID數(shù)據(jù) returnnewCommonResult(dataDo.get$primary_key_hump_A$()); } @Override publicCommonResultpageQuery(JSONObjectrequest){ //入?yún)⒒拘r?yàn) CommonAssert.isNoEmptyObj(request,"請(qǐng)求參數(shù)不可空"); //分頁(yè)信息校驗(yàn) PaginationDOpagination=PaginationDO.setRequestOffsetAndRows(request); CommonAssert.isNoEmptyObj(pagination,"分頁(yè)參數(shù)$pageIndex、$pageSize不可空"); CommonAssert.isTrue(pagination.getPageSize()<=?100,?"單次查詢條數(shù)不可超過100條"); ????????//?取分頁(yè)列表數(shù)據(jù) ????????List<$table_name_hump_A$DO>dbResult=$table_name_hump$DAO.pageQuery(request); //取count數(shù)據(jù) longcount=$table_name_hump$DAO.pageQueryCount(request); //空返回 if(CollectionUtils.isEmpty(dbResult)){ returnnewCommonResult(newPaginationResult(null,request,count)); } //模型轉(zhuǎn)換 List<$table_name_hump_A$DTO>list=$table_name_hump_A$Converter.toDtoList(dbResult); //返回分頁(yè)結(jié)果 returnnewCommonResult(newPaginationResult(list,request,count)); } @Override publicCommonResultqueryById(JSONObjectrequest){ //取入?yún)?CommonAssert.isNoEmptyObj(request,"請(qǐng)求參數(shù)不可空"); //根據(jù)ID獲取數(shù)據(jù) $primary_key_type_java$$primary_key_hump$=request.get$primary_key_type_java$("$primary_key_hump$"); CommonAssert.isNoEmptyObj($primary_key_hump$,"參數(shù)錯(cuò)誤,無法執(zhí)行查詢"); $table_name_hump_A$DOdbResult=$table_name_hump$DAO.queryById($primary_key_hump$); //未查詢到結(jié)果,返回 if(null==dbResult){ returnnewCommonResult(); } //模型轉(zhuǎn)換 $table_name_hump_A$DTOresult=$table_name_hump_A$Converter.toDto(dbResult); //返回結(jié)果對(duì)象 returnnewCommonResult(result); } }
成員代碼塊 必填項(xiàng)業(yè)務(wù)校驗(yàn)(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請(qǐng)求控制器 *Createdby創(chuàng)建人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; /** *創(chuàng)建 *@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); } /** *分頁(yè)查詢 *@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); } }
動(dòng)態(tài)參數(shù)
原始表名 $table_name$
?
用戶輸入的表名,不做任何處理。
?
表名駝峰首字母小寫 $table_name_hump$
?
用戶輸入的表名,經(jīng)過駝峰處理。例如輸入:goods_order ,輸出:goodsOrder
?
表名駝峰首字母大寫 $table_name_hump_A$
?
用戶輸入的表名,經(jīng)過駝峰處理。例如輸入:goods_order ,輸出:GoodsOrder
?
原始字段名 $field_name$
?
用戶輸入的表字段名,不做任何處理。
?
字段名駝峰首字母小寫 $field_name_hump$
?
用戶輸入的表字段名,經(jīng)過駝峰處理。例如輸入:order_number ,輸出:orderNumber
?
字段名駝峰首字母大寫 $field_name_hump_A$
?
用戶輸入的表字段名,經(jīng)過駝峰處理。例如輸入:order_number ,輸出:OrderNumber
?
字段說明 $field_comment$
?
用戶輸入的表字段說明,不做任何處理。
?
字段數(shù)據(jù)類型(對(duì)應(yīng)DB)$field_type_db$
?
用戶選擇的表字段類型,不做任何處理。
?
字段數(shù)據(jù)類型(對(duì)應(yīng)Java)$field_type_java$
?
用戶選擇的表字段類型,會(huì)自動(dòng)匹配對(duì)應(yīng)的Java類型。例如輸入:VARCHAR(),輸出:String
?
主鍵字段名 $primary_key$
?
用戶選擇的主鍵字段,不做任何處理。例如用戶定義的主鍵是id,那么輸出就是:id
?
主鍵字段名駝峰首字母小寫 $primary_key_hump$
?
用戶選擇的主鍵字段,經(jīng)過駝峰處理。例如輸入:order_number ,輸出:orderNumber
?
主鍵字段名駝峰首字母大寫 $primary_key_hump_A$
?
用戶選擇的主鍵字段,經(jīng)過駝峰處理。例如輸入:order_number ,輸出:OrderNumber
?
主鍵字段數(shù)據(jù)類型(對(duì)應(yīng)Java)$primary_key_type_java$
?
用戶選擇的主鍵字段類型,會(huì)自動(dòng)匹配對(duì)應(yīng)的Java類型。例如輸入:VARCHAR(),輸出:String
?
插入數(shù)據(jù)sql,字段名列表 $insert_field_name_list$
?
例如表中有三個(gè)字段:id(主鍵)、goods_name、price,輸出:goods_name,price 。會(huì)自動(dòng)排除主鍵 不僅插入數(shù)據(jù)時(shí)可用,任何需要排除ID,然后使用英文逗號(hào)拼接表所有字段信息的地方,都可以使用它
?
插入數(shù)據(jù)sql,字段值列表 $insert_field_value_list$
?
例如表中有三個(gè)字段:id(主鍵)、goods_name、price,輸出:#{goodsName},#{price} 。會(huì)自動(dòng)排除主鍵 不僅插入數(shù)據(jù)時(shí)可用,任何需要排除ID,然后使用英文逗號(hào)拼接表所有字段信息的地方,都可以使用它
?
修改數(shù)據(jù)sql,字段名列表 $update_field_list$
?
例如表中有三個(gè)字段:id(主鍵)、goods_name、price 輸出(會(huì)自動(dòng)換行,會(huì)攜帶以下縮進(jìn),會(huì)自動(dòng)排除主鍵):
?
goods_name=#{goodsName}, price=#{price}
查詢數(shù)據(jù)sql,字段名列表 $select_field_list$
?
例如表中有三個(gè)字段:id(主鍵)、goods_name、price,輸出:id,goods_name,price 。帶主鍵
?
whele字段條件sql,字段名列表 $whele_field_list$
?
例如表中有三個(gè)字段:id(主鍵)、goods_name、price, 輸出(會(huì)自動(dòng)換行,會(huì)攜帶以下縮進(jìn)):
?
ANDid=#{id} ANDgoods_name=#{goodsName} ANDprice=#{price}
創(chuàng)建表-表字段列表 $create_table_field_list$
?
例如表中有三個(gè)字段:id(自增主鍵)、goods_name、price 輸出(會(huì)自動(dòng)換行,會(huì)攜帶以下縮進(jìn)):
?
`id`INT(11)NOTNULLAUTO_INCREMENT, `goods_name`VARCHAR(128)NOTNULLDEFAULT'NULL', `price`DECIMAL(10,2)NOTNULLDEFAULT'NULL'
當(dāng)前時(shí)間 $current_time$
?
自動(dòng)獲取當(dāng)前時(shí)間,格式:yyyy-MM-DD hhss,示例值:2023-02-05 1718
?
自動(dòng)根據(jù)數(shù)據(jù)類型,匹配斷言方法 $java_type_adapter_assert_method$
?
對(duì)于Java數(shù)據(jù)類型等于String的字段,使用isNoBlankStr方法,其他的類型都使用isNoEmptyObj方法 這是一個(gè)定制化很高的動(dòng)態(tài)參數(shù),可忽略它。
?
動(dòng)態(tài)代碼塊
動(dòng)態(tài)代碼塊由用戶自行定義,代碼塊中也可以設(shè)置動(dòng)態(tài)參數(shù),目前僅提供4種明確的動(dòng)態(tài)代碼塊
成員變量列表 $member_param_list$
例如表中有三個(gè)字段:id(主鍵)、goods_name、price
假設(shè)用戶定義了如下代碼塊內(nèi)容:
/**$field_comment$*/ private$field_type_java$$field_name_hump$;
輸出(會(huì)自動(dòng)根據(jù)字段數(shù)量,累加輸出自定義代碼塊內(nèi)容):
/**id*/ privateIntegerid; /**商品名稱*/ privateStringgoodsName; /**商品價(jià)格*/ privateStringprice;
GetSet方法列表 $get_set_method_list$
例如表中有三個(gè)字段:id(主鍵)、goods_name、price
假設(shè)用戶定義了如下代碼塊內(nèi)容:
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$; }
輸出(會(huì)自動(dòng)根據(jù)字段數(shù)量,累加輸出自定義代碼塊內(nèi)容):
publicIntegergetId(){ returnid; } publicvoidsetId(Integerid){ this.id=id; } publicStringgetGoodsName(){ returngoodsName; } publicvoidsetGoodsName(StringgoodsName){ this.goodsName=goodsName; } publicStringgetPrice(){ returnprice; } publicvoidsetPrice(Stringprice){ this.price=price; }
模型轉(zhuǎn)換器參數(shù)列表 $converter_source_to_target_params_list$
例如表中有三個(gè)字段:id(主鍵)、goods_name、price
假設(shè)用戶定義了如下代碼塊內(nèi)容:
target.set$field_name_hump_A$(source.get$field_name_hump_A$());
輸出(會(huì)自動(dòng)根據(jù)字段數(shù)量,累加輸出自定義代碼塊內(nèi)容):
target.setId(source.getId()); target.setGoodsName(source.getGoodsName()); target.setPrice(source.getPrice());
必填項(xiàng)業(yè)務(wù)校驗(yàn) $biz_check_required_params$
例如表中有三個(gè)字段:id(主鍵)、goods_name、price
假設(shè)用戶定義了如下代碼塊內(nèi)容:
CommonAssert.$java_type_adapter_assert_method$(dto.get$field_name_hump_A$(),"$field_comment$不可空");
輸出(會(huì)自動(dòng)根據(jù)字段數(shù)量,累加輸出自定義代碼塊內(nèi)容):
CommonAssert.isNoBlankStr(dto.getGoodsName(),"goodsName不可空"); CommonAssert.isNoBlankStr(dto.getPrice(),"price不可空");
審核編輯:劉清
-
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8961瀏覽量
150773 -
SQL
+關(guān)注
關(guān)注
1文章
780瀏覽量
44816 -
代碼生成器
+關(guān)注
關(guān)注
0文章
25瀏覽量
9315
原文標(biāo)題:非低代碼,我寫了一個(gè)比ChatGPT還牛的CRUD代碼生成器
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
介紹一下ABOV提供的代碼生成器
python生成器
利用LabVIEW代碼生成器簡(jiǎn)化應(yīng)用項(xiàng)目

STM32庫(kù)函數(shù)代碼自動(dòng)生成器V1.2
STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版
STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版
python生成器是什么
如何擴(kuò)展自定義功能塊,以及代碼生成器的用法
將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目

個(gè)性化地定制自己的uvm代碼生成器模板和腳本

將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目

評(píng)論