原文: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

<#-- // 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.ftl

<#-- // 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.java

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方法

/**
     * 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.JDBCBinder

/**
     * @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&amp;characterEncoding=UTF-8&amp;useInformationSchema=true”即可。
 
 
 
 

Hibernate Tools生成注释的更多相关文章

  1. 用hibernate tools生成对应的sql应用代码

    参考资料: eclipse在线配置hibernate tools http://jingyan.baidu.com/article/db55b609959d154ba20a2f5d.html [图]H ...

  2. 用Hibernate Tools生成Hibernate Mapping映射文件

    Eclipse中要集成安装Hibernate Tools组件 如果没有,请查看:Eclipse juno 中安装 JBoss Tools,集成Hibernate 一.确定环境: 1.Maven3.0. ...

  3. 【原创】Hibernate自动生成(1)

    本实战是博主初次学习Java,分析WCP源码时,学习HibernateTools部分的实战,由于初次接触,难免错误,仅供参考,希望批评指正. 开发环境: Eclipse Version: Photon ...

  4. Hibernate Tools for Eclipse的使用

    Hibernate Tools的官方网站:http://hibernate.org/tools/Step1.安装好Hibernate Tools,建立一个Dynamic web project,工程名 ...

  5. Hibernate Tools 自动生成hibernate的hbm文件

    本文有待商榷 当我们在新增插件的时候发现会出现duplicate location,意思是所选的anchive所包含的zip路径已经复用,现象如下: 如上图所示黄色标记部分“Duplicate loc ...

  6. 使用Hibernate Tools从数据库逆向生成Hibernate实体类

    自动生成model.java.*.hbm.xml 甚至是dao.java.*.ddl.*.html等等.一般也就如下三种方式1. MyEclipse 自带插件2. jboss的 hibernate-t ...

  7. Eclipse中通过Hibernate Tools插件实现从数据库逆向生成Hibernate带注解的实体类

    一.安装hibernate tools插件 1.在线安装 通过Eclipse的Help->Install New Software 在线安装插件,插件连接为: eclipse helios(3. ...

  8. 利用Hibernate注解生成表

    转自:http://blog.csdn.net/madison__/article/details/55677099 Hibernate4注释 @Entity(name = "tbl_use ...

  9. eclipse中怎么添加Hibernate tools

    最近在学习Hibernate框架,但是用eclipse的时候发现自己安装的过程不是很顺利,因此记下来,供自己和别人参考. Hibernate Tools是由JBoss推出的一个Eclipse集成开发工 ...

随机推荐

  1. GAN笔记——理论与实现

    GAN这一概念是由Ian Goodfellow于2014年提出,并迅速成为了非常火热的研究话题,GAN的变种更是有上千种,深度学习先驱之一的Yann LeCun就曾说,"GAN及其变种是数十 ...

  2. JavaWeb学习 (十)————Cookie

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  3. BGP笔记

    BGP:用于AS与AS之间的路由,但现在也越来越多的用在IDC内部了 BGP是应用层协议,应用TCP协议(唯一一个运用TCP的路由协议) IGP和EGP的区别:IGP运行在一个AS之内,EGP运行在A ...

  4. Mybatis 3 配置 Log4j

    Mybatis与Log4j 最常用的日志输出是Log4j,将相应的jar包和配置文件放到相应的位置,Mybatis就可以通过Log4j将SQL语句打印出来. 配置Log4j.properties 将l ...

  5. int和Integer有什么区别?

    Java提供两种不同的类型:引用类型和原始类型(或内置类型): int是Java的原始数据类型,Integer是java为int提供的封装类. java为每个原始类型提供了封装类: 原始类型:bool ...

  6. SignalR 自寄宿

    源代码 https://github.com/xlb378917466/Chat.Server 1.使用控制台程序来寄宿SignalR的服务端,这需要借助于Owin中间件, 2.实现一个服务端的Cha ...

  7. [转载] C# 调用C++ DLL 的类型转换

    //C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byt ...

  8. Java程序设计概述

    摘要:1996年Java第一次发布就引起了人们的广大关注.本文简要地介绍一下Java语言的发展历史. 一.Java程序设计平台 Java是一种优秀的程序设计语言.一旦一种语言应用于某个领域,与现存代码 ...

  9. 【redis】7、redis用法总结

    Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 一.redis优点 Redis支持数据的持久化,可以将内存中 ...

  10. jsp使用servlet实现用户登录 及动态验证码

    在进行表单设计中,验证码的增加恰恰可以实现是否为“人为”操作,增加验证码可以防止网站数据库信息的冗杂等... 现在,我将讲述通过servlet实现验证码: 验证码作为一个图片,在页面中为“画”出来的, ...