原文:http://www.blogjava.net/pauliz/archive/2009/11/13/302162.htmlphp
有同窗須要修改後的Hibernate Tools
整個tool我就不上傳了,須要的請到http://downloads.sourceforge.net/jboss/HibernateTools-3.2.4.GA-R200905070146-H18.zip 或者 http://files.cnblogs.com/eggbucket/hibernate-tools.zip下載。
hibernate-tools.zip
是修改後的jar,解壓後覆蓋plugins\org.hibernate.eclipse_3.2.4.GA-R200905070146-H18\lib\tools\hibernate-tools.jar
template.zip 或者 http://files.cnblogs.com/eggbucket/template.zip
是ftl模板,Hibernate Code Generation Configuration中Main選項卡最下面Template directory可指定使用自定義的模板
template.zip只是在默認的模板上作了少許修改,拋磚引玉了,若是各位有更好的模板,也但願能爲你們共享一下html
最近作項目時,使用Hibernate Tools 3.2.4生成entity和hbm.xml,但默認狀況下,DB中的comments無法生成到javadoc和xml中,改了templates卻是有註釋了,但倒是亂碼,內心一直耿耿於懷...(這不符合咱一直強調的編碼規範不是?最主要的是人懶,有時用entity不想再找文檔)。在網上找了半天,大多說是freemarker編碼設置問題,但無論怎麼設置,都沒一點效果,決定本身動手。下了源碼,查到緣由,人家壓根就沒處理中文問題。記錄一下處理過程。
ftl是freemarker模板,能夠在jar包外使用,java和properties從新打包替換hibernate-tools.jar,若是是eclipse-plugins,jar包在plugins\org.hibernate.eclipse_3.2.4.GA-R200905070146-H18\lib\tools\hibernate-tools.jar
pojo\PojoFields.ftljava
<
#
--
//
Fields -->
<
#foreach field in pojo.getAllPropertiesIterator()
><
#
if
pojo.getMetaAttribAsBool(field,
"
gen-property
"
,
true
)
>
/** */
/**
<#if pojo.hasMetaAttribute(field, "field-description")>
${pojo.getFieldJavaDoc(field, 0)}
</#if>
<#foreach column in field.columnIterator><#if column.comment?exists && column.comment?trim?length!=0> * ${column.comment}.
</#if>
</#foreach>
*/
$
{pojo.getFieldModifiers(field)}
$
{pojo.getJavaTypeName(field, jdk5)}
$
{field.name}
<
#
if
pojo.hasFieldInitializor(field, jdk5)
>
=
$
{pojo.getFieldInitialization(field, jdk5)}
</
#
if
>
;
</
#
if
>
</
#foreach
>
pojo\PojoPropertyAccessors.ftlmysql
<
#
--
//
Property accessors -->
<
#foreach property in pojo.getAllPropertiesIterator()
>
<
#
if
pojo.getMetaAttribAsBool(property,
"
gen-property
"
,
true
)
>
/**
<#if pojo.hasFieldJavaDoc(property)>
* ${pojo.getFieldJavaDoc(property, 4)}
</#if>
<#foreach column in property.columnIterator><#if column.comment?exists && column.comment?trim?length!=0> * 取得 ${column.comment}.
</#if>
</#foreach>
*/
<
#include
"
GetPropertyAnnotation.ftl
"
/>
$
{pojo.getPropertyGetModifiers(property)}
$
{pojo.getJavaTypeName(property, jdk5)}
$
{pojo.getGetterSignature(property)}
()
{
return this.${property.name};
}
/**
<#if pojo.hasFieldJavaDoc(property)>
* ${pojo.getFieldJavaDoc(property, 4)}
</#if>
<#foreach column in property.columnIterator><#if column.comment?exists && column.comment?trim?length!=0> * 設置 ${column.comment}.
</#if>
</#foreach>
*/
$
{pojo.getPropertySetModifiers(property)}
void
set$
{pojo.getPropertyName(property)}
($
{pojo.getJavaTypeName(property, jdk5)}
$
{property.name}
)
{
this.${property.name} = ${property.name};
}
</
#
if
>
</
#foreach
>
org\hibernate\tool\hbm2x\TemplateProducer.javasql
public
void
produce(Map additionalContext, String templateName, File destination, String identifier, String fileType, String rootContext)
{
String tempResult = produceToString( additionalContext, templateName, rootContext );
if(tempResult.trim().length()==0) {
log.warn("Generated output is empty. Skipped creation for file " + destination);
return;
}
FileWriter fileWriter = null;
Writer fileWriter = null;
try {
th.ensureExistence( destination );
ac.addFile(destination, fileType);
log.debug("Writing " + identifier + " to " + destination.getAbsolutePath() );
fileWriter = new FileWriter(destination);
fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
fileWriter.write(tempResult);
}
catch (Exception e) {
throw new ExporterException("Error while writing result to file", e);
} finally {
if(fileWriter!=null) {
try {
fileWriter.flush();
fileWriter.close();
}
catch (IOException e) {
log.warn("Exception while flushing/closing " + destination,e);
}
}
}
}
org\hibernate\tool\hbm2x\jtidy.properties數據庫
indent
=
auto
indent
-
spaces
=
4
#indent
-
attributes
=
yes
wrap
=
180
markup
=
yes
clean
=
yes
output
-
xml
=
yes
input
-
xml
=
yes
show
-
warnings
=
yes
trim
-
empty
-
elements
=
yes
input-encoding=utf-8
output-encoding=utf-8
補充:
沒法取得MySQL5 Table的Comments,修改org.hibernate.cfg.reveng.dialec.MySQLMetaDataDialect
重載getTables方法app
/**
* MetaData中沒法取得table Comment,重載
*/
@Override
public
Iterator getTables(String xcatalog, String xschema, String xtable)
{
try {
final String catalog = caseForSearch(xcatalog);
final String schema = caseForSearch(xschema);
final String table = caseForSearch(xtable);
log.debug("getTables(" + catalog + "." + schema + "." + table + ")");
ResultSet tableRs = getMetaData().getTables(catalog, schema, table, new String[] { "TABLE", "VIEW" });
return new ResultSetIterator(tableRs, getSQLExceptionConverter()) {
Map element = new HashMap();
protected Object convertRow(ResultSet tableResultSet) throws SQLException {
element.clear();
putTablePart(element, tableResultSet);
element.put("TABLE_TYPE", tableResultSet.getString("TABLE_TYPE"));
String remarks = tableResultSet.getString("REMARKS");
if (StringHelper.isEmpty(remarks)) {
String sql = "show table status " + (schema == null ? "" : " from " + schema + " ") + " like '"
+ element.get("TABLE_NAME") + "' ";
PreparedStatement statement = getConnection().prepareStatement(sql);
ResultSet tableRs = statement.executeQuery();
if (tableRs.next()) {
remarks = tableRs.getString("COMMENT");
}
}
element.put("REMARKS", remarks);
return element;
}
protected Throwable handleSQLException(SQLException e) {
// schemaRs and catalogRs are only used for error reporting if
// we get an exception
String databaseStructure = getDatabaseStructure(catalog, schema);
throw getSQLExceptionConverter().convert(
e,
"Could not get list of tables from database. Probably a JDBC driver problem. "
+ databaseStructure, null);
}
};
} catch (SQLException e) {
// schemaRs and catalogRs are only used for error reporting if we get an exception
String databaseStructure = getDatabaseStructure(xcatalog, xschema);
throw getSQLExceptionConverter().convert(e,
"Could not get list of tables from database. Probably a JDBC driver problem. " + databaseStructure,
null);
}
}
外鍵默認生成List,修改org.hibernate.cfg.JDBCBindereclipse
/**
* @param rc
* @param processed
* @param table
* @param object
*/
private
Property bindOneToMany(PersistentClass rc, ForeignKey foreignKey, Set processed, Mapping mapping)
{
Table collectionTable = foreignKey.getTable();
Collection collection = new org.hibernate.mapping.Set(rc); // MASTER TODO: allow overriding collection type
Collection collection = new org.hibernate.mapping.Bag(rc); // MASTER TODO: allow overriding collection type
。。。
關於沒法取得MySQL5 Table的Comments的問題,樓主的修改源碼的方案是可行的。當我從GitHub獲取了hibernate-tools源碼,並修改了「org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect」類以後,問題解決了。
這時候,我忽然想到個問題,既然是經過JDBC獲取數據庫元信息,沒有獲取到,應該是數據庫廠商JDBC驅動有問題,爲何要去修改hibernate-tools的源碼呢?
最後我找到了MySQL驅動的這個bug(http://bugs.mysql.com/bug.php?id=65213),並從該bug頁找到了解決方案:
修改MySQL JDBC驅動URL,在其後追加:「?useUnicode=true&characterEncoding=UTF-8&useInformationSchema=true」便可。