成長(zhǎng)的記憶

          整理學(xué)習(xí)中的心得體會(huì),記錄開發(fā)中的酸甜苦辣,這是成長(zhǎng)的記憶

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            5 隨筆 :: 0 文章 :: 36 評(píng)論 :: 0 Trackbacks
          最近做項(xiàng)目時(shí),使用Hibernate Tools 3.2.4生成entity和hbm.xml,但默認(rèn)情況下,DB中的comments沒法生成到j(luò)avadoc和xml中,改了templates倒是有注釋了,但卻是亂碼,心里一直耿耿于懷...(這不符合咱一直強(qiáng)調(diào)的編碼規(guī)范不是?最主要的是人懶,有時(shí)用entity不想再找文檔)。在網(wǎng)上找了半天,大多說是freemarker編碼設(shè)置問題,但不管怎么設(shè)置,都沒一點(diǎn)效果,決定自己動(dòng)手。下了源碼,查到原因,人家壓根就沒處理中文問題。記錄一下處理過程。

          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>     * 設(shè)置 ${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

          補(bǔ)充:
          無法取得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);
                  }

              }

          外鍵默認(rèn)生成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) 評(píng)論(23)  編輯  收藏 所屬分類: Hibernate

          評(píng)論

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

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

          http://www.aygfsteel.com/pauliz/archive/2010/01/25/310754.html  回復(fù)  更多評(píng)論
            

          # re: Hibernate Tools生成注釋 2010-05-28 14:31 James Liu
          請(qǐng)問如何得到其源代碼進(jìn)行修改?  回復(fù)  更多評(píng)論
            

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

          http://anonsvn.jboss.org/repos/hibernate/trunk/HibernateExt/tools/
            回復(fù)  更多評(píng)論
            

          # re: Hibernate Tools生成注釋 2010-06-04 17:55 James Liu
          @小牧
          多謝,不過修改好后發(fā)現(xiàn)外鍵關(guān)系沒有生成了。  回復(fù)  更多評(píng)論
            

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

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

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

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

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

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

          # 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";
          }  回復(fù)  更多評(píng)論
            

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

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

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

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

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

          # 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();
          }

            回復(fù)  更多評(píng)論
            

          # 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;
          }

            回復(fù)  更多評(píng)論
            

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

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

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

          https://github.com/hibernate/hibernate-tools/  回復(fù)  更多評(píng)論
            

          # re: Hibernate Tools生成注釋 2013-07-02 16:15 SHELL
          關(guān)于無法取得MySQL5 Table的Comments的問題,樓主的修改源碼的方案是可行的。當(dāng)我從GitHub獲取了hibernate-tools源碼,并修改了“org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect”類之后,問題解決了。
          這時(shí)候,我突然想到個(gè)問題,既然是通過JDBC獲取數(shù)據(jù)庫(kù)元信息,沒有獲取到,應(yīng)該是數(shù)據(jù)庫(kù)廠商JDBC驅(qū)動(dòng)有問題,為什么要去修改hibernate-tools的源碼呢?
          最后我找到了MySQL驅(qū)動(dòng)的這個(gè)bug(http://bugs.mysql.com/bug.php?id=65213),并從該bug頁(yè)找到了解決方案:
          修改MySQL JDBC驅(qū)動(dòng)URL,在其后追加:“?useUnicode=true&amp;characterEncoding=UTF-8&amp;useInformationSchema=true”即可。  回復(fù)  更多評(píng)論
            

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

          # re: Hibernate Tools生成注釋 2015-02-03 18:19 馬行空
          大神,請(qǐng)問怎么讓hibernate tools默認(rèn)accesstype是field啊,求教  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 民乐县| 鄄城县| 红河县| 龙门县| 当雄县| 溧水县| 西乡县| 樟树市| 忻城县| 兴仁县| 阳西县| 青龙| 轮台县| 蒙城县| 赣榆县| 泗洪县| 丹东市| 清徐县| 双柏县| 蒲江县| 烟台市| 稷山县| 岑巩县| 贵溪市| 聂荣县| 时尚| 蓬安县| 客服| 金坛市| 石渠县| 洪洞县| 定远县| 漯河市| 玛多县| 嫩江县| 六安市| 婺源县| 山东省| 安远县| 连江县| 陈巴尔虎旗|