锁定老帖子 主题:代码生成工具的实现思路
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-01-03
最后修改:2012-01-04
DataSource dataSource = context.getBean("dataSource", DataSource.class); Connection conn = dataSource.getConnection(); List<Column> lsColumns = new ArrayList<Column>(10); PreparedStatement stmt = conn.prepareStatement("select * from "+tableName+" where 1=0 "); ResultSet resultSet = stmt.executeQuery(); ResultSetMetaData rsmd = resultSet.getMetaData(); int n = rsmd.getColumnCount(); for (int i = 1; i <= n; i++) { String colName = rsmd.getColumnName(i); String fieldName = StringUtil.toBeanPatternStr(colName); Column column = new Column(); column.setName(colName) ; column.setJavaName(fieldName) ; column.setDataType(rsmd.getColumnClassName(i)); column.setPrecision(String.valueOf(rsmd.getPrecision(i))); column.setScale( String.valueOf(rsmd.getScale(i)) ); column.setLength( String.valueOf(rsmd.getColumnDisplaySize(i))); column.setNullable(String.valueOf("1".equals(rsmd.isNullable(i)))); //获取列注释 DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getColumns(null, null, tableName, null); while (rs.next()) { if (colName.equals(rs.getString("COLUMN_NAME"))) column.setComments(rs.getString("REMARKS")); } //获取主键列 ResultSet rs2 = dbmd.getPrimaryKeys(null, null, tableName); while (rs2.next()) { if (colName.equals(rs2.getString("COLUMN_NAME"))) column.setColumnKey("TRUE"); } 2.讲表字段相关信息放入模板引擎的上下文中,根据模板内容生成JAVA文件; Velocity.addProperty("file.resource.loader.path", getClassPath() + tmplDir); Template template = Velocity.getTemplate(tmplFile, encoding); VelocityContext tmplContext = new VelocityContext(context); FileUtil.createFile(absolutePath); PrintWriter writer = new PrintWriter( new FileOutputStream(absolutePath), true); template.merge(tmplContext, writer); writer.flush(); writer.close(); 3.tmplFile模板文件的内容如下: #if($pkResult.size()>1) @EmbeddedId #else @Id @Column(name = "$pkResult.get(0).name" ) @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="${TABLE_NAME}_SEQ") #end private ${keyType} ${keyVar} ; #foreach($prop in $columnResult) #set ($fieldName = ${prop.javaName} ) #set ($fieldType = $prop.dataType ) @Column(name = "${prop.name}" ) private $fieldType $fieldName ; #end public ${keyType} get${KeyFieldUpper} () { return ${keyVar}; } public void set${KeyFieldUpper} (${keyType} ${keyVar}) { this.${keyVar} = ${keyVar}; } #foreach($prop in $columnResult) #set ($fieldName = ${prop.javaName} ) #set ($fieldType = $prop.dataType ) #set ($innerFieldUpper = $stringUtil.capitalize($fieldName) ) public $fieldType get$innerFieldUpper () { return $fieldName; } public void set$innerFieldUpper ($fieldType $fieldName) { this.$fieldName = $fieldName; } #end 代码路径: 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-01-04
你这是velocity吧,不过这种操作应该包含javabean的生成
|
|
返回顶楼 | |
发表时间:2012-01-04
jyjava 写道 你这是velocity吧,不过这种操作应该包含javabean的生成
是的。也可以使用其他模块框架,freemarker也可以的。 |
|
返回顶楼 | |
发表时间:2012-01-05
代码生成器本身并没什么难度,只要能抽象出代码模型来,用freemarker类似的东西搞一下就行,主要是架构风格的问题
|
|
返回顶楼 | |
发表时间:2012-01-05
写的很好,也很实用
目前已经有的代码生成工具,类似于middgen,ibatior之类的,可以考虑一下改装 我以前在公司就改装过一个类似的,是通过middgen改装的,如果什么都自己写,感觉太累了 |
|
返回顶楼 | |
发表时间:2012-01-05
我用 CODESMITH 挺好用的。。 只不过模板是C#语法。但是网络上很多。
|
|
返回顶楼 | |
发表时间:2012-01-05
这个东西写个适合工作使用的就行了
|
|
返回顶楼 | |
发表时间:2012-01-05
senvon 写道 写的很好,也很实用
目前已经有的代码生成工具,类似于middgen,ibatior之类的,可以考虑一下改装 我以前在公司就改装过一个类似的,是通过middgen改装的,如果什么都自己写,感觉太累了 拼写都错误诶。。iBATOR |
|
返回顶楼 | |
发表时间:2012-01-05
核心技术是模板引擎..
@Log4j @Getter@Setter @SuppressWarnings("serial") @Component("{{actionName}}Action") public class {{ActionClass}} extends AppAction { private String id = null; private {{ServiceClass}} {{serviceId}} = null; private {{DomainClass}}{{domainSuffix}} {{domainName}} = new {{DomainClass}}{{domainSuffix}}(); public String index() { log.debug("execute index..."); return "index"; } public String show() { log.debug("execute show..."); return "show"; } public String create() { log.debug("execute create..."); {{domainName}} = new {{DomainClass}}{{domainSuffix}}(); return "create"; } public String save() { log.debug("execute save..."); return "show"; } public String edit() { log.debug("execute edit..."); return "edit"; } public String update() { log.debug("execute update..."); return "show"; } public String remove() { log.debug("execute remove..."); return "list"; } public String search() { log.debug("execute search..."); return "list"; } }
生成代码比较easy:
// TODO 从tmpls中读取文件 fs.readFile(actionPath, "UTF-8", function(err, data) { if (err) throw err; var actionCode = Mustache.to_html(data, vals); console.log(actionCode) fs.writeFile(targetPath + vals.ActionClass + ".java", actionCode, function(err) { if(err) throw err; console.log("generate " + vals.ActionClass + ".java success!"); }); })
|
|
返回顶楼 | |
发表时间:2012-01-05
要能前后台一体化生成,后台,页面。都生成好了。后台加上注解。连配置文件都可以极大的节省。主要是通过读取你要做的功能的表(可以是多个表关联)的字段,生成模板文件。然后通过el表达式替换掉模板里面的模块名称。
|
|
返回顶楼 | |