经常需要编写可重复的代码片段。
考虑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
次然后编辑之外,我发现处理此问题的唯一“聪明”方式是使用python
,jinja2
库并编写一个小代码生成器。
但是,为了做到这一点,我必须安装python
,安装库,创建template
,创建自定义script
以从text file
读取值然后为读取的值生成代码。
我想知道有没有更简单的方法来实现上述目标?
支持代码生成的任何编辑器或插件?
我知道像Netbeans,Eclipse这样的IDE可以生成一些代码 - 比如getter和setter等等,但这还不够......
简而言之, 我想通过仅改变特定部分来重新生成一些代码行......问题是如何轻松实现这一点? (我知道很难做到这一点)..我正在寻找想法......
答案 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和其他代码。
我正在使用Python27和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-----------------
答案 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