当前位置:编程学习 > JAVA >>

让Hibernate生成的DDL脚本自动增加注释

我们知道可以通过Hibernate对象自动生成DDL建表语句,通过PowerDesigner工具可以反向工程生成数据字典,但是在生成的DDL中一直不能写上中文的注释,这就使我们生成的数据字典不具有可用性。
 
这个假期宅在家里调试代码,发现Hibernate的Dialect,Table,Column的映射中已经做了comment的处理,只是Hibernate团队认为这个功能的重要性太小,一直没有时间提供这个需求,于是就自己动手实现这个功能了,这可是使用我们的数据对象代码与数据字典文档同步的关键一环啊!
 
通过对Hibernate代码的跟踪发现了处理映射的逻辑是在代码AnnotationBinder中,我们不需要在运行期间处理comment,只是在用SchemaExport时处理就可以,于是简单的实现了此功能:
 
1. 增加一个注解 @Comment("这是表的说明,也可以是字段的说明"),适用在类名和属性名
 
2. 复制org.hibernate.cfg.AnnotationBuilder代码为org.hibernate.cfg.MyAnnotationBuilder,处理注解@Comment
 
3. 复制org.hibernate.cfg.Configuration为org.hibernate.cfg.MyConfiguration,将AnnotationBuilder的调用换成MyAnnotationBuilder
 
3. 实现SchemaExportTool类,传入MyConfiguration处理Hibernate对象的映射关系,并生成DDL
 
 
 
以上思路在基于Hibernate 4.2.3版本在MySql 5.1上测试成功,因为代码只是在开发期运行,不需要良好的结构和优化,所以只是简单实现了,需要此功能的朋友可以自己实现。
 
 
 
以下是处理结果示例:
 
[java] 
@Entity  
@Table(name = "AuditRecord_")  
@Comment("系统审计表")  
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)  
public class AuditRecord implements Serializable {  
  
    private static final long serialVersionUID = 8844543936912679937L;  
    @Id  
    @GeneratedValue  
    @Comment("ID主键")  
    private Long id;  
    @Comment("审计类型")  
    @Column(length = 30)  
    private String auditType;  
    @Comment("操作人")  
    @ManyToOne  
    @JoinColumn(name = "userId")  
    private Passport operator;  
    // 操作简述  
    @Comment("操作简述")  
    @Column(length = 4000)  
    private String description;  
    @Comment("创建时间")  
    private Date creationTime;  
}  
 
生成的DDL如下:
 
[sql]  
create table audit_record_ (  
        id bigint not null auto_increment comment 'ID主键',  
        audit_type varchar(30) comment '审计类型',  
        creation_time datetime comment '创建时间',  
        description longtext comment '操作简述',  
        user_id bigint comment '操作人',  
        primary key (id)  
    ) comment='系统审计表';  
 
 
 
主要代码片断如下:
 
 
 
[java]  
import java.io.IOException;  
import java.util.Properties;  
  
import javax.persistence.Embeddable;  
import javax.persistence.Entity;  
import javax.persistence.MappedSuperclass;  
  
import org.hibernate.MappingException;  
import org.hibernate.cfg.MyConfiguration;  
import org.hibernate.tool.hbm2ddl.SchemaExport;  
import org.springframework.core.io.Resource;  
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;  
import org.springframework.core.io.support.ResourcePatternResolver;  
import org.springframework.core.io.support.ResourcePatternUtils;  
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;  
import org.springframework.core.type.classreading.MetadataReader;  
import org.springframework.core.type.classreading.MetadataReaderFactory;  
import org.springframework.core.type.filter.AnnotationTypeFilter;  
import org.springframework.core.type.filter.TypeFilter;  
import org.springframework.util.ClassUtils;  
  
public class SchemaExportTool extends MyConfiguration {  
  
    private static final long serialVersionUID = 1L;  
  
    private static final String RESOURCE_PATTERN = "/**/*.class";  
  
    private static final String PACKAGE_INFO_SUFFIX = ".package-info";  
  
    private static final TypeFilter[] ENTITY_TYPE_FILTERS = new TypeFilter[] {  
            new AnnotationTypeFilter(Entity.class, false),  
            new AnnotationTypeFilter(Embeddable.class, false),  
            new AnnotationTypeFilter(MappedSuperclass.class, false) };  
    private final ResourcePatternResolver resourcePatternResolver;  
  
    public SchemaExportTool() {  
        this.resourcePatternResolver = ResourcePatternUtils  
                .getResourcePatternResolver(new PathMatchingResourcePatternResolver());  
    }  
  
    public static void main(String[] args) {  
        try {  
            Properties p = new Properties();  
            p.setProperty("hibernate.dialect",  
                    "org.hibernate.dialect.MySQLDialect");  
            SchemaExportTool cfg = new SchemaExportTool();  
            cfg.addProperties(p);  
            cfg.setNamingStrategy(new ImprovedMyNamingStrategy());  
            cfg.scanPackage("com.share.passport.domain",  
                    "com.share.authority.domain", "com.share.utils.domain");  
  
            SchemaExport se = new SchemaExport(cfg);  
            if (null != args && args.length > 1)  
                if ("-f".equals(args[0]))  
                    se.setO
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,