可重复代码生成

时间:2017-03-23 19:07:04

标签: java eclipse netbeans editor code-generation

经常需要编写可重复的代码片段。

考虑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表和一些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次然后编辑之外,我发现处理此问题的唯一“聪明”方式是使用pythonjinja2库并编写一个小代码生成器。

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

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

支持代码生成的任何编辑器或插件?

我知道像Netbeans,Eclipse这样的IDE可以生成一些代码 - 比如getter和setter等等,但这还不够......

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

5 个答案:

答案 0 :(得分:2)

你可以使用像Telosys这样的轻量级代码生成器:

在您的情况下,带有DSL模型的Telosys-CLI可能是正确的选择,您只需使用Velocity语言(http://velocity.apache.org/

创建特定模板

答案 1 :(得分:0)

在这种情况下,您可以做的最好的事情是将常量数组与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>

答案 2 :(得分:0)

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

所以,我只会发布我的 艰难的方式&#39;实现,我在我的问题中描述的内容(希望这对某些人有用 - 有时候)。

这里我将预设一个小代码生成器,用于生成java,html,jsp,xsd和其他代码。

我正在使用Python27Jinja2-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-----------------

答案 3 :(得分:-1)

在IntelliJ中我们有&#34; Live Template&#34;用于生成部分代码的功能。

例如,当您键入&#34; sout&#34; ,IntelliJ建议&#34; System.out.println&#34;。

键入&#34; main&#34; ,Eclipse建议&#34; public static void main(String [] args)&#34;

你可以为那些非常普通的代码创建类似的东西。

答案 4 :(得分:-1)

如果我能正确理解您的问题,那么您的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