• 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/ 原创,转载请注明本文出处。

  • 相关阅读:
    springboot:springboot初识(相关概念、新建项目)
    ssm项目无法加载静态资源
    js:初识(相关概念、js代码的书写位置、注释方式、输入输出语句)
    lucene:索引维护(删除、更新、查询)
    数据库连接池:Durid(执行流程、工具类)
    redis:HyperLogLog&发布订阅(HyperLogLog的概念和命令、redis的发布订阅)
    redis:zset(赋值、取值、删除、修改分数)
    css:css3新特性(过渡)
    css:css3新特性(盒子模型的box-sizing属性、图片模糊处理、calc函数)
    css:css3新特性(属性选择器、结构伪类选择器)
  • 原文地址:https://www.cnblogs.com/LDDXFS/p/4171251.html
Copyright © 2020-2023  润新知