怎么用java画鱼_要“鱼”也要“渔”-java手写代码生成器

遇到重复工作一定想办法将其转化为自动化,我觉得这才是合格的程序猿。我们日常开发中遇到的80%的代码都是增删改查,当然,已经有一些插件,比如MP提供了一整套的代码生成方案,但是提供的基本都是java代码,因为模板语言有太多种,根据每个人每个项目的不同而不同,但是,模板中一样也基本是列表和表单提交,怎么来解决这个重复工作呢?

思路:依然依赖mp组件,因为mp已经提供了对应的BaseService,BaseMapper等,但是本文重点不在于“怎么用”,而在于“怎么写”。“怎么写”属于自己的代码生成器,方便自己随意扩展前端页面生成。

前提-数据库设计约定:表名、字段名多个单词时下划线分割

读取数据库,解析各个表字段及备注

实体类生成:根据字段名解析为对应实体类属性名,同时注释为属性注释

定义生成模板(xxx.ftl)

前端页面:数据库字段备注为表单中的字段名,根据字段类型设置输入项的html标签

分别生成实体类、Mapper、Service、前端页面等

替换(xxx.ftl)中的变量

一、TableInfo对象

788c626359ef47febd1e70821296a370.png

773d492f2652915e4c98ecb6cacb03e6.png

一、JDBC读取数据库表结构

publicMapgetTables(){

try{

DatabaseMetaDatadatabaseMetaData=getConn().getMetaData();

ResultSetresultSet=databaseMetaData.getColumns(null,"%","%","%");

MaptableInfoMap=newHashMap<>(8);

while(resultSet.next()){

StringtableName=resultSet.getString("TABLE_NAME");

TableInfotableInfo=tableInfoMap.get(tableName);

if(tableInfo==null){

tableInfo=newTableInfo(tableName,StringUtil.toHump(tableName,true));

}

StringcolName=resultSet.getString("COLUMN_NAME");

Stringremark=resultSet.getString("REMARKS");

StringcolType=resultSet.getString("TYPE_NAME");

ListcolInfos=tableInfo.getColInfos();

if(colInfos==null||colInfos.size()==0){

colInfos=newArrayList<>();

}

ColInfocolInfo=newColInfo(colName,colType,remark);

colInfos.add(colInfo);

tableInfo.setColInfos(colInfos);

tableInfoMap.put(tableName,tableInfo);

}

returntableInfoMap;

}catch(SQLExceptione){

e.printStackTrace();

}

returnnull;

}

二、生成实体类

dataMap 存放渲染ftl模板时的数据。

publicvoidgenerateModel(StringdiskPath,TableInfotableInfo){

StringtemplateName="model.ftl";

Stringpath=diskPath+File.separator+tableInfo.getModelName()+TableInfo.GEN_SUFFIX;

MapdataMap=newHashMap<>();

dataMap.put("ModelName",tableInfo.getModelName());

dataMap.put("packageName","com.mos.aaa");

ListcolInfos=tableInfo.getColInfos();

dataMap.put("fields",colInfos);

Listpcks=newArrayList<>();

for(ColInfoinfo:colInfos){

if(StringUtil.isNotBlank(info.getFieldType().getPkg())&&!pcks.contains(info.getFieldType().getPkg())){

pcks.add(info.getFieldType().getPkg());

}

}

dataMap.put("pcks",pcks);

generateFileByTemplate(templateName,path,dataMap);

}

三、Model模板定义(用来生成Entity)

package${packageName};

importcom.baomidou.mybatisplus.activerecord.Model;

importjava.io.Serializable;

import${pck!};

#list>

#if>

publicclass${ModelName}extendsModel{

privatestaticfinallongserialVersionUID=1L;

/**

* ${field.remark!}

*/

private${field.fieldType.type}${field.changedColNameLower};

#list>

public${field.fieldType.type}get${field.changedColName}(){

return${field.changedColNameLower};

}

publicvoidset${field.changedColName}(${field.fieldType.type}${field.changedColNameLower}){

this.${field.changedColNameLower}=${field.changedColNameLower};

}

#list>

@Override

protectedSerializablepkVal(){

returnthis.id;

}

}

四、最终文件生成

privatevoidgenerateFileByTemplate(finalStringtemplateName,StringgenPath,MapdataMap){

try{

Templatetemplate=FreeMarkerTemplateUtils.getTemplate(templateName);

FileOutputStreamfos=newFileOutputStream(newFile(genPath));

Writerout=newBufferedWriter(newOutputStreamWriter(fos,"utf-8"),10240);

template.process(dataMap,out);

}catch(Exceptione){

System.out.println(e.getMessage());

}

}

五、生成结果

d68258b9404ad72eaacd4515f8bb0cc2.png

六、扩展

以上只是生成简单的Entity实体类示例。一般我们后台页面结构为左、上、下、中四部分,我们只需要生成“中”部分即可,可以根据一个已完成的页面,替换其中的变量即可,生成原理同上。如有需要,可以关注我的公众号【陌与尘埃】或者关注我的开源项目【EBOOT】,后面我会将完整的代码生成器开源出来,欢迎大家一起来完善~~~

RPC(Remote Procedure Call)是一种远程过程调用技术,用于实现分布式系统中的服务调用。分布式事务管理器则是用于管理分布式事务的组件,保证跨多个系统的操作的原子性、一致性、隔离性和持久性。 在实现分布式事务管理器时,可以使用两阶段提交(Two-Phase Commit,2PC)协议。该协议包含两个阶段:准备阶段和提交阶段。 在准备阶段,事务协调器向参与者节点发送准备请求,询问它们是否准备好提交事务。如果所有参与者节点都准备好提交事务,那么协调器发送提交请求;否则,协调器发送回滚请求,让所有参与者回滚事务。 在提交阶段,参与者节点根据协调器的请求提交或回滚事务,并向协调器发送响应。 以下是一个简单的使用Java手写的分布式事务管理器的示例代码: ```java import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; public class TransactionManager { private List<TransactionParticipant> participants; public TransactionManager() { participants = new ArrayList<>(); } public void addParticipant(TransactionParticipant participant) { participants.add(participant); } public void commit() throws RemoteException { boolean allPrepared = true; for (TransactionParticipant participant : participants) { if (!participant.prepare()) { allPrepared = false; break; } } if (allPrepared) { for (TransactionParticipant participant : participants) { participant.commit(); } } else { for (TransactionParticipant participant : participants) { participant.rollback(); } } } } ``` 在上面的代码中,TransactionManager是一个分布式事务管理器,它维护了一个参与者列表,并提供了添加参与者和提交事务的方法。TransactionParticipant是一个参与者接口,它包含了prepare、commit和rollback三个方法,分别表示准备、提交和回滚事务。 需要注意的是,在实际应用中需要考虑到网络延迟、节点故障等因素,以确保分布式事务的正确执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值