zoukankan      html  css  js  c++  java
  • Hibernate映射文件生成器by LDDXFS

    本文由 http://www.cnblogs.com/LDDXFS/ 原创,转载请注明本文出处。(新版本的代码生成器写好了,新版本设计上更合理,会在近期对其进行相关介绍,打算在工作稳定后开源,本文为旧版本)

    关于代码生成器,JBOSS的Hibernate Tool插件也有hbm.xml生成功能,自己写这个生成器的目的是为了代码简洁一些

    1作用

    它根据.properties文件上定义的参数扫描某文件夹下XXX.java文件, 依据xml模板文件生成Hibernate的映射文件 XXX.hbm.xml

    可以提取XXX.java文件中字段上的doc注释到XXX.hbm.xml文件对应的配置上

    支持的关联关系有 一对一,一对多Set List,多对一。

    最终 生成的hbm.xml文件如下

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <hibernate-mapping package="cn.lddxfs.tieba.domain">
     5     <class name="AdminUser" table="tiebaTB_AdminUser">
     6 <!--id-->
     7 <id name="id" column="id">
     8     <generator class="native"></generator>
     9 </id>
    10 <!--用户名-->
    11 <property name="name" unique="true"></property>
    12 <!--邮箱,登陆时使用-->
    13 <property name="email" unique="true"></property>
    14 <!--密码-->
    15 <property name="password"></property>
    16 <!--UUID用于激活-->
    17 <property name="uuid"></property>
    18 <!--状态,已经启用,为激活-->
    19 <!-- status属性,表达的是本类AdminUser与DataDictoryValue的多对一 
    20     class属性:关联的实体类型
    21     column属性:外键列(引用关联对象的表的主键)
    22 -->
    23 <many-to-one name="status" class="DataDictoryValue" column="statusId"></many-to-one>
    24 <!--居民身份证-->
    25 <property name="idcard"></property>
    26 <!--审核了那些吧-->
    27 <!-- baApply属性,List集合,表达的是本类与BaApply的一对多 
    28     class属性:关联的实体类型
    29     key子元素:对方表中的外键列(多方的那个表)
    30             
    31     inverse属性:
    32         默认为false,表示本方维护关联关系。
    33         如果为true,表示本方不维护关联关系。
    34         只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响。
    35                 
    36     cascade属性:
    37         默认为none,代表不级联。
    38         级联是指操作主对象时,对关联的对象也做相同的操作。
    39         可设为:delete, save-update, all, none ...
    40                 
    41     lazy属性:懒加载,默认为true。
    42         true:懒加载,在第一次使用时加载。
    43         false:立即加载,在获取本对象时就加载这个集合的所有元素。
    44         extra:增强的懒加载策略。
    45 -->
    46 <set name="baApply">
    47     <key column="adminUserId"></key>
    48     <one-to-many class="BaApply"/>
    49 </set>
    50 </class>
    51 </hibernate-mapping>

    2依赖的jar文件

    3模板文件  src/generator/template/template.xml

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <beanCache>
      3     <XMLBeans>
      4         <XMLBean>
      5             <type><![CDATA[hbmhead]]></type>
      6             <note></note>
      7             <value>
      8 <![CDATA[
      9 <?xml version="1.0"?>
     10 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     11 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     12 <hibernate-mapping package="<%package%>">
     13     <class name="<%Class%>" table="<%tableprefix%><%Class%>">
     14 ]]>
     15             </value>
     16         </XMLBean>
     17         <XMLBean>
     18             <type><![CDATA[id]]></type>
     19             <note></note>
     20             <value>
     21 <![CDATA[
     22 <id name="<%key%>" column="<%keyColumn%>">
     23     <generator class="native"></generator>
     24 </id>
     25 ]]>
     26             </value>
     27         </XMLBean>
     28         <XMLBean>
     29             <type><![CDATA[hbmfoot]]></type>
     30             <note></note>
     31             <value>
     32 <![CDATA[
     33     </class>
     34 </hibernate-mapping>
     35 ]]>
     36             </value>
     37         </XMLBean>
     38         <XMLBean>
     39             <type><![CDATA[property]]></type>
     40             <note></note>
     41             <value>
     42 <![CDATA[
     43     <property name="<%field%>"></property>
     44 ]]>
     45             </value>
     46         </XMLBean>
     47         <XMLBean>
     48             <type><![CDATA[picture]]></type>
     49             <note></note>
     50             <value>
     51 <![CDATA[
     52     <property name="<%field%>" length="819200"></property>
     53 ]]>
     54             </value>
     55         </XMLBean>
     56         <XMLBean>
     57             <type><![CDATA[111]]></type>
     58             <note>
     59 <![CDATA[
     60 <!--<%field%>属性,<%Field%>类型。
     61     表达的是本类<%Class%>与<%Field%>的一对一。
     62     采用基于外键的一对一映射方式,本方<%Field%>是有外键方。
     63 -->
     64 ]]>
     65             </note>
     66             <value>
     67 <![CDATA[
     68 <many-to-one name="<%field%>" class="<%Field%>" column="<%field%>Id" unique="true"></many-to-one>
     69 ]]>
     70             </value>
     71         </XMLBean>
     72         <XMLBean>
     73             <type><![CDATA[110]]></type>
     74             <note>
     75 <![CDATA[
     76 <!-- <%field%>属性,<%Field%>类型。
     77     表达的是本类<%Class%>与<%Field%>的一对一。
     78     采用基于外键的一对一映射方式,本方<%Class%>是无外键方。
     79     property-ref属性:
     80         写的是对方<%Field%>映射中外键列对应的属性名<%class%>。    
     81 -->
     82 ]]>
     83             </note>
     84             <value>
     85 <![CDATA[
     86 <one-to-one name="<%field%>" class="<%Field%>" property-ref="<%class%>"/>
     87 ]]>
     88             </value>
     89         </XMLBean>
     90         <XMLBean>
     91             <type><![CDATA[1nSet]]></type>
     92             <note>
     93 <![CDATA[
     94 <!-- <%field%>属性,Set集合,表达的是本类与<%Field%>的一对多 
     95     class属性:关联的实体类型
     96     key子元素:对方表中的外键列(多方的那个表)
     97             
     98     inverse属性:
     99         默认为false,表示本方维护关联关系。
    100         如果为true,表示本方不维护关联关系。
    101         只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响。
    102                 
    103     cascade属性:
    104         默认为none,代表不级联。
    105         级联是指操作主对象时,对关联的对象也做相同的操作。
    106         可设为:delete, save-update, all, none ...
    107                 
    108     lazy属性:懒加载,默认为true。
    109         true:懒加载,在第一次使用时加载。
    110         false:立即加载,在获取本对象时就加载这个集合的所有元素。
    111         extra:增强的懒加载策略。
    112 -->
    113 ]]>
    114             </note>
    115             <value>
    116 <![CDATA[
    117 <set name="<%field%>" cascade="all" lazy="true">
    118     <key column="<%class%>Id"></key>
    119     <one-to-many class="<%Field%>"/>
    120 </set>
    121 ]]>
    122             </value>
    123         </XMLBean>
    124         <XMLBean>
    125             <type><![CDATA[1nList]]></type>
    126             <note>
    127 <![CDATA[
    128 <!-- <%field%>属性,List集合,表达的是本类与<%Field%>的一对多 
    129     class属性:关联的实体类型
    130     key子元素:对方表中的外键列(多方的那个表)
    131             
    132     inverse属性:
    133         默认为false,表示本方维护关联关系。
    134         如果为true,表示本方不维护关联关系。
    135         只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响。
    136                 
    137     cascade属性:
    138         默认为none,代表不级联。
    139         级联是指操作主对象时,对关联的对象也做相同的操作。
    140         可设为:delete, save-update, all, none ...
    141                 
    142     lazy属性:懒加载,默认为true。
    143         true:懒加载,在第一次使用时加载。
    144         false:立即加载,在获取本对象时就加载这个集合的所有元素。
    145         extra:增强的懒加载策略。
    146 -->
    147 ]]>
    148             </note>
    149             <value>
    150 <![CDATA[
    151 <list name="<%field%>">
    152     <key column="<%class%>Id"></key>
    153     <list-index column="<%Class%>_<%field%>_idx"></list-index>
    154     <one-to-many class="<%Field%>"/>
    155 </list>
    156 ]]>
    157             </value>
    158         </XMLBean>
    159         <XMLBean>
    160             <type><![CDATA[n1]]></type>
    161             <note>
    162 <![CDATA[
    163 <!-- <%field%>属性,表达的是本类<%Class%>与<%Field%>的多对一 
    164     class属性:关联的实体类型
    165     column属性:外键列(引用关联对象的表的主键)
    166 -->
    167 ]]>
    168             </note>
    169             <value>
    170 <![CDATA[
    171 <many-to-one name="<%field%>" class="<%Field%>" column="<%field%>Id"></many-to-one>
    172 ]]>
    173             </value>
    174         </XMLBean>
    175         <XMLBean>
    176             <type><![CDATA[nnSet]]></type>
    177             <note>
    178 <![CDATA[
    179 <!-- <%field%>属性,Set集合。
    180     表达的是本类<%Class%>与<%Field%>的多对多。    
    181     table属性:中间表(集合表)
    182     key子元素:集合外键(引用当前表主键的那个外键)
    183 -->
    184 ]]>
    185             </note>
    186             <value>
    187 <![CDATA[
    188 <set name="<%field%>" table="<%tableprefix%><%centerTable%>" inverse="false">
    189     <key column="<%class%>Id"></key>
    190     <many-to-many class="<%Field%>" column="<%field%>Id"></many-to-many>
    191 </set>
    192 ]]>
    193             </value>
    194         </XMLBean>
    195         <XMLBean>
    196             <type><![CDATA[nnList]]></type>
    197             <note>
    198 <![CDATA[
    199 <!-- <%field%>属性,List集合。
    200     表达的是本类<%Class%>与<%Field%>的多对多。    
    201     table属性:中间表(集合表)
    202     key子元素:集合外键(引用当前表主键的那个外键)
    203 -->
    204 ]]>
    205             </note>
    206             <value>
    207 <![CDATA[
    208 <list name="<%field%>" table="<%tableprefix%><%centerTable%>" inverse="false">
    209     <key column="<%class%>Id"></key>
    210     <list-index column="<%Class%>_<%field%>_idx"></list-index>
    211     <many-to-many class="<%Field%>" column="<%field%>Id"></many-to-many>
    212 </list>
    213 ]]>
    214             </value>
    215         </XMLBean>
    216     </XMLBeans>
    217 </beanCache>
    View Code

    4properties文件  src/generator/generator.properties

     1 #项目名称
     2 project=cn.lddxfs.tieba
     3 #实体所在包名
     4 package=cn.lddxfs.tieba.domain
     5 #实体所在包相对路径
     6 #pathname=src/cn/lddxfs/tieba/domain/
     7 #数据库中表前缀
     8 tableprefix=tiebaTB_
     9 #实体唯一标示符
    10 key=id
    11 #数据库表主键名
    12 keyColumn=id
    13 #中间表
    14 #centerTable=<%Class%>_<%Field%>
    View Code

    5 java文件

    src/generator/XMLBean.java

     1 package generator;
     2 
     3 public class XMLBean {
     4 
     5     /**
     6      * <pre>
     7      * 基本类型 
     8      * 
     9      * 本方                                          对方
    10      * 一对一主键                            一对一外键
    11      * ClassA key        ClassB
    12      * 
    13      * 一对多List                    多对一 
    14      * List《ClassA》              ClassB
    15      * 
    16      * 一对多Set           多对一 
    17      * Set《ClassA》               ClassB
    18      * 
    19      * 多对多List          多对多List
    20      * List《ClassA》             List《ClassB》
    21      * 
    22      * 多对多Set           多对多Set
    23      * Set《ClassA》               Set《ClassB》
    24      *  dynamic-update="true"
    25         dynamic-insert="true"
    26      * </pre>
    27      */
    28     /**
    29      * 关联关系类型
    30      */
    31     private String type;
    32     /**
    33      * 注释
    34      */
    35     private String note;
    36     /**
    37      * 内容,通过type来指定
    38      */
    39     private String value;
    40 
    41     public String getType() {
    42         return type;
    43     }
    44 
    45     public void setType(String type) {
    46         this.type = type;
    47     }
    48 
    49     public String getNote() {
    50         return note;
    51     }
    52 
    53     public void setNote(String note) {
    54         this.note = note;
    55     }
    56 
    57     public String getValue() {
    58         return value;
    59     }
    60 
    61     public void setValue(String value) {
    62         this.value = value;
    63     }
    64 
    65 }
    View Code

    src/generator/XMLBeanCache.java

     1 package generator;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 public class XMLBeanCache {
     7 
     8     private Map<String, XMLBean> XMLBeanMap = new HashMap<String, XMLBean>();
     9     private Boolean hasNote;
    10 
    11     public Boolean getHasNote() {
    12         return hasNote;
    13     }
    14 
    15     public void setHasNote(Boolean hasNote) {
    16         this.hasNote = hasNote;
    17     }
    18 
    19     public Map<String, XMLBean> getXMLBeanMap() {
    20         return XMLBeanMap;
    21     }
    22 
    23     public void setXMLBeanMap(Map<String, XMLBean> xMLBeanMap) {
    24         XMLBeanMap = xMLBeanMap;
    25     }
    26 
    27     /**
    28      * 
    29      * @param key
    30      *            map的key
    31      * @return 字符串,hashMap的value 中的XMLBean的内容
    32      */
    33     public String getXMLBeanStr(String key) {
    34         XMLBean xmlBean = this.XMLBeanMap.get(key);
    35         if (hasNote) {
    36             if (xmlBean.getNote()==null||"".equals(xmlBean.getNote().trim())) {
    37                 return xmlBean.getNote() + xmlBean.getValue() + '
    ';
    38             } else {
    39                 return xmlBean.getNote() + '
    ' + xmlBean.getValue() + '
    ';
    40             }
    41         }
    42         return xmlBean.getValue() + '
    ';
    43     }
    44 
    45     // 供Digester调用的方法
    46     public void addXMLBean(XMLBean xMLBean) {
    47         this.XMLBeanMap.put(xMLBean.getType(), xMLBean);
    48 
    49     }
    50 }
    View Code

    src/generator/XMLBeanDigester.java

     1 package generator;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.FileInputStream;
     5 import java.io.IOException;
     6 import java.io.InputStream;
     7 import java.io.InputStreamReader;
     8 
     9 import org.apache.commons.digester3.Digester;
    10 import org.xml.sax.SAXException;
    11 
    12 public class XMLBeanDigester {
    13      public XMLBeanCache digester() throws Exception {  
    14             Digester digester = new Digester();  
    15             digester.setValidating(false);  
    16             digester.addObjectCreate("beanCache/XMLBeans", XMLBeanCache.class);  
    17             // 指明匹配模式和要创建的类   
    18             digester.addObjectCreate("beanCache/XMLBeans/XMLBean", XMLBean.class);  
    19             // 设置对象属性,与xml文件对应,不设置则是默认  
    20             digester.addBeanPropertySetter("beanCache/XMLBeans/XMLBean/type", "type");   
    21             digester.addBeanPropertySetter("beanCache/XMLBeans/XMLBean/note", "note");   
    22             digester.addBeanPropertySetter("beanCache/XMLBeans/XMLBean/value", "value");   
    23   
    24   
    25             // 当移动到下一个标签中时的动作  
    26             digester.addSetNext("beanCache/XMLBeans/XMLBean", "addXMLBean");  
    27               
    28             XMLBeanCache bc = null;  
    29             try {  
    30                 
    31                 InputStream inputStream = new FileInputStream("src/generator/template/template.xml");
    32 
    33                 BufferedReader bufferedReader = new BufferedReader(
    34                         new InputStreamReader(inputStream, "UTF-8"));
    35                 
    36                 bc = (XMLBeanCache) digester.parse(bufferedReader);
    37 //                bc = (BeanCache) digester.parse("beanCache.xml");  
    38             } catch (IOException e) {  
    39                 throw new Exception(e);  
    40             } catch (SAXException e) {  
    41                 throw new Exception(e);  
    42             }  
    43             return bc;
    44         }  
    45 }
    View Code

    src/generator/GlobalVar.java

      1 package generator;
      2 
      3 import java.io.File;
      4 import java.io.FileInputStream;
      5 import java.io.InputStream;
      6 import java.util.LinkedList;
      7 import java.util.List;
      8 import java.util.Properties;
      9 
     10 public class GlobalVar {
     11     /**
     12      * 基本数据类型
     13      */
     14     protected String[] BASE_TYPE = new String[] { "Integer", "Long", "String",
     15             "Date", "Boolean","Blob","Clob" };
     16     /**
     17      * 数组类型
     18      */
     19     protected String[] ARRAY_TYPE = new String[] { "byte[]", "Byte[]" };
     20     /**
     21      * 集合数据类型
     22      */
     23     protected String[] COLLECTION_TYPE = new String[] { "List", "Set" };
     24     /**
     25      * 配置文件的路径
     26      */
     27     protected String PROPERTIES_LOCATION = "src/generator/generator.properties";
     28     /**
     29      * 源码文件夹
     30      */
     31     protected String SRC_PATH = "src/";
     32     /**
     33      * class文件的文件编码
     34      */
     35     protected String CHARSET_NAME = "UTF-8";
     36     protected String[] DOMAIN_TYPE = new String[] {};
     37     protected Properties PROPS;
     38     protected String PACKAGE_Str;
     39     protected String PATHNAME;
     40 
     41     public GlobalVar() {
     42         /* 加载资源文件 */
     43         PROPS = new Properties();
     44         InputStream is;
     45         try {
     46             is = new FileInputStream(PROPERTIES_LOCATION);
     47             PROPS.load(is);
     48         } catch (Exception e) {
     49             // TODO Auto-generated catch block
     50             e.printStackTrace();
     51         }
     52 
     53         // 得到包名
     54         PACKAGE_Str = PROPS.getProperty("package");
     55         // 得到路径名 pathname=src/cn/lddxfs/tieba/domain/
     56         PATHNAME = SRC_PATH + PACKAGE_Str.replace('.', '/') + "/";
     57 
     58         // logger.debug("pathname=" + pathname);
     59         /* 得到路径名,得到domain类名迭代器 */
     60         File dir = new File(PATHNAME);
     61         List<String> classNameList = new LinkedList<String>();
     62         listClassName(dir, classNameList);
     63         // Iterator<String> classNameit1 = classNameList.iterator();
     64 
     65         DOMAIN_TYPE = classNameList.toArray(new String[0]);
     66         for(String name:DOMAIN_TYPE){
     67             System.out.println(name);
     68         }
     69 
     70     }
     71 
     72     /**
     73      * 列出指定目录下的java文件的类名 ,例如 如果有文件“Person.java” ,则列出“Person”
     74      * 
     75      * @param file
     76      *            指定一个目录
     77      * @param classNameList
     78      *            返回的类名列表 ,无“.java”后缀
     79      */
     80     private void listClassName(File file, List<String> classNameList) {
     81         if (file == null) {
     82             return;
     83         }
     84         if (file.isDirectory()) {
     85             File f[] = file.listFiles();
     86             if (f != null)
     87                 for (int i = 0; i < f.length; i++) {
     88                     listClassName(f[i], classNameList);
     89                 }
     90         } else {
     91 
     92             if (file.getName().endsWith(".java")) {
     93                 String str = (file.getName().substring(0, file.getName()
     94                         .length() - 5));
     95 
     96                 classNameList.add(str);
     97             }
     98         }
     99     }
    100 
    101 }

    一个重点

    src/generator/DomainGenerator.java

      1 package generator;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileInputStream;
      6 import java.io.FileNotFoundException;
      7 import java.io.FileOutputStream;
      8 import java.io.InputStream;
      9 import java.io.InputStreamReader;
     10 import java.io.OutputStreamWriter;
     11 import java.lang.reflect.Field;
     12 import java.lang.reflect.ParameterizedType;
     13 import java.lang.reflect.Type;
     14 import java.util.Iterator;
     15 import java.util.List;
     16 import java.util.Set;
     17 import java.util.regex.Matcher;
     18 import java.util.regex.Pattern;
     19 
     20 import org.apache.log4j.Logger;
     21 import org.junit.Test;
     22 
     23 import cn.lddxfs.tieba.domain.DataDictory;
     24 import cn.lddxfs.tieba.domain.DataDictoryValue;
     25 
     26 public class DomainGenerator extends GlobalVar {
     27 
     28     private Logger logger = Logger.getLogger(DomainGenerator.class);
     29 
     30     /**
     31      * 设置是否显示注释
     32      */
     33     private Boolean HAS_NOTE = true;
     34 
     35     /**
     36      * 
     37      * @throws Exception
     38      */
     39     @Test
     40     public void generatorHBMXML() throws Exception {
     41         /**
     42          * 遍历
     43          */
     44         XMLBeanDigester xmlBeanDigester = new XMLBeanDigester();
     45         XMLBeanCache xmlBeanCache = xmlBeanDigester.digester();
     46         xmlBeanCache.setHasNote(HAS_NOTE);
     47         /**
     48          * Map<String, XMLBean> xmlBeanMap = xmlBeanCache.getXMLBeanMap();
     49          * Set<String> beantypeSet = xmlBeanMap.keySet(); Iterator<String>
     50          * beantypeSetit = beantypeSet.iterator(); while
     51          * (beantypeSetit.hasNext()) { String beantype = beantypeSetit.next();
     52          * XMLBean xmlBean = xmlBeanMap.get(beantype);
     53          * System.out.println(xmlBean.getType());
     54          * System.out.println(xmlBean.getValue());
     55          * 
     56          * }
     57          */
     58         /**
     59          * <pre>
     60          * 生成hbm.xml文件的思路: 
     61          *  1 遍历完一个类就直接写出到文件
     62          *  2 遍历完所有类才写,这种方式实现复杂并且需要消耗较多系统资源,不宜采用
     63          * 对于1 ,文件的命名为 “实体名.temp”, 存放到properties文件 给出的package下
     64          * 
     65          * <pre>
     66          */
     67         // 部分 new String[]{"Level","User"} 或全部 DOMAIN_TYPE
     68         for (String domain_type : DOMAIN_TYPE) {
     69             // 得到类全限定名
     70             String className = PACKAGE_Str + "." + domain_type;
     71             // 得到Class对象
     72             Class clazz = Class.forName(className);
     73             // 新建实体对应的Hibernate映射文件.hbm.xml的临时文件.hbm.temp
     74             File classNamehbmFile = new File(PATHNAME + clazz.getSimpleName()
     75                     + ".hbm.xml");
     76             // 存储 .hbm.temp 文件的字符串
     77             StringBuffer hbmFileSB = new StringBuffer();
     78             String hbmFileStr = "";
     79 
     80             hbmFileSB.append(xmlBeanCache.getXMLBeanStr("hbmhead"));
     81 
     82             /**
     83              * 返回 Field 对象的一个数组,这些对象反映此 Class
     84              * 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段
     85              * ,但不包括继承的字段。返回数组中的元素没有排序,也没有任何特定的顺序。如果该类或接口不声明任何字段,或者此 Class
     86              * 对象表示一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
     87              */
     88             Field[] fields = clazz.getDeclaredFields();
     89             logger.debug("className=" + className);
     90             logger.debug("类" + clazz + "的字段如下========");
     91 
     92             System.out.println("DomainGenerator.name()" + clazz.getName()
     93                     + "  {");
     94             for (Field field : fields) {
     95                 // 获得所有Field的类型 不包括泛型Field的 泛型参数
     96                 // 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型
     97                 Class fieldClazz = field.getType();
     98                 /**
     99                  * 
    100                  */
    101                 Class dClazz = null;
    102 
    103                 String fieldClazzSimpleName = fieldClazz.getSimpleName();
    104 
    105                 if (HAS_NOTE) {
    106                     String fieldNote = "<!--" + getNote(field) + "-->
    ";
    107                     hbmFileSB.append(fieldNote);
    108                 }
    109                 // 获得所有泛型的Field
    110                 // 返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。
    111                 // 如果 Type 是一个参数化类型,则返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
    112                 // 如果底层字段的类型是一个类型变量或者是一个参数化类型,则创建它。否则将解析它。
    113                 Type fieldGenericType = field.getGenericType();
    114 
    115                 /*
    116                  * System.out.println(fieldGenericType.toString().replaceAll(
    117                  * "java\.lang\.", ""));
    118                  */
    119 
    120                 /* 如果是类类型 String Byte[] User */
    121                 if (fieldGenericType instanceof Class) {
    122 
    123                     for (String s : BASE_TYPE) {
    124                         if (fieldClazzSimpleName.equals(s)) {
    125                             // TODO 直接创建xml
    126                             if (field.getName()
    127                                     .equals(PROPS.getProperty("key"))) {
    128                                 hbmFileSB.append(xmlBeanCache
    129                                         .getXMLBeanStr("id"));
    130                             } else {
    131                                 hbmFileSB.append(xmlBeanCache
    132                                         .getXMLBeanStr("property"));
    133                                 break;
    134                             }
    135                         }
    136                     }
    137                     for (String s : ARRAY_TYPE) {
    138                         if (fieldClazzSimpleName.equals(s)) {
    139                             // 设置长度
    140                             hbmFileSB.append(xmlBeanCache
    141                                     .getXMLBeanStr("picture"));
    142                             break;
    143                         }
    144                     }
    145 
    146                     for (String s : DOMAIN_TYPE) {
    147                         if (fieldClazzSimpleName.equals(s)) {
    148                             // 实体类型
    149                             dClazz = fieldClazz;
    150                             // 获得对端是0 1 还是 n
    151                             String otherString = Other(clazz, fieldClazz);
    152                             if (otherString.equals("0")) {
    153                                 logger.debug("0对1");// 本方含外键
    154                                 // 多对一
    155                                 hbmFileSB.append(xmlBeanCache
    156                                         .getXMLBeanStr("n1"));
    157                                 System.out.println("0对1默认为多对1"
    158                                         + clazz.getName() + " 中Field "
    159                                         + fieldClazzSimpleName);
    160 
    161                                 // 110
    162                                 break;
    163                             } else if (otherString.equals("1")) {
    164                                 logger.debug("1对1");
    165                                 hbmFileSB.append(xmlBeanCache
    166                                         .getXMLBeanStr("111"));
    167                                 hbmFileSB.append(xmlBeanCache
    168                                         .getXMLBeanStr("110"));
    169                                 System.out.println("1对1请手动指定含外键方  "
    170                                         + clazz.getName() + " 中Field "
    171                                         + fieldClazzSimpleName);
    172                                 // 111 或110
    173                                 break;
    174                             } else if (otherString.equals("n")) {
    175                                 logger.debug("n对1");
    176                                 // n1
    177                                 hbmFileSB.append(xmlBeanCache
    178                                         .getXMLBeanStr("n1"));
    179                                 break;
    180                             }
    181 
    182                         }
    183                     }
    184 
    185                 } else if (fieldGenericType instanceof ParameterizedType) {
    186 
    187                     /* 如果是参数化类型 List<User> List<Tie> List<String> */
    188                     // 得到泛型类java.util.List<cn.lddxfs.tieba.domain.Ba>
    189                     ParameterizedType pt = (ParameterizedType) fieldGenericType;
    190                     Type t1Type = pt.getActualTypeArguments()[0];
    191 
    192                     Class t1Clazz = null;
    193                     if (t1Type instanceof Class) {
    194                         t1Clazz = (Class) t1Type;
    195                     }
    196 
    197                     dClazz = t1Clazz;
    198 
    199                     String t1SimpleName = t1Clazz.getSimpleName();
    200 
    201                     String otherString = Other(clazz, t1Clazz);
    202 
    203                     // System.out.print(fieldClazzSimpleName);
    204 
    205                     if (otherString.equals("0")) {
    206                         System.out.println("0对n默认为1对n" + clazz.getName()
    207                                 + " 中Field " + t1Clazz.getSimpleName());
    208 
    209                         logger.debug("0对n");
    210                         // 1nList或 1nSet
    211                         hbmFileSB.append(xmlBeanCache.getXMLBeanStr("1n"
    212                                 + fieldClazzSimpleName));
    213                     } else if (otherString.equals("1")) {
    214                         logger.debug("1对n");
    215                         // 1nList 或1nSet
    216                         hbmFileSB.append(xmlBeanCache.getXMLBeanStr("1n"
    217                                 + fieldClazzSimpleName));
    218                     } else if (otherString.equals("n")) {
    219                         logger.debug("n对n");
    220                         // nnList 或nnSet
    221                         hbmFileSB.append(xmlBeanCache.getXMLBeanStr("nn"
    222                                 + fieldClazzSimpleName));
    223 
    224                         String centerTableString = "";
    225                         if (dClazz.getSimpleName().compareTo(
    226                                 clazz.getSimpleName()) > 0) {
    227                             centerTableString = dClazz.getSimpleName() + "_"
    228                                     + clazz.getSimpleName();
    229                         } else {
    230                             centerTableString = clazz.getSimpleName() + "_"
    231                                     + dClazz.getSimpleName();
    232                         }
    233                         hbmFileStr = hbmFileSB.toString();
    234                         hbmFileStr = hbmFileStr.replaceAll("<%centerTable%>",
    235                                 centerTableString);
    236 
    237                         hbmFileSB = new StringBuffer(hbmFileStr);
    238                     }
    239                 }
    240 
    241                 logger.debug("fieldClazzSimpleName=" + fieldClazzSimpleName);
    242                 // 字段上的注释
    243 
    244                 // 替换Field 替换field
    245                 hbmFileStr = hbmFileSB.toString();
    246 
    247                 hbmFileStr = hbmFileStr
    248                         .replaceAll("<%field%>", field.getName());
    249                 if (dClazz != null) {
    250                     hbmFileStr = hbmFileStr.replaceAll("<%Field%>",
    251                             dClazz.getSimpleName());
    252                 }
    253                 hbmFileSB = new StringBuffer(hbmFileStr);
    254             }
    255             System.out.println(" }");
    256 
    257             logger.debug("类" + clazz + "的字段如上=====");
    258             hbmFileStr = hbmFileSB.toString();
    259             hbmFileStr += xmlBeanCache.getXMLBeanStr("hbmfoot");
    260             // 替换Class class
    261             hbmFileStr = hbmFileStr.replaceAll("<%Class%>",
    262                     clazz.getSimpleName());
    263             String clazzSimpleString = clazz.getSimpleName().substring(0, 1)
    264                     .toLowerCase()
    265                     + clazz.getSimpleName().substring(1);
    266             hbmFileStr = hbmFileStr.replaceAll("<%class%>", clazzSimpleString);
    267 
    268             // 循环properties文件
    269             Set<String> keySet = PROPS.stringPropertyNames();
    270             Iterator<String> keyIterator = keySet.iterator();
    271             while (keyIterator.hasNext()) {
    272                 String key = (String) keyIterator.next();
    273                 String value = PROPS.getProperty(key);
    274                 // 用properties文件中的键 值替换文件中相应的内容
    275                 hbmFileStr = hbmFileStr.replaceAll("<%" + key + "%>", value);
    276             }
    277 
    278             if (classNamehbmFile.exists()) {
    279                 classNamehbmFile.delete();
    280             }
    281 
    282             // 将hbmFileStr写出到文件
    283             OutputStreamWriter writer = new OutputStreamWriter(
    284                     new FileOutputStream(classNamehbmFile), CHARSET_NAME);
    285             writer.write(hbmFileStr);
    286             writer.flush();
    287             writer.close();
    288 
    289         }
    290         /*
    291          * // BeanInfo表示该Student对象所有的属性情况 BeanInfo bi =
    292          * Introspector.getBeanInfo(clazz); // 取得Student对象所有属性集合
    293          * PropertyDescriptor[] pds = bi.getPropertyDescriptors(); for
    294          * (PropertyDescriptor pd : pds) { System.out.println(pd.getName()); }
    295          */
    296         /*
    297          * 列出文件名 List<File> fileList = new LinkedList<File>(); listFileName(dir,
    298          * fileList); Iterator<File> fileListiterator = fileList.iterator();
    299          * while (fileListiterator.hasNext()) { fileListiterator.next(); }
    300          */
    301     }
    302 
    303     /**
    304      * 获取给定Field类型字段上的java注释
    305      * 
    306      * @param field
    307      * @return
    308      * @throws FileNotFoundException
    309      */
    310     public String getNote(Field field) throws Exception {
    311 
    312         Class fieldClazz = field.getType();
    313         Class clazz = field.getDeclaringClass();
    314 
    315         // System.out.println("fieldClazz=" + fieldClazz.getSimpleName());
    316 
    317         String pathString = SRC_PATH + clazz.getName().replace('.', '/')
    318                 + ".java";
    319 
    320         logger.debug("pathString=" + pathString);// 打印java文件的路径
    321         InputStream inputStream = new FileInputStream(pathString);
    322 
    323         BufferedReader bufferedReader = new BufferedReader(
    324                 new InputStreamReader(inputStream, CHARSET_NAME));
    325         String line;
    326         StringBuffer stringBuffer = new StringBuffer();
    327         while ((line = bufferedReader.readLine()) != null) {
    328             // System.out.println(line);
    329             stringBuffer.append(line);
    330         }
    331         // 得到文件的内容
    332         String fileContent = stringBuffer.toString();
    333 
    334         String REGEX = "\s+/\*\*[,,\s\*0-9A-Za-zu4e00-u9fa5]+(\*/)?\s*private{1}\s*"
    335                 + fieldClazz.getSimpleName().replaceAll("\[\s*\]", "")
    336                 + "((<[A-Za-z]*>)|(\[[A-Za-z]*\]))*"
    337                 + "\s*"
    338                 + field.getName()
    339                 + "\s*"
    340                 + "(=\s*new\s*[A-Za-z]*\s*<[A-Za-z]*>\s*\(\s*\))?"
    341                 + "\s*;{1}";
    342         // =new LinkedList<Ba>()
    343         /* 匹配语法 */
    344         // private Field field;
    345         Pattern p = Pattern.compile(REGEX);
    346         Matcher m = p.matcher(fileContent); // 获取 matcher 对象
    347         int count = 0;
    348         String remarkString = "";
    349         while (m.find()) {
    350             count++;
    351             remarkString = fileContent.substring(m.start(), m.end());
    352             logger.debug("finded a remark=" + remarkString);
    353         }
    354         if (count != 1) {
    355             System.out.println("匹配不正确,无法找到方法上注释" + clazz.getName() + "   "
    356                     + fieldClazz.getName() + " " + field.getName());
    357 
    358         }
    359         bufferedReader.close();
    360 
    361         return remarkString.substring(0, remarkString.lastIndexOf("*/"))
    362                 .replaceAll("\*", "").replaceAll("/", "").trim();
    363     }
    364 
    365     // //////////////////////
    366     @Test
    367     public void initDataDictory() throws Exception {
    368 
    369         for (String domain_type : DOMAIN_TYPE) {
    370             // 得到类全限定名
    371             String className = PACKAGE_Str + "." + domain_type;
    372             // 得到Class对象
    373             Class clazz = Class.forName(className);
    374             Field[] fields = clazz.getDeclaredFields();
    375             for (Field field : fields) {
    376                 if (field.getType().equals(DataDictoryValue.class)) {
    377 
    378                     
    379                     DataDictory dataDictory = new DataDictory();
    380                     dataDictory.setKeyWord(clazz.getSimpleName()+field.getName());
    381                     dataDictory.setRemark(clazz.getSimpleName()+getNote(field));
    382                     
    383                              
    384                             
    385                     System.out.println("INSERT into tiebatb_datadictory(keyWord,remark) VALUES('"+clazz.getSimpleName()+"','"+clazz.getSimpleName()+getNote(field)+"');");
    386                 }
    387                 ;
    388             }
    389         }
    390     }
    391 
    392     /**
    393      * 列出指定目录下的java文件名
    394      * 
    395      * @param file
    396      *            指定一个目录
    397      * @param fileList
    398      *            返回的类名列表 ,无“.java”后缀
    399      */
    400     @Deprecated
    401     public void listFileName(File file, List<File> fileList) {
    402         if (file == null) {
    403             return;
    404         }
    405         if (file.isDirectory()) {
    406             File f[] = file.listFiles();
    407             if (f != null)
    408                 for (int i = 0; i < f.length; i++) {
    409                     listFileName(f[i], fileList);
    410                 }
    411         } else {
    412 
    413             if (file.getName().endsWith(".java")) {
    414                 System.out.println(file.getName());
    415 
    416                 // fileList.add(str);
    417             }
    418         }
    419     }
    420 
    421     /**
    422      * 判断名称为fieldClazz的实体中含有多少个clazz类型的Field
    423      * 
    424      * @param clazz
    425      *            A类
    426      * @param fieldClazz
    427      *            A类中的Field
    428      * @return
    429      */
    430     public String Other(Class clazz, Class fieldClazz) {
    431 
    432         Field[] oFields = fieldClazz.getDeclaredFields();
    433         // 获得关联实体上所有的Field并遍历
    434         for (Field ofield : oFields) {
    435             Class ofieldClazz = ofield.getType();
    436             String ofieldClazzSN = ofieldClazz.getSimpleName();
    437 
    438             Type ofieldGenericType = ofield.getGenericType();
    439 
    440             /* 如果是类类型 String Byte[] User */
    441             if (ofieldGenericType instanceof Class) {
    442                 if (clazz.getSimpleName().equals(ofieldClazzSN)) {
    443                     // 基本类型
    444                     // System.out.println("1" + ofieldClazzSN);
    445                     // 一对一主键
    446                     return "1";
    447                     // 一对一外键
    448                 }
    449 
    450             }
    451 
    452             else if (ofieldGenericType instanceof ParameterizedType) {
    453                 /* 如果是参数化类型 List<User> List<Tie> */
    454                 // 得到泛型类java.util.List<cn.lddxfs.tieba.domain.Ba>
    455                 ParameterizedType pt = (ParameterizedType) ofieldGenericType;
    456                 Type t1Type = pt.getActualTypeArguments()[0];
    457 
    458                 Class t1Clazz = null;
    459                 if (t1Type instanceof Class) {
    460                     t1Clazz = (Class) t1Type;
    461                 }
    462 
    463                 String t1SimpleName = t1Clazz.getSimpleName();
    464                 if (clazz.getSimpleName().equals(t1SimpleName)) {
    465                     // 基本类型
    466                     /*
    467                      * System.out .println("多" + ofieldClazzSN + " " +
    468                      * t1SimpleName);
    469                      */
    470                     // 一对多1nSet 1nList
    471 
    472                     return "n";
    473                 }
    474 
    475             }
    476 
    477         }
    478         return "0";
    479     }
    480 
    481 }
    View Code

    你需要将类似以下格式的java文件

      1 package cn.lddxfs.tieba.domain;
      2 
      3 import java.util.HashSet;
      4 import java.util.LinkedList;
      5 import java.util.List;
      6 import java.util.Set;
      7 
      8 /**
      9  * 系统管理员
     10  */
     11 public class AdminUser {
     12 
     13     /**
     14      * id
     15      */
     16     private Long id;
     17 
     18     /**
     19      * 用户名
     20      */
     21     private String name;
     22 
     23     /**
     24      * 邮箱,登陆时使用
     25      */
     26     private String email;
     27 
     28     /**
     29      * 密码
     30      */
     31     private String password;
     32 
     33     /**
     34      * UUID用于激活
     35      */
     36     private String uuid;
     37 
     38     /**
     39      * 状态,已经启用,为激活
     40      */
     41     private DataDictoryValue status;
     42 
     43     /**
     44      * 居民身份证
     45      */
     46     private String idcard;
     47 
     48     /**
     49      * 审核了那些吧
     50      */
     51     private Set<BaApply> baApply=new HashSet<BaApply>();
     52 
     53     public Long getId() {
     54         return id;
     55     }
     56 
     57     public void setId(Long id) {
     58         this.id = id;
     59     }
     60 
     61     public String getName() {
     62         return name;
     63     }
     64 
     65     public void setName(String name) {
     66         this.name = name;
     67     }
     68 
     69     public String getEmail() {
     70         return email;
     71     }
     72 
     73     public void setEmail(String email) {
     74         this.email = email;
     75     }
     76 
     77     public String getPassword() {
     78         return password;
     79     }
     80 
     81     public void setPassword(String password) {
     82         this.password = password;
     83     }
     84 
     85     public String getUuid() {
     86         return uuid;
     87     }
     88 
     89     public void setUuid(String uuid) {
     90         this.uuid = uuid;
     91     }
     92 
     93     public DataDictoryValue getStatus() {
     94         return status;
     95     }
     96 
     97     public void setStatus(DataDictoryValue status) {
     98         this.status = status;
     99     }
    100 
    101     public String getIdcard() {
    102         return idcard;
    103     }
    104 
    105     public void setIdcard(String idcard) {
    106         this.idcard = idcard;
    107     }
    108 
    109     public Set<BaApply> getBaApply() {
    110         return baApply;
    111     }
    112 
    113     public void setBaApply(Set<BaApply> baApply) {
    114         this.baApply = baApply;
    115     }
    116 }
    View Code

    现在只需要通过junit运行src/generator/DomainGenerator.java中的generatorHBMXML()方法就可以生成 hbm.xml文件了,

    本文由 http://www.cnblogs.com/LDDXFS/ 原创,转载请注明本文出处。

  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/LDDXFS/p/4171251.html
Copyright © 2011-2022 走看看