Hibernate Tools生成注释

时间:2023-03-09 00:16:29
Hibernate Tools生成注释

原文:http://www.blogjava.net/pauliz/archive/2009/11/13/302162.html

有同学需要修改后的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只是在默认的模板上做了少量修改,抛砖引玉了,如果各位有更好的模板,也希望能为大家共享一下

最近做项目时,使用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.ftl

Hibernate Tools生成注释<#-- // Fields -->
Hibernate Tools生成注释
Hibernate Tools生成注释<#foreach field in pojo.getAllPropertiesIterator()><#if pojo.getMetaAttribAsBool(field, "gen-property", true)>    /** *//**
Hibernate Tools生成注释<#if pojo.hasMetaAttribute(field, "field-description")>
Hibernate Tools生成注释     ${pojo.getFieldJavaDoc(field, 0)}
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释<#foreach column in field.columnIterator><#if column.comment?exists && column.comment?trim?length!=0>     * ${column.comment}.
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释</#foreach>
Hibernate Tools生成注释     */
Hibernate Tools生成注释    ${pojo.getFieldModifiers(field)} ${pojo.getJavaTypeName(field, jdk5)} ${field.name}<#if pojo.hasFieldInitializor(field, jdk5)> = ${pojo.getFieldInitialization(field, jdk5)}</#if>;
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释</#foreach>

pojo\PojoPropertyAccessors.ftl

Hibernate Tools生成注释<#-- // Property accessors -->
Hibernate Tools生成注释<#foreach property in pojo.getAllPropertiesIterator()>
Hibernate Tools生成注释<#if pojo.getMetaAttribAsBool(property, "gen-property", true)>
Hibernate Tools生成注释    /**  
Hibernate Tools生成注释<#if pojo.hasFieldJavaDoc(property)>    
Hibernate Tools生成注释     * ${pojo.getFieldJavaDoc(property, 4)}
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释<#foreach column in property.columnIterator><#if column.comment?exists && column.comment?trim?length!=0>     * 取得 ${column.comment}.
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释</#foreach>
Hibernate Tools生成注释     */
Hibernate Tools生成注释    <#include "GetPropertyAnnotation.ftl"/>
Hibernate Tools生成注释    ${pojo.getPropertyGetModifiers(property)} ${pojo.getJavaTypeName(property, jdk5)} ${pojo.getGetterSignature(property)}() {
Hibernate Tools生成注释        return this.${property.name};
Hibernate Tools生成注释    }
Hibernate Tools生成注释
Hibernate Tools生成注释    /**
Hibernate Tools生成注释<#if pojo.hasFieldJavaDoc(property)>    
Hibernate Tools生成注释     * ${pojo.getFieldJavaDoc(property, 4)}
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释<#foreach column in property.columnIterator><#if column.comment?exists && column.comment?trim?length!=0>     * 设置 ${column.comment}.
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释</#foreach>
Hibernate Tools生成注释     */   
Hibernate Tools生成注释    ${pojo.getPropertySetModifiers(property)} void set${pojo.getPropertyName(property)}(${pojo.getJavaTypeName(property, jdk5)} ${property.name}) {
Hibernate Tools生成注释        this.${property.name} = ${property.name};
Hibernate Tools生成注释    }
Hibernate Tools生成注释</#if>
Hibernate Tools生成注释</#foreach>
Hibernate Tools生成注释

org\hibernate\tool\hbm2x\TemplateProducer.java

Hibernate Tools生成注释public void produce(Map additionalContext, String templateName, File destination, String identifier, String fileType, String rootContext) {
Hibernate Tools生成注释        
Hibernate Tools生成注释        String tempResult = produceToString( additionalContext, templateName, rootContext );
Hibernate Tools生成注释        
Hibernate Tools生成注释        if(tempResult.trim().length()==0) {
Hibernate Tools生成注释            log.warn("Generated output is empty. Skipped creation for file " + destination);
Hibernate Tools生成注释            return;
Hibernate Tools生成注释        }
Hibernate Tools生成注释        FileWriter fileWriter = null;
Hibernate Tools生成注释        Writer fileWriter = null;
Hibernate Tools生成注释        try {
Hibernate Tools生成注释            
Hibernate Tools生成注释            th.ensureExistence( destination );    
Hibernate Tools生成注释         
Hibernate Tools生成注释            ac.addFile(destination, fileType);
Hibernate Tools生成注释            log.debug("Writing " + identifier + " to " + destination.getAbsolutePath() );
Hibernate Tools生成注释            fileWriter = new FileWriter(destination);
Hibernate Tools生成注释            fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
Hibernate Tools生成注释
Hibernate Tools生成注释            fileWriter.write(tempResult);            
Hibernate Tools生成注释        } 
Hibernate Tools生成注释        catch (Exception e) {
Hibernate Tools生成注释            throw new ExporterException("Error while writing result to file", e);    
Hibernate Tools生成注释        } finally {
Hibernate Tools生成注释            if(fileWriter!=null) {
Hibernate Tools生成注释                try {
Hibernate Tools生成注释                    fileWriter.flush();
Hibernate Tools生成注释                    fileWriter.close();
Hibernate Tools生成注释                }
Hibernate Tools生成注释                catch (IOException e) {
Hibernate Tools生成注释                    log.warn("Exception while flushing/closing " + destination,e);
Hibernate Tools生成注释                }                
Hibernate Tools生成注释            }
Hibernate Tools生成注释        }
Hibernate Tools生成注释        
Hibernate Tools生成注释    }

org\hibernate\tool\hbm2x\jtidy.properties

Hibernate Tools生成注释indent=auto
Hibernate Tools生成注释indent-spaces=4
Hibernate Tools生成注释#indent-attributes=yes
    wrap=180
Hibernate Tools生成注释markup=yes
Hibernate Tools生成注释clean=yes
Hibernate Tools生成注释output-xml=yes
Hibernate Tools生成注释input-xml=yes
Hibernate Tools生成注释show-warnings=yes
Hibernate Tools生成注释trim-empty-elements=yes
Hibernate Tools生成注释input-encoding=utf-8
Hibernate Tools生成注释output-encoding=utf-8

补充:
无法取得MySQL5 Table的Comments,修改org.hibernate.cfg.reveng.dialec.MySQLMetaDataDialect
重载getTables方法

Hibernate Tools生成注释/**
Hibernate Tools生成注释     * MetaData中无法取得table Comment,重载
Hibernate Tools生成注释     */
Hibernate Tools生成注释    @Override
Hibernate Tools生成注释    public Iterator getTables(String xcatalog, String xschema, String xtable) {
Hibernate Tools生成注释        try {
Hibernate Tools生成注释            final String catalog = caseForSearch(xcatalog);
Hibernate Tools生成注释            final String schema = caseForSearch(xschema);
Hibernate Tools生成注释            final String table = caseForSearch(xtable);
Hibernate Tools生成注释
Hibernate Tools生成注释            log.debug("getTables(" + catalog + "." + schema + "." + table + ")");
Hibernate Tools生成注释
Hibernate Tools生成注释            ResultSet tableRs = getMetaData().getTables(catalog, schema, table, new String[] { "TABLE", "VIEW" });
Hibernate Tools生成注释
Hibernate Tools生成注释            return new ResultSetIterator(tableRs, getSQLExceptionConverter()) {
Hibernate Tools生成注释
Hibernate Tools生成注释                Map element = new HashMap();
Hibernate Tools生成注释
Hibernate Tools生成注释                protected Object convertRow(ResultSet tableResultSet) throws SQLException {
Hibernate Tools生成注释                    element.clear();
Hibernate Tools生成注释                    putTablePart(element, tableResultSet);
Hibernate Tools生成注释                    element.put("TABLE_TYPE", tableResultSet.getString("TABLE_TYPE"));
Hibernate Tools生成注释
Hibernate Tools生成注释                    String remarks = tableResultSet.getString("REMARKS");
Hibernate Tools生成注释                    if (StringHelper.isEmpty(remarks)) {
Hibernate Tools生成注释                        String sql = "show table status " + (schema == null ? "" : " from " + schema + " ") + " like '"
Hibernate Tools生成注释                                + element.get("TABLE_NAME") + "' ";
Hibernate Tools生成注释                        PreparedStatement statement = getConnection().prepareStatement(sql);
Hibernate Tools生成注释
Hibernate Tools生成注释                        ResultSet tableRs = statement.executeQuery();
Hibernate Tools生成注释
Hibernate Tools生成注释                        if (tableRs.next()) {
Hibernate Tools生成注释                            remarks = tableRs.getString("COMMENT");
Hibernate Tools生成注释                        }
Hibernate Tools生成注释                    }
Hibernate Tools生成注释                    element.put("REMARKS", remarks);
Hibernate Tools生成注释                    return element;
Hibernate Tools生成注释                }
Hibernate Tools生成注释
Hibernate Tools生成注释                protected Throwable handleSQLException(SQLException e) {
Hibernate Tools生成注释                    // schemaRs and catalogRs are only used for error reporting if
Hibernate Tools生成注释                    // we get an exception
Hibernate Tools生成注释                    String databaseStructure = getDatabaseStructure(catalog, schema);
Hibernate Tools生成注释                    throw getSQLExceptionConverter().convert(
Hibernate Tools生成注释                            e,
Hibernate Tools生成注释                            "Could not get list of tables from database. Probably a JDBC driver problem. "
Hibernate Tools生成注释                                    + databaseStructure, null);
Hibernate Tools生成注释                }
Hibernate Tools生成注释            };
Hibernate Tools生成注释        } catch (SQLException e) {
Hibernate Tools生成注释            // schemaRs and catalogRs are only used for error reporting if we get an exception
Hibernate Tools生成注释            String databaseStructure = getDatabaseStructure(xcatalog, xschema);
Hibernate Tools生成注释            throw getSQLExceptionConverter().convert(e,
Hibernate Tools生成注释                    "Could not get list of tables from database. Probably a JDBC driver problem. " + databaseStructure,
Hibernate Tools生成注释                    null);
Hibernate Tools生成注释        }
Hibernate Tools生成注释    }

外键默认生成List,修改org.hibernate.cfg.JDBCBinder

Hibernate Tools生成注释/**
Hibernate Tools生成注释     * @param rc
Hibernate Tools生成注释     * @param processed
Hibernate Tools生成注释     * @param table
Hibernate Tools生成注释     * @param object
Hibernate Tools生成注释     */
Hibernate Tools生成注释    private Property bindOneToMany(PersistentClass rc, ForeignKey foreignKey, Set processed, Mapping mapping) {
Hibernate Tools生成注释
Hibernate Tools生成注释        Table collectionTable = foreignKey.getTable();
Hibernate Tools生成注释        Collection collection = new org.hibernate.mapping.Set(rc); // MASTER TODO: allow overriding collection type
Hibernate Tools生成注释        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&amp;characterEncoding=UTF-8&amp;useInformationSchema=true”即可。