自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring Jpa這個(gè)問(wèn)題怎么解決?

開(kāi)發(fā) 前端
spring jpa是基于Habernate實(shí)現(xiàn),同樣我們需要基于接口org.hibernate.integrator.spi.Integrator,在生成ddl時(shí)進(jìn)行擴(kuò)展。

在使用spring-boot-starter-data-jpa時(shí),通過(guò)這樣的配置可以在程序啟動(dòng)后實(shí)現(xiàn)在指定數(shù)據(jù)庫(kù)自動(dòng)建表。

spring:
  jpa:
    hibernate:
      ddl-auto: update

但是這種方式建表后沒(méi)辦法為每一列增加對(duì)應(yīng)的中文注釋,有什么辦法可以實(shí)現(xiàn)這一需求呢?

后面在網(wǎng)上找到了實(shí)現(xiàn)方法:

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

但是在當(dāng)前項(xiàng)目中無(wú)效,后面發(fā)現(xiàn)部分依賴已經(jīng)改變,應(yīng)該是對(duì)高版本JPA不支持導(dǎo)致。今天基于該jar重新梳理實(shí)現(xiàn)過(guò)程。

實(shí)現(xiàn)方式

基于自定義注解以及Spring自動(dòng)配置實(shí)現(xiàn)。

  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實(shí)現(xiàn),同樣我們需要基于接口org.hibernate.integrator.spi.Integrator,在生成ddl時(shí)進(jìn)行擴(kuò)展。
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. 定義配置類,對(duì)HibernatePropertiesCustomizer進(jìn)行擴(kuò)展。
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配置,實(shí)現(xiàn)自動(dòng)裝配。

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

cn.cycad.jpa.comment.config.CommentConfig

應(yīng)用示例

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

    @Id
    @Comment("業(yè)務(wù)主鍵")
    private String id;

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

    @Comment("用戶年齡")
    private Integer age;
    
}
  1. 啟動(dòng)服務(wù)后,可以看到控制臺(tái)輸出的建表語(yǔ)句信息。
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
        '業(yè)務(wù)主鍵'
Hibernate: 
    comment on column t_user.age is
        '用戶年齡'
Hibernate: 
    comment on column t_user.caption is
        '用戶名稱'

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2012-03-06 11:25:40

ibmdw

2021-10-06 23:31:45

HibernateJPASpring Data

2009-06-01 12:04:38

JPASpringJAVA

2022-04-28 08:05:05

數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)交互

2013-09-22 10:15:01

Spring DataJPA

2009-06-18 15:28:08

Glassfish JSpring

2013-08-01 10:05:54

大數(shù)據(jù)信息安全

2023-05-23 10:01:51

冪等性抽象代數(shù)

2009-06-01 16:18:30

SpringJPA集成

2019-11-26 14:30:20

Spring循環(huán)依賴Java

2009-06-18 13:44:05

Spring2.0spring2.5

2021-06-08 08:38:36

MySQL數(shù)據(jù)庫(kù)死鎖問(wèn)題

2024-02-26 08:42:10

亂碼UTF-8編碼

2022-07-13 08:53:28

函數(shù)Go語(yǔ)言

2022-08-27 15:15:31

iOS耗電后臺(tái)

2023-11-28 08:36:16

Spring中Body讀取

2021-03-01 19:09:45

編程程序代碼

2024-02-26 08:21:51

CPUkafka死循環(huán)

2022-08-01 09:43:19

程序員Googlefacebook

2023-12-26 17:07:56

GenAICIO
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)