springboot jpa oracle實體類中配置註解沒法在數據庫中生成註釋的一種解決方式

需求

對於oracle數據庫,jpaEntity即便配置了註釋註解@Column(columnDefinition = '列註釋'),沒法在數據庫層生成列的註釋css

解決方案

自定義註解,配置在Entity類上,項目初始化時,經過EntityManager獲取全部的實體類,遍歷實體類中是否配置了註解,若是配置了,動態拼接DDL語句並執行java

  • 自定義註解:spring

    import java.lang.annotation.*;
    /**
    * description: * 解決jap根據實體類建立建表過程當中沒法添加字段註釋
    * @author MorningSun
    * @version 1.0 * @since JDK1.8 * date 11/6/2020 10:45 AM */@Target({ElementType.TYPE, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface JPAOracleComment {
       /**
    * spring jpa + oracle add comment * @return */ String value() default "";
    }
    import com.orient.cssrc.jpa.model.JpaOracleComment;
    import lombok.extern.slf4j.Slf4j;
    import org.hibernate.SessionFactory;
    import org.hibernate.internal.SessionFactoryImpl;
    import org.hibernate.persister.entity.EntityPersister;
    import org.hibernate.persister.entity.SingleTableEntityPersister;
    import org.hibernate.persister.walking.spi.AttributeDefinition;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Component;
    import javax.annotation.Resource;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.PersistenceContext;
    import java.lang.reflect.Field;
    import java.util.Map;
    import java.util.Objects;
    /**
    * description: * * @author MorningSun * @version V1.0 * @since date 2020/12/25 */@Slf4j
    @Component
    public class JpaOracleCommentInit implements CommandLineRunner {
       @PersistenceContext
    private EntityManager entityManager;
       @Resource
    private JdbcTemplate jdbcTemplate;
       @Resource
    private HibernateProperties hibernateProperties;
       @Override
    public void run(String... args) throws Exception {
           String ddlAuto = this.hibernateProperties.getDdlAuto();
           if(Objects.nonNull(ddlAuto) && "update".equalsIgnoreCase(ddlAuto)){
               this.scanCommentAnnotationOnEntityAndCreate();
           }
       }
       private void scanCommentAnnotationOnEntityAndCreate(){
           EntityManagerFactory entityManagerFactory = this.entityManager.getEntityManagerFactory();
           SessionFactoryImpl sessionFactory = (SessionFactoryImpl)entityManagerFactory.unwrap(SessionFactory.class);
           Map<String, EntityPersister> persisterMap = sessionFactory.getMetamodel().entityPersisters();
           if(Objects.nonNull(persisterMap) && persisterMap.keySet().size() > 0){
               for(Map.Entry<String, EntityPersister> entry: persisterMap.entrySet()){
                   Class<?> targetClazz = entry.getValue().getMappedClass();
                   SingleTableEntityPersister persister = (SingleTableEntityPersister)entry.getValue();
                   //數據表名
    String tableName = persister.getTableName();
                   //添加表的註釋
    JpaOracleComment targetClazzAnno = targetClazz.getAnnotation(JpaOracleComment.class);
                   if(Objects.nonNull(targetClazzAnno)){
                       String sql = "comment on table " +
                               tableName +
                               " is " +
                               "'" + targetClazzAnno.value() + "'";
                       this.jdbcTemplate.execute(sql);
                   }
                   for (AttributeDefinition attributeDefinition : persister.getAttributes()) {
                       //屬性名稱
    String propertyName = attributeDefinition.getName();
                       if (propertyName.equalsIgnoreCase("_identifierMapper")) {
                           log.warn("嘗試爲實體類:" + targetClazz.getSimpleName() + "生成註解,發現了聯合主鍵,暫時沒法處理,已忽略對應字段");
                           continue;
                       }
                       Field field;
                       try {
                           field = targetClazz.getDeclaredField(propertyName);
                           JpaOracleComment anno = field.getAnnotation(JpaOracleComment.class);
                           if (Objects.nonNull(anno)) {
                               //數據庫字段名
    String[] columns = persister.getPropertyColumnNames(propertyName);
                               String sql = "comment on column " +
                                       tableName +
                                       "." +
                                       columns[0] +
                                       " is " +
                                       "'" + anno.value() + "'";
                               this.jdbcTemplate.execute(sql);
                           }
                       } catch (NoSuchFieldException ex) {
                           ex.printStackTrace();
                       }
                   }
               }
           }
       }
    }
相關文章
相關標籤/搜索