可重复代码生成

Repeatable Code generation

经常需要编写重复table 段代码。

考虑以下来自 Java 的例子(尽管它可能不是最好的例子,但我希望你能理解一般的想法...)

String X = rs.getString("X");

其中 X 将具有以下值:'name''surname' ... 和 20-30 其他值。

(另一个示例是 HTML 代码和任何其他代码 - 您需要为 X 创建)

最终结果应该是:

String name=rs.getString("name");
String surname=rs.getString("surname");
....

String whatever = rs.getString("whatever");

这是另一个例子 html table 和一些 scriplets,在这种情况下要复制的字符串将是 <th>X</th><td><%=myBean.getX()%></td> 最终结果将是:

<table style="width:100%">
  <tr>
    <th>name</th>
    <th>surname</th> 
    <th>..</th>
    <th>whatever</th>
  </tr>
 <tr>
    <td><%=myBean.getName()%></td>
    <td><%=myBean.getSurname()%></td> 
    <td>..</td>
    <td><%=myBean.getWhatever()%></td> 
  </tr>
</table>

所以,除了将上面的内容复制粘贴 30 次然后编辑之外,我发现处理此问题的唯一 'clever' 方法是使用 pythonjinja2 库并编写一个小型代码生成器。

但是,为了做到这一点,我必须安装 python、安装库、创建 template、创建自定义 script 以从 [=31] 中读取值=] 然后为读取的值生成代码。

我想知道有没有更简单的方法来实现上述目标?

有支持代码生成的编辑器或插件吗?

我知道像 Netbeans、Eclipse 这样的 IDE 可以生成一些代码——比如 getters 和 setters……等等,但这还不够……

简而言之, 我想通过仅更改特定部分来重新生成一些代码行......问题是如何轻松实现? (我知道这样做的困难方法)..我正在寻求想法...

在 IntelliJ 中,我们有 "Live Template" 功能,您可以使用它来生成部分代码。

例如,当您键入 "sout" 时,IntelliJ 会建议 "System.out.println".

当您键入 "main" 时,Eclipse 会建议 "public static void main(String[] args)"

您可以为非常常见的代码片段创建类似的东西。

在这种情况下,您能做的最好的事情就是将常量数组与 HashMap 一起使用。常量数组将保存 hashmap 的键名,而 hashmap 还将保存每个键名。

例如:

String[] keys = {"name", "surname", "whatever" };
HashMap<String, String> elements = new HashMap<String, String>();
for (String key : keys)
{
    elements.put(key, rs.getString(key));
}

您只需要注意所有元素都来自同一类型即可。如果不是,则必须将它们存储为对象然后再进行转换。

编辑:为了在 Scriptlet 中使用,一个好主意是:

<tr>
    <% for (String key : keys)
       {
    %>      
    <td><%= elements.get(key)%></td>
    <% } %>
</tr>

如果我对您的问题的理解正确,您的 ResultSet 包含很多列。而且您不想一一得到它们。 可以通过以下方式从 ResultSet 中获取所有列:

ResultSetMetaData metaData = resultSet.getMetaData();
for (int columnIndex = 1; columnIndex <= metaData.getColumnCount(); columnIndex++) {
    String columnName = metaData.getColumnName(columnIndex);
    String value = resultSet.getString(columnIndex);
}

当然,在此示例中,所有值都将表示为字符串,但您也可以使用相同的 metaData 对象来确定列的类型。在文档中阅读更多相关信息:https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html

可能我正在寻找不存在的东西。

所以,我将 post 我的“困难方式”实现,我在问题中描述的内容(希望这对有人 - 某个时候)。

这里我会预设一个我正在使用的小型代码生成器,用于生成java、html、jsp、xsd等代码。

我正在使用 Python27 and Jinja2-2.7.2

我的文件:

InputData.txt

:This is field list
field1:field1 description
field2:field2 description
field3:field3 description
field4:field4 description
name:first name of the person 
surname:last name of the person
whatever:whatever you need

CodeGenerator.py

import jinja2 
import codecs 
templateLoader = jinja2.FileSystemLoader( searchpath="." ) 
templateEnv    = jinja2.Environment( loader=templateLoader )
TEMPLATE_FILE  = "CodeGenerator.jinja" 
template       = templateEnv.get_template( TEMPLATE_FILE )
COLUMNS        = [tuple(line.split(':')) for line in codecs.open( "InputData.txt", "r", "utf-8" )]
COLUMNS        = map(lambda s: (s[0],(s[0].strip().title(),s[1].strip())), COLUMNS)
#title() copy of the string in which first characters of all the words are capitalized.
#strip()  copy of the string, all chars have been stripped from the beginning and the end
#lambda s --> (field1,(Field1,field1 description))
#ignore the first line 
COLUMNS.pop(0)
#add variables to work with 
templateVars = { "table" : "MyTableName",
                 "description" : "A simple code generator",
                 "columns" : COLUMNS
               }

outputText = template.render( templateVars ) 
f = open('Generated.txt', 'w') 
outputText = outputText.encode('utf-8')
f.write(outputText)
f.close() 
print outputText

CodeGenerator.jinja

//------------------model------------------------
//Generated code for model 
import java.io.Serializable;
public class {{table|capitalize}}_Model implements Serializable{
{%for columnName,columnTitle in columns%}
private String {{columnName|lower}};{%endfor%}

{% for columnName,columnTitle in columns %}
public void set{{columnName|capitalize}}(String {{columnName|lower}}){ 
  this.{{columnName|lower}}={{columnName|lower}};
}
public String get{{columnName|capitalize}}(){ 
  return this.{{columnName|lower}};
}
{% endfor %}
public {{table|capitalize}}_Model({% for columnName,columnTitle in columns %}String {{columnName|lower}}{% if not loop.last %},{% endif %}{% endfor %}){
        {% for columnName,columnTitle in columns %}
  this.{{columnName|lower}}={{columnName|lower}}; {% endfor %}  
    }
public String toString(){

return {% for columnName,columnTitle in columns %}"{{columnName|lower}}:" + this.{{columnName|lower}}{% if not loop.last %}+{% endif %}{% endfor %};

}

}
//------------------model------------------------
//-----------------getStrings--------------------
{% for columnName,columnTitle in columns %}
 String {{columnName}}=rs.getString("{{columnName}}");
{% endfor %}
//----------------------------------------------
//------------------jsp example-----------------
{% for columnName,columnTitle in columns %}
<s:label  cssStyle ="margin-top:5px;color:blue;" value="{{columnTitle[1]}} :" id="{{columnName}}_label"/>
<s:textfield label="{{columnTitle[1]}}" name="myBean.{{columnName}}" />
{% endfor %}
//------------------jsp example-----------------

您可以使用像 Telosys 这样的轻量级代码生成器来做到这一点:

在你的情况下,带有 DSL 模型的 Telosys-CLI 可能是正确的选择,你只需要用 Velocity 语言创建你的特定模板 (http://velocity.apache.org/)