笔者现在毕业半年,开始在公司做项目的时候遇到底层代码一系列的增删改查,让我非常头疼。刚开始都是一点点敲的,后来觉得实在麻烦去网上找代码生成器,不过没有一个我会用的(小小鄙视一下自己),去读这些代码生成器的源码也是稀里糊涂的,但又实在不想再敲了,于是尝试着自己去写一个,之前工作忙一直拖着,过年回来后任务不是很多,终于写完(其实认真写的话,大部分人,一两天就可以写完,比找别人的用合算多了)。
写完之后觉得自己写一个实在比用别人的舒服多了,很容易更改格式,而且出问题了很容易调整。
在此记录一下思路。
源码下载链接:http://download.csdn.net/detail/whithorse/6923175
一.使用的工具:FreeMaker,用于写模板文件,java的代码生成器用的基本上都是这个。
二.分层结构: 代码重构了四五次,最终的结构是这样的,但还是不满意,觉得不够灵活,有时间慢慢修改。
Main层:代码生成器的主体和执行入口。
Model层:就一个模型类,记录每一列的信息,这里只有三个属性:
private StringfieldName;//数据库原字段名
private StringproName; //变量名
private StringproType; //变量类型
有些生成器的模型类还有表的模型,我的需求比较简单,只有列的模型类。
工具层:
Db层:很明显是操作数据库的,为Data层服务。
Data层:调用Db层获取和模板相匹配的数据模型
(FreeMaker的思想就是:模板+数据模型=输出);
FreeMaker层:用于生成文件。
ftl层:存放模板文件。
三.思路整理
一个代码生成器执行一次是针对一张表,生成的代码必然涉及到表中每一列的字段和相应的数据类型。
JDBC中提供了这个类ResultSetMetaData来获取到这些信息,当然了拿到的数据需要转换才能成为你想要的数据,把拿到的信息转换然后封装成相应的模型类。主要代码如下:
this.rs =this.st.executeQuery(sqlstr);
ResultSetMetaData resultSetMetaData =rs.getMetaData();
for(int i=1;i<=resultSetMetaData.getColumnCount();i++){
String columName =resultSetMetaData.getColumnName(i);
String proName = convertField(columName);
String dataType =getTypeName(resultSetMetaData.getColumnType(i));
FieldBean fieldBean = new FieldBean();
fieldBean.setFieldName(columName.toLowerCase());
fieldBean.setProName(proName);
fieldBean.setProType(dataType);
returnList.add(fieldBean);
有了上面的代码在data层就可以根据表名来得到这张表的每一列的信息,从而生成数据模型,有了数据模型,根据自己的需求写出相应的模板(ftl文件),然后使用FreeMaker生成文件即可。
四.效果展示
vo的模板文件:
package ${ package };
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import com.excellence.common.base.BaseObject;
/**
* @author masb
*
*对应表(${ tableName })
*/
public class ${ className } extends BaseObject {
private static final long serialVersionUID = 1L;
<#list properties as pro>
private ${pro.proType} ${pro.proName};
</#list>
/**无参构造方法**/
public ${ className }(){};
/**带参构造方法*/
public ${ className } (<#list properties as pro>${pro.proType} ${pro.proName}<#if pro_has_next>,<#else></#if></#list>){
<#list properties as pro>
this.${pro.proName} = ${pro.proName};
</#list>
}
/**带Map类型参数构造方法 将Map数据按key设置到对应的属性上,从而实例对象*/
public ${ className }(Map data){
<#list properties as pro>
this.${pro.proName} = data.get("${pro.fieldName}") == null ? null : (${pro.proType})data.get("${pro.fieldName}");
</#list>
}
/***
* 将形参传入的参数data的值,设置到vo对象对应属性中
*/
public BaseObject setMap(Map data) {
<#list properties as pro>
this.set${pro.proName?cap_first}(data.get("${pro.fieldName}") == null ? null : (${pro.proType})data.get("${pro.fieldName}"));
</#list>
return this;
}
/** 将vo对象的值放入到Map对象中*/
public Map toMap()
{
Map map = new HashMap();
<#list properties as pro>
map.put("${pro.fieldName}",${pro.proName});
</#list>
return map;
}
public String toString(){
return toMap().toString();
}
//属性get||set方法
<#list properties as pro>
public ${pro.proType} get${pro.proName?cap_first}() {
return this.${pro.proName};
}
public void set${pro.proName?cap_first}(Integer ${pro.proName}) {
this.${pro.proName} = ${pro.proName};
}
</#list>
}
生成的代码:
package com.platform.main;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import com.excellence.common.base.BaseObject;
/**
* @author masb
*
*对应表(cms_file)
*/
public class FileVO extends BaseObject {
private static final long serialVersionUID = 1L;
private Integer id;
private Integer businessId;
private Integer businessType;
private String oldFilename;
private String filename;
private String filepath;
private Timestamp createDate;
private Timestamp lastModifiedDate;
private Integer lastModifiedUser;
private Integer priority;
private Integer orgId;
private String remark;
private Integer creatorId;
/**无参构造方法**/
public FileVO(){};
/**带参构造方法*/
public FileVO (Integer id,Integer businessId,Integer businessType,String oldFilename,String filename,String filepath,Timestamp createDate,Timestamp lastModifiedDate,Integer lastModifiedUser,Integer priority,Integer orgId,String remark,Integer creatorId){
this.id = id;
this.businessId = businessId;
this.businessType = businessType;
this.oldFilename = oldFilename;
this.filename = filename;
this.filepath = filepath;
this.createDate = createDate;
this.lastModifiedDate = lastModifiedDate;
this.lastModifiedUser = lastModifiedUser;
this.priority = priority;
this.orgId = orgId;
this.remark = remark;
this.creatorId = creatorId;
}
/**带Map类型参数构造方法 将Map数据按key设置到对应的属性上,从而实例对象*/
public FileVO(Map data){
this.id = data.get("id") == null ? null : (Integer)data.get("id");
this.businessId = data.get("business_id") == null ? null : (Integer)data.get("business_id");
this.businessType = data.get("business_type") == null ? null : (Integer)data.get("business_type");
this.oldFilename = data.get("old_filename") == null ? null : (String)data.get("old_filename");
this.filename = data.get("filename") == null ? null : (String)data.get("filename");
this.filepath = data.get("filepath") == null ? null : (String)data.get("filepath");
this.createDate = data.get("create_date") == null ? null : (Timestamp)data.get("create_date");
this.lastModifiedDate = data.get("last_modified_date") == null ? null : (Timestamp)data.get("last_modified_date");
this.lastModifiedUser = data.get("last_modified_user") == null ? null : (Integer)data.get("last_modified_user");
this.priority = data.get("priority") == null ? null : (Integer)data.get("priority");
this.orgId = data.get("org_id") == null ? null : (Integer)data.get("org_id");
this.remark = data.get("remark") == null ? null : (String)data.get("remark");
this.creatorId = data.get("creator_id") == null ? null : (Integer)data.get("creator_id");
}
/***
* 将形参传入的参数data的值,设置到vo对象对应属性中
*/
public BaseObject setMap(Map data) {
this.setId(data.get("id") == null ? null : (Integer)data.get("id"));
this.setBusinessId(data.get("business_id") == null ? null : (Integer)data.get("business_id"));
this.setBusinessType(data.get("business_type") == null ? null : (Integer)data.get("business_type"));
this.setOldFilename(data.get("old_filename") == null ? null : (String)data.get("old_filename"));
this.setFilename(data.get("filename") == null ? null : (String)data.get("filename"));
this.setFilepath(data.get("filepath") == null ? null : (String)data.get("filepath"));
this.setCreateDate(data.get("create_date") == null ? null : (Timestamp)data.get("create_date"));
this.setLastModifiedDate(data.get("last_modified_date") == null ? null : (Timestamp)data.get("last_modified_date"));
this.setLastModifiedUser(data.get("last_modified_user") == null ? null : (Integer)data.get("last_modified_user"));
this.setPriority(data.get("priority") == null ? null : (Integer)data.get("priority"));
this.setOrgId(data.get("org_id") == null ? null : (Integer)data.get("org_id"));
this.setRemark(data.get("remark") == null ? null : (String)data.get("remark"));
this.setCreatorId(data.get("creator_id") == null ? null : (Integer)data.get("creator_id"));
return this;
}
/** 将vo对象的值放入到Map对象中*/
public Map toMap()
{
Map map = new HashMap();
map.put("id",id);
map.put("business_id",businessId);
map.put("business_type",businessType);
map.put("old_filename",oldFilename);
map.put("filename",filename);
map.put("filepath",filepath);
map.put("create_date",createDate);
map.put("last_modified_date",lastModifiedDate);
map.put("last_modified_user",lastModifiedUser);
map.put("priority",priority);
map.put("org_id",orgId);
map.put("remark",remark);
map.put("creator_id",creatorId);
return map;
}
public String toString(){
return toMap().toString();
}
//属性get||set方法
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getBusinessId() {
return this.businessId;
}
public void setBusinessId(Integer businessId) {
this.businessId = businessId;
}
public Integer getBusinessType() {
return this.businessType;
}
public void setBusinessType(Integer businessType) {
this.businessType = businessType;
}
public String getOldFilename() {
return this.oldFilename;
}
public void setOldFilename(Integer oldFilename) {
this.oldFilename = oldFilename;
}
public String getFilename() {
return this.filename;
}
public void setFilename(Integer filename) {
this.filename = filename;
}
public String getFilepath() {
return this.filepath;
}
public void setFilepath(Integer filepath) {
this.filepath = filepath;
}
public Timestamp getCreateDate() {
return this.createDate;
}
public void setCreateDate(Integer createDate) {
this.createDate = createDate;
}
public Timestamp getLastModifiedDate() {
return this.lastModifiedDate;
}
public void setLastModifiedDate(Integer lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
public Integer getLastModifiedUser() {
return this.lastModifiedUser;
}
public void setLastModifiedUser(Integer lastModifiedUser) {
this.lastModifiedUser = lastModifiedUser;
}
public Integer getPriority() {
return this.priority;
}
public void setPriority(Integer priority) {
this.priority = priority;
}
public Integer getOrgId() {
return this.orgId;
}
public void setOrgId(Integer orgId) {
this.orgId = orgId;
}
public String getRemark() {
return this.remark;
}
public void setRemark(Integer remark) {
this.remark = remark;
}
public Integer getCreatorId() {
return this.creatorId;
}
public void setCreatorId(Integer creatorId) {
this.creatorId = creatorId;
}
}
发现博客上不能添加附件o(╯□╰)o
源码下载链接:http://download.csdn.net/detail/whithorse/6923175