一直想找一個東東根據數據庫生成實體,具有以下功能:
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();
}
}
}
