杀鸡用牛刀之用velocity根据数据库表生成javabean
一直想找一个东东根据数据库生成实体,具有以下功能:
1,可以根据参数定义实体的父类和接口。
2,能够去除父类中或接口中已经定义的属性和方法。
经谷哥和度娘后,满足自己个性化要求的很难找到,于是杀鸡用牛刀,操起了velocity这样的模板引擎,幸好velocity并不算太重。
为了达到可配置化,使用了两个配置文件--参数文件和模板文件。
思路:
1,在xml文件中定义四个参数(生成文件路径,包路径,父类名称,接口名称);
2,写一个javabean的模板文件。
3,调用参数和模板文件生成javabean文件。
以下为关键代码:
1,xml中参数定义
<!--
以下为生成javabean模板涉及的参数
-->
<beantemplet name="default">
<param name="genDirPath" rem="生成java文件的路径">
src/entitybean/
</param>
<param name="templetFilePath" rem="模板文件的路径">
src/cfg/beanTemplet.vm
</param>
<param name="packagePath" rem="包路径">
entitybean
</param>
<param name="superClass" rem="所继承的父类">
bean.EntityObject
</param>
<param name="implInterface" rem="所实现的接口,本参数可重复,重复时表示实现多个接口">
</param>
</beantemplet>
2, velocity语法的javabean模板文件
##类型定义
#macro(typeof $field)
#if($field.startsWith("s") || $field.startsWith("t"))String##
#elseif($field.startsWith("i"))Integer##
#elseif($field.startsWith("n"))BigDecimal##
#elseif($field.startsWith("b"))Integer##
#else String##
#end
#end
##首字母大写
#macro(initUpperCase $field)
$field.toUpperCase().substring(0,1)$field.substring(1)##
#end
##类名称简写,去掉类名前面的类路径
#macro(shortName $fullClassName)
#set($index = $fullClassName.lastIndexOf(".") + 1)
$fullClassName.substring($index)##
#end
package $vm.packagePath;
import java.math.BigDecimal;
#if($vm.superClass)
import $vm.superClass;
#end
#if($vm.interfaces)
#foreach($itf in $vm.interfaces)
import $itf;##
#end
#end
public class $vm.className ##
#if($vm.superClass)extends #shortName($vm.superClass)##
#end
#if($vm.interfaces)
#foreach($itf in $vm.interfaces)
#if($foreach.count < 2) implements ##
#end##
#shortName($itf)##
#if( $foreach.hasNext ),##
#end
#end
#end{
#if($vm.fields)
#foreach($field in $vm.fields)
private #typeof($field) $field;
#end
#end
#if($vm.fields)
#foreach($field in $vm.fields)
public void set#initUpperCase($field)(#typeof($field) $field){
this.$field = $field;
}
public #typeof($field) get#initUpperCase($field)(){
return this.$field;
}
#end
#end
#if($vm.tableName)##
public String getTableName(){
return "$vm.tableName";
}
#end
#if($vm.unImplMethods)
#foreach($method in $vm.unImplMethods)
$method
#end
#end
}
3,生成javabean文件代码
public class BeanGennerator2 {
String genDirPath = null;
String templetFilePath = null;
String packagePath = null;
String superClass = null;
String[] implInterface = null;
public String getGenDirPath() {
return genDirPath;
}
public void setGenDirPath(String genDirPath) {
this.genDirPath = genDirPath;
}
public String getTempletFilePath() {
return templetFilePath;
}
public void setTempletFilePath(String templetFilePath) {
this.templetFilePath = templetFilePath;
}
public String getPackagePath() {
return packagePath;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
}
public String getSuperClass() {
return superClass;
}
public void setSuperClass(String superClass) {
this.superClass = superClass;
}
public String[] getImplInterface() {
return implInterface;
}
public void setImplInterface(String[] implInterface) {
this.implInterface = implInterface;
}
public BeanGennerator2(){
setDefaultFromCfgFile();
}
/**
* 从配置文件中设置默认参数
*/
private void setDefaultFromCfgFile(){
String[] params = null;
params = ConfigHelper.instance().getBeanTempletParams("genDirPath");
if(0 < params.length){
genDirPath = params[0];
}
params = ConfigHelper.instance().getBeanTempletParams("templetFilePath");
if(0 < params.length){
templetFilePath = params[0];
}
params = ConfigHelper.instance().getBeanTempletParams("packagePath");
if(0 < params.length){
packagePath = params[0];
}
params = ConfigHelper.instance().getBeanTempletParams("superClass");
if(0 < params.length){
superClass = params[0];
}
implInterface = ConfigHelper.instance().getBeanTempletParams("implInterface");
}
/**
* 生成javabean文件
* @param tableGetter
* @param tableCodes
* @throws Exception
*/
@SuppressWarnings("unchecked")
void genBeanFile(ITableGetter tableGetter,String[] tableCodes) throws Exception{
VelocityEngine ve = new VelocityEngine();
ve.init();
Template vt = ve.getTemplate(getTempletFilePath());
VelocityContext context = new VelocityContext();
String[] superFields = getSuperFields(getSuperClass());
String[] unImplMethods = getUnImplMethods(getImplInterface());
@SuppressWarnings("rawtypes")
Map map = new ConcurrentHashMap();
if(null != getPackagePath()){
map.put("packagePath", getPackagePath());
}
if(null != getSuperClass()){
map.put("superClass", getSuperClass());
}
if(null != getImplInterface() && 0 < getImplInterface().length){
map.put("interfaces", getImplInterface());
}
if(null != unImplMethods && 0 < unImplMethods.length){
map.put("unImplMethods", unImplMethods);
}
// map.put("superFields", superFields);
List<Table> list = tableGetter.getTables(tableCodes);
for(Table t:list){
String tableName = t.getScode();
String className = CommTool.initialUpperCase(BeanTool.tableCode2ClassName(tableName.toLowerCase()));
String[] fields = getFields(getThisFields(t),superFields);
map.put("tableName",tableName);
map.put("className",className);
map.put("fields", fields);
context.put("vm", map);
StringWriter sw = new StringWriter();
vt.merge( context, sw );
// writeToFile(className,sw.toString());
System.out.print(sw);
}
}
/**
* 取本类中不包含父类中已经声明的属性
* @param thisFields
* @param superFields
* @return
*/
private String[] getFields(String[] thisFields,String[] superFields){
if(null == thisFields){
return new String[0];
}
if(null == superFields || 0 >= superFields.length){
return thisFields;
}
List<String> thisList = new ArrayList<String>();
Set<String> superFieldSet = new HashSet<String>(Arrays.asList(superFields));
for(String field:thisFields){
if(!superFieldSet.contains(field)){
thisList.add(field);
}
}
return thisList.toArray(new String[0]);
}
/**
* 取表t中所有的属性
* @param t
* @return
*/
private String[] getThisFields(Table t) {
// TODO Auto-generated method stub
return BeanTool.vosFieldValues(t.getColumns().toArray(new Column[0]),"scode");
}
/**
* 取父类中声明的属性
* @param superClass2
* @return
*/
private String[] getSuperFields(String superClass2) {
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
Class cls = null;
try {
cls = Class.forName(superClass2);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(null != cls){
Field[] fieldList = cls.getDeclaredFields();
for(Field f: fieldList){
String name = f.getName();
if(!list.contains(name)){
list.add(name);
}
}
}
return list.toArray(new String[list.size()]);
}
private String[] getUnImplMethods(String[] implInterface2) {
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
if(null != implInterface2){
String str = " abstract ";
StringBuffer buf = new StringBuffer();
try{
for(String itf : implInterface2){
Class cls = Class.forName(itf);
Method[] methods = cls.getMethods();
for(Method m:methods){
buf.append(m.toGenericString());
if(m.getReturnType().isPrimitive()){
buf.append("{\r\n return 0;\r\n}");
}else if(buf.indexOf(" void ")>0){
buf.append("{\r\n\r\n}\r\n");
}else {
buf.append("{\r\n return null;\r\n}");
}
int index = buf.indexOf(str);
list.add(buf.replace(index, index+str.length(), " ").toString());
}
// list.add(buf.toString());
}
}catch(ClassNotFoundException e){
}
}
return list.toArray(new String[list.size()]);
}
private void writeToFile(String fileName, String content) throws IOException {
// TODO Auto-generated method stub
FileWriter fw =null;
BufferedWriter bufWriter = null;
String filePath = this.getGenDirPath()+fileName+".java";
try {
fw = new FileWriter(filePath);
bufWriter = new BufferedWriter(fw);
bufWriter.append(content).flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null != bufWriter)
bufWriter.close();
if(null != fw)
fw.close();
}
}
}