成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Jpa這個問題怎么解決?

開發 前端
spring jpa是基于Habernate實現,同樣我們需要基于接口org.hibernate.integrator.spi.Integrator,在生成ddl時進行擴展。

在使用spring-boot-starter-data-jpa時,通過這樣的配置可以在程序啟動后實現在指定數據庫自動建表。

spring:
  jpa:
    hibernate:
      ddl-auto: update

但是這種方式建表后沒辦法為每一列增加對應的中文注釋,有什么辦法可以實現這一需求呢?

后面在網上找到了實現方法:

<dependency>
            <groupId>com.github.biyanwen</groupId>
            <artifactId>jpa-comment-spring-boot-starter</artifactId>
            <version>1.0.2</version>
        </dependency>

但是在當前項目中無效,后面發現部分依賴已經改變,應該是對高版本JPA不支持導致。今天基于該jar重新梳理實現過程。

實現方式

基于自定義注解以及Spring自動配置實現。

  1. 定義注解Comment,該注解定義在字段上,定義該列的中文描述。
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Comment {
    /**
     * 注釋的值
     *
     * @return {@link String}
     */
    String value() default "";
}
  1. spring jpa是基于Habernate實現,同樣我們需要基于接口org.hibernate.integrator.spi.Integrator,在生成ddl時進行擴展。
public class CommentIntegrator implements Integrator {
    public static final CommentIntegrator INSTANCE = new CommentIntegrator();

    public CommentIntegrator() {
        super();
    }

    @Override
    public void integrate(Metadata metadata, BootstrapContext bootstrapContext, SessionFactoryImplementor sessionFactory) {
        processComment(metadata);
    }

    /**
     * Not used.
     *
     * @param sessionFactoryImplementor     The session factory being closed.
     * @param sessionFactoryServiceRegistry That session factory's service registry
     */
    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {
    }

    /**
     * 生成注釋代碼
     *
     * @param metadata process annotation of this {@code Metadata}.
     */
    protected void processComment(Metadata metadata) {
        for (PersistentClass persistentClass : metadata.getEntityBindings()) {
            Class<?> clz = persistentClass.getMappedClass();
            if (clz.isAnnotationPresent(Comment.class)) {
                Comment comment = clz.getAnnotation(Comment.class);
                persistentClass.getTable().setComment(comment.value());
            }
            Property identifierProperty = persistentClass.getIdentifierProperty();
            if (identifierProperty != null) {
                propertyComment(persistentClass, identifierProperty.getName());
            } else {
                org.hibernate.mapping.Component component = persistentClass.getIdentifierMapper();
                if (component != null) {
                    Iterator<Property> iterator = component.getPropertyIterator();
                    while (iterator.hasNext()) {
                        propertyComment(persistentClass, iterator.next().getName());
                    }
                }
            }
            Iterator<Property> iterator = persistentClass.getProperties().iterator();
            while (iterator.hasNext()) {
                propertyComment(persistentClass, iterator.next().getName());
            }
        }
    }

    /**
     * 為屬性生成注釋
     *
     * @param persistentClass Hibernate {@code PersistentClass}
     * @param columnName      name of field
     */
    private void propertyComment(PersistentClass persistentClass, String columnName) {
        try {
            String comment = getPropertyComment(persistentClass, columnName);
            Value value = persistentClass.getProperty(columnName).getValue();
            if( value.getColumns().iterator().hasNext() ){
                String sqlColumnName = value.getColumns().iterator().next().getText();
                Iterator<org.hibernate.mapping.Column> columnIterator = persistentClass.getTable().getColumns().iterator();
                while (columnIterator.hasNext()) {
                    org.hibernate.mapping.Column column = columnIterator.next();
                    if (sqlColumnName.equalsIgnoreCase(column.getName())) {
                        column.setComment(comment);
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getPropertyComment(PersistentClass persistentClass, String columnName) throws Exception {
        String comment = null;

        Field field = ReflectionUtils.findField(persistentClass.getMappedClass(), columnName);
        if (field != null) {
            if (field.isAnnotationPresent(Comment.class)) {
                comment = field.getAnnotation(Comment.class).value();
            } else {
                PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), persistentClass.getMappedClass());
                Method readMethod = descriptor.getReadMethod();
                Comment comment1 = readMethod.getAnnotation(Comment.class);
                if (comment1 != null) {
                    comment = comment1.value();
                }
            }
        }
        return comment;
    }
}
  1. 定義配置類,對HibernatePropertiesCustomizer進行擴展。
public class HibernateProperties implements HibernatePropertiesCustomizer {
    @Override
    public void customize(Map<String, Object> hibernateProperties) {
        hibernateProperties.put("hibernate.integrator_provider",    (IntegratorProvider) () -> Collections.singletonList(CommentIntegrator.INSTANCE));
    }
}
  1. 定義spring配置,實現自動裝配。

在resource目錄添加自動注入配置META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,這樣通過引入jar就可以自動使用該配置。

cn.cycad.jpa.comment.config.CommentConfig

應用示例

  1. 比如現在有一個User實體,我們通過繼承基類。
@Entity
@Table(name = "t_user")
@Data
public class User extends Domain {

    @Id
    @Comment("業務主鍵")
    private String id;

    @Comment("用戶名稱")
    private String caption;

    @Comment("用戶年齡")
    private Integer age;
    
}
  1. 啟動服務后,可以看到控制臺輸出的建表語句信息。
Hibernate: 
    create table t_user (
        id varchar(255) not null,
        create_time timestamp(6),
        creator varchar(56),
        modified_time timestamp(6),
        modifier varchar(56),
        age integer,
        caption varchar(255),
        primary key (id)
    )
Hibernate: 
    comment on column t_user.id is
        '業務主鍵'
Hibernate: 
    comment on column t_user.age is
        '用戶年齡'
Hibernate: 
    comment on column t_user.caption is
        '用戶名稱'

責任編輯:武曉燕 來源: Java技術指北
相關推薦

2012-03-06 11:25:40

ibmdw

2021-10-06 23:31:45

HibernateJPASpring Data

2009-06-01 12:04:38

JPASpringJAVA

2023-05-23 10:01:51

冪等性抽象代數

2013-08-01 10:05:54

大數據信息安全

2022-04-28 08:05:05

數據庫數據庫交互

2013-09-22 10:15:01

Spring DataJPA

2009-06-18 15:28:08

Glassfish JSpring

2021-06-08 08:38:36

MySQL數據庫死鎖問題

2019-11-26 14:30:20

Spring循環依賴Java

2009-06-01 16:18:30

SpringJPA集成

2009-06-18 13:44:05

Spring2.0spring2.5

2024-02-26 08:42:10

亂碼UTF-8編碼

2022-07-13 08:53:28

函數Go語言

2022-08-27 15:15:31

iOS耗電后臺

2022-08-01 09:43:19

程序員Googlefacebook

2023-12-26 17:07:56

GenAICIO

2024-02-26 08:21:51

CPUkafka死循環

2021-03-01 19:09:45

編程程序代碼

2023-11-28 08:36:16

Spring中Body讀取
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲黄色一区二区三区 | 中文字幕一区在线观看视频 | 一区日韩 | 97精品超碰一区二区三区 | 综合九九| 久久久久久久久国产成人免费 | 爱爱视频在线观看 | 久久久久久国产精品 | 欧美综合在线视频 | 在线一级片 | 一级片网址 | 国内精品久久久久久久 | 特级做a爰片毛片免费看108 | 91一区二区三区在线观看 | 久久天堂 | 亚洲国产欧美精品 | av毛片在线免费观看 | 午夜精品久久久久久久久久久久久 | 久久精品 | 一级毛片在线播放 | 日韩免费一区二区 | 亚洲综合色站 | 国产区久久 | 久久成人高清视频 | 欧美精品一区二区三区在线 | 久久99精品久久久97夜夜嗨 | 一级电影免费看 | 亚洲精品无 | 国产伦精品一区二区三区精品视频 | 91视频在线观看 | 超碰人人91 | 成人欧美一区二区三区白人 | 国内自拍视频在线观看 | 91精品在线播放 | 狠狠色香婷婷久久亚洲精品 | 国产精品视频免费看 | 成人性视频免费网站 | 免费视频一区二区 | 婷婷在线视频 | 精品欧美一区二区三区久久久 | 亚洲一区毛片 |