2013-11-28 16 views
0

什麼給出:Hibernate的代碼生成:創建抽象/具體的模型類對

  • 我產生我的模型類與Hibernate代碼生成(休眠工具4)
  • 我想爲每個數據庫表的抽象基類以及具體擴展
  • 基類應包含所有數據庫字段(獲取/設置)
  • 具體類應該從基本擴展並且應該爲空的爲傳輸字段
  • 我處理我libararies與Apache Maven的
  • 我有一個Java可配置Spring MVC的環境

我已閱讀,你可以覆蓋在Hibernate工具JAR Freemarker的模板。但是當我使用Maven時,這是不可能的。?

因爲我使用java配置的Spring MVC環境,如果不存在xml的解決方案,它會很棒。

該解決方案應該做到以下幾點:

  • 在MySQL數據庫中創建一個類對每個表
  • 我不舒爾,但增加@MappedSuperclass註解?

實施例: 抽象基類

@Entity 
@MappedSuperclass 
@Table(name = "employee", catalog = "test", uniqueConstraints = @UniqueConstraint(columnNames = "E_MAIL")) 
public abstract class EmployeeBase implements java.io.Serializable { 

    private Integer id; 

    public Employee() { 
    } 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "ID", unique = true, nullable = false) 
    public Integer getId() { 
     return this.id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

實施例:混凝土類

public class Employee extends EmployeeBase { 
    // my transistent fields, for example getFirstAndLastName(); 
} 
+0

使用'',你應該可以在休眠的工具JAR,而不是從回購的一個定製版本的Maven點。 (即你會得到工具JAR,修改模板,然後將它安裝到你公司的'groupName'下的本地或網站倉庫中。) – millimoose

+0

好的,謝謝,我會檢查這個,但我還沒有好的方法來編寫這樣的符合我要求的模板。 – Tunguska

+0

這種缺乏方法的背後是什麼?你看過現有的模板嗎?你有沒有試過Google搜索「冬眠自定義模板」?戳到[Hibernate Tools文檔](http://docs.jboss.org/tools/4.1.0.Final/en/hibernatetools/html_single/index.html#hbmtemplate)至少看看下一步要看哪裏?除了在此列出您的高級要求之外,還有什麼? – millimoose

回答

0

解決方案:

  1. 從HibernateTools.jar
  2. 創建兩個ReverseEngineeringStrategies(基地和混凝土)
  3. 更新Freemarker的模板創建代碼生成配置在Eclipse(Hibernate插件),並設置策略和自定義模板。
  4. 切換逆向工程策略並運行兩次。

來源:

BaseClassStrategy:

public class BaseClassStrategy extends DelegatingReverseEngineeringStrategy { 

    public BaseClassStrategy(ReverseEngineeringStrategy delegate) { 
     super(delegate); 
    } 

    @Override 
    public Map<String, MetaAttribute> tableToMetaAttributes(TableIdentifier tableIdentifier) { 

     @SuppressWarnings("unchecked") 
     Map<String, MetaAttribute> metaAttributes = super.tableToMetaAttributes(tableIdentifier); 
     if (metaAttributes == null) { 
      metaAttributes = new HashMap<String, MetaAttribute>(); 
     } 

     // Update modifier 
     if (!metaAttributes.containsKey("scope-class")) { 
      MetaAttribute metaAttribute = new MetaAttribute("scope-class"); 
      metaAttribute.addValue("public abstract"); 
      metaAttributes.put(metaAttribute.getName(), metaAttribute); 
     } 

     // Update class name 
     if (!metaAttributes.containsKey("generated-class")) { 
      MetaAttribute metaAttribute = new MetaAttribute("generated-class"); 
      metaAttribute.addValue(tableToAbstractClassName(tableIdentifier)); 
      metaAttributes.put(metaAttribute.getName(), metaAttribute); 
     } 

     return metaAttributes; 
    } 

    private String tableToAbstractClassName(TableIdentifier tableIdentifier) { 
     String className = super.tableToClassName(tableIdentifier); 
     int dotIndex = className.lastIndexOf('.'); 
     return className.substring(0, dotIndex + 1) + className.substring(dotIndex + 1) + "Base"; 
    } 
} 

ConcreteClassStrategy:

public class ConcreteClassStrategy extends DelegatingReverseEngineeringStrategy { 

    public ConcreteClassStrategy(ReverseEngineeringStrategy delegate) { 
     super(delegate); 
    } 

    @Override 
    public Map<String, MetaAttribute> tableToMetaAttributes(TableIdentifier tableIdentifier) { 

     @SuppressWarnings("unchecked") 
     Map<String, MetaAttribute> metaAttributes = super.tableToMetaAttributes(tableIdentifier); 
     if (metaAttributes == null) { 
      metaAttributes = new HashMap<String, MetaAttribute>(); 
     } 


     String className = super.tableToClassName(tableIdentifier); 
     int dotIndex = className.lastIndexOf('.'); 
     String abstractClassName = className.substring(dotIndex + 1) + "Base"; 

     // Update extends modifier 
     if (!metaAttributes.containsKey("scope-class")) { 
      MetaAttribute metaAttribute = new MetaAttribute("extends"); 
      metaAttribute.addValue(abstractClassName); 
      metaAttributes.put(metaAttribute.getName(), metaAttribute); 
     } 

     return metaAttributes; 
    } 
} 

Hibernate的模板:

添加下面的文件夾結構到您的項目:

src/main/resources 
|-> hibernate-templates 
    |-> dao 
    |-> pojo 

複製從休眠-的tools.jar和更新以下文件的POJO和DAO文件夾。它只會工作,如果你添加兩個文件夾!

Ejb3TypeDeclaration.ftl

<#if ejb3?if_exists> 
<#if pojo.isComponent()> 
@${pojo.importType("javax.persistence.Embeddable")} 
<#else> 
@${pojo.importType("javax.persistence.Entity")} 
@${pojo.importType("javax.persistence.Table")}(name="${clazz.table.name}" 
<#if clazz.table.schema?exists> 
    ,schema="${clazz.table.schema}" 
</#if><#if clazz.table.catalog?exists> 
    ,catalog="${clazz.table.catalog}" 
</#if> 
<#assign uniqueConstraint=pojo.generateAnnTableUniqueConstraint()> 
<#if uniqueConstraint?has_content> 
    , uniqueConstraints = ${uniqueConstraint} 
</#if>) 
</#if> 
</#if> 

Ejb3TypeDeclaration.ftl

<#if ejb3?if_exists> 
<#if pojo.isComponent()> 
@${pojo.importType("javax.persistence.Embeddable")} 
<#else> 
@${pojo.importType("javax.persistence.MappedSuperclass")} 
</#if> 
</#if> 

Pojo.ftl

${pojo.getPackageDeclaration()} 
// Generated ${date} by Hibernate Tools ${version} 
<#assign classbody> 
<#include "PojoTypeDeclaration.ftl"/> { 

<#if !pojo.isInterface()> 

<#if pojo.getDeclarationName()?ends_with("Base")> 
<#include "PojoFields.ftl"/> 
</#if> 

<#include "PojoConstructors.ftl"/> 

<#if pojo.getDeclarationName()?ends_with("Base")> 

<#include "PojoPropertyAccessors.ftl"/> 

<#include "PojoToString.ftl"/> 

<#include "PojoEqualsHashcode.ftl"/> 
</#if> 

<#else> 
<#include "PojoInterfacePropertyAccessors.ftl"/> 

</#if> 
<#include "PojoExtraClassCode.ftl"/> 

} 
</#assign> 

${pojo.generateImports()} 
${classbody} 

PojoConstructor.ftl

<#-- /** default constructor */ --> 
public ${pojo.getDeclarationName()}() {} 

<#if pojo.needsMinimalConstructor()>  
<#-- /** minimal constructor */ --> 
public ${pojo.getDeclarationName()}(${c2j.asParameterList(pojo.getPropertyClosureForMinimalConstructor(), jdk5, pojo)}) { 
    <#if pojo.getDeclarationName()?ends_with("Base")> 
     <#foreach field in pojo.getPropertiesForMinimalConstructor()> 
     this.${field.name} = ${field.name}; 
     </#foreach> 
    <#else> 
     super(${c2j.asArgumentList(pojo.getPropertyClosureForMinimalConstructor())});   
    </#if> 
} 
</#if>  

<#if pojo.needsFullConstructor()> 
<#-- /** full constructor */ --> 
public ${pojo.getDeclarationName()}(${c2j.asParameterList(pojo.getPropertyClosureForFullConstructor(), jdk5, pojo)}) { 
    <#if pojo.getDeclarationName()?ends_with("Base")> 
     <#foreach field in pojo.getPropertiesForFullConstructor()> 
     this.${field.name} = ${field.name}; 
     </#foreach> 
    <#else> 
     super(${c2j.asArgumentList(pojo.getPropertyClosureForFullConstructor())});   
    </#if> 
} 
</#if>