成長的記憶

          整理學習中的心得體會,記錄開發中的酸甜苦辣,這是成長的記憶

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            5 隨筆 :: 0 文章 :: 36 評論 :: 0 Trackbacks
          最近做項目時,使用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
          。。。
          posted on 2009-11-13 00:20 小牧 閱讀(9500) 評論(23)  編輯  收藏 所屬分類: Hibernate

          評論

          # re: Hibernate Tools生成注釋 2010-01-22 11:21 zuiwoguzhu
          把它弄好,發布出來,謝謝了!  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-01-25 17:45 小牧
          @zuiwoguzhu

          http://www.aygfsteel.com/pauliz/archive/2010/01/25/310754.html  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-05-28 14:31 James Liu
          請問如何得到其源代碼進行修改?  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-06-01 08:22 小牧
          @James Liu

          http://anonsvn.jboss.org/repos/hibernate/trunk/HibernateExt/tools/
            回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-06-04 17:55 James Liu
          @小牧
          多謝,不過修改好后發現外鍵關系沒有生成了。  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-06-04 22:34 小牧
          @James Liu

          所有的修改都沒有涉及外鍵,不知你是否改到其他地方?
          或者最新的trunk代碼已做了不同處理
          如果沒有其他需求的話,直接到http://www.aygfsteel.com/pauliz/archive/2010/01/25/310754.html 下載修改好的jar包替換吧  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-06-06 07:47 James Liu
          再次表示感謝,原來我用的是3.3的版本,修改之前就不能生成外鍵關系。我測試的是MYSQL數據庫,不知其他數據庫能否生成?  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-06-07 08:39 James Liu
          @小牧
          用oracle試過了,能生成外鍵關系,但是不能生成注釋,呵呵。  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 00:24 yangghost
          用oracle生成不了注釋..測試過了..
          中文問題最關鍵的地方還是
          org.hibernate.tool.hbm2x.TemplateHelper類
          在freeMarkerEngine = new Configuration();后面添加
          freeMarkerEngine.setDefaultEncoding("UTF-8");
          要不然還是會亂碼
            回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 00:25 yangghost
          生成LIST使用的是
          Collection collection = new org.hibernate.mapping.List(rc); // MASTER TODO: allow overriding collection type
          你那個是生成collection的
            回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 00:29 yangghost
          oracle在主鍵字段生成為long不是Long的原因
          org.hibernate.cfg.reveng.JDBCToHibernateTypeHelper類
          public static String getPreferredHibernateType(int sqlType, int size, int precision, int scale, boolean nullable, boolean generatedIdentifier)方法中
          把為空的判斷去掉.全部返回包裝類.
          if (precision == 1) {
          // NUMERIC(1) is a often used idiom for storing boolean thus providing it out of the box.
          return returnNullable?Boolean.class.getName():"boolean";
          }
          else if (precision < 3) {
          return Byte.class.getName();
          }
          else if (precision < 5) {
          return Short.class.getName();
          }
          else if (precision < 10) {
          return Integer.class.getName();
          }
          else if (precision < 19) {
          return Long.class.getName();
          }
          else {
          return "big_decimal";
          }  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 04:49 yangghost
          終于把oracle注釋和模板都改好了...哈哈
          快5點了.天亮了..汗..
          果然是個舊東西...還是要自己改改..  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 23:50 小牧
          @yangghost
          以上修改只在Hibernate Tools 3.2.4、MySQL 5.1.39上做了測試,其他數據庫沒有跑過  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-22 23:55 小牧
          @yangghost
          生成LIST使用的是
          Collection collection = new org.hibernate.mapping.List(rc); // MASTER TODO: allow overriding collection type
          你那個是生成collection的

          org.hibernate.mapping.Bag(rc)沒有問題,根據Hibernate API,Bag是集合類型,一般映射為List,在hbm.xml中也是<bag />,我一直這么用  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-23 23:22 yangghost
          小牧你有QQ么?加我88241787,討論下
          我用這個org.hibernate.mapping.Bag(rc)類,
          在oracle下生成的是Collection 不是List
          現在在oracle下表注釋和列注釋我都弄好了.
          明天再把代碼貼上來  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-24 23:13 yangghost
          列注釋
          JDBCReaderFactory類中
          newMetaDataDialect方法中
          在if(dialect!=null) { // temporary hack to enable dialect specific metadata dialects. 里面的代碼改為
          if(dialect instanceof Oracle9Dialect) {
          return new OracleMetaDataDialect();
          } else if (dialect instanceof Oracle9iDialect) {
          return new OracleMetaDataDialect();
          } else if (dialect instanceof OracleDialect) {
          return new OracleMetaDataDialect();
          } else if (dialect instanceof H2Dialect) {
          return new H2MetaDataDialect();
          } else if (dialect instanceof MySQLDialect) {
          return new MySQLMetaDataDialect();
          }

            回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-24 23:15 yangghost
          表注釋
          TableIdentifier類中
          增加屬性
          private String comment = "";
          以及set & get方法
          public String getComment() {
          return comment;
          }

          public void setComment(String comment) {
          this.comment = comment;
          }

            回復  更多評論
            

          # re: Hibernate Tools生成注釋 2010-10-26 11:24 小牧
          @yangghost
          應該沒有改其他地方,直接就生成List,不過是在MySQL上測試,Oracle沒試,照理說應該一樣  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2012-04-17 14:27 dingbowell
          求急助。在哪兒可以找到Hibernate Tools 3.4.0的源碼吖,請問樓主是怎么找到源碼的,我需要改文件中的代碼,但需要源碼啊……  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2012-04-17 14:42 小牧
          @dingbowell
          在這里找一下吧
          http://sourceforge.net/projects/hibernate/files/

          https://github.com/hibernate/hibernate-tools/  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2013-07-02 16:15 SHELL
          關于無法取得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”即可。  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2015-02-03 18:17 馬行空
          大神,類的表comment還沒有呢  回復  更多評論
            

          # re: Hibernate Tools生成注釋 2015-02-03 18:19 馬行空
          大神,請問怎么讓hibernate tools默認accesstype是field啊,求教  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 同德县| 启东市| 天峻县| 樟树市| 黄陵县| 永年县| 承德县| 孝义市| 荃湾区| 阳新县| 翼城县| 朝阳县| 察隅县| 湄潭县| 望江县| 红桥区| 宝丰县| 定兴县| 巴东县| 同心县| 藁城市| 云梦县| 贡嘎县| 鄂伦春自治旗| 确山县| 青铜峡市| 临汾市| 新余市| 资兴市| 甘孜县| 岑巩县| 萨嘎县| 策勒县| 施甸县| 西安市| 兰考县| 巨野县| 昔阳县| 西乡县| 太康县| 双鸭山市|