@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) public @interface Comment { String value() default ""; }
package cn.com.micro.qx.comment; import org.hibernate.boot.Metadata; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.integrator.spi.Integrator; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.service.spi.SessionFactoryServiceRegistry; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.util.Iterator; @Component public class CommentIntegrator implements Integrator { public static final CommentIntegrator INSTANCE = new CommentIntegrator(); public CommentIntegrator() { super(); } /** * Perform comment integration. * * @param metadata The "compiled" representation of the mapping information * @param sessionFactory The session factory being created * @param serviceRegistry The session factory's service registry */ @Override public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { 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) { } /** * Process comment annotation. * * @param metadata process annotation of this {@code Metadata}. */ private void processComment(Metadata metadata) { for (PersistentClass persistentClass : metadata.getEntityBindings()) { // Process the Comment annotation is applied to Class Class<?> clz = persistentClass.getMappedClass(); if (clz.isAnnotationPresent(Comment.class)) { Comment comment = clz.getAnnotation(Comment.class); persistentClass.getTable().setComment(comment.value()); } // Process Comment annotations of identifier. Property identifierProperty = persistentClass.getIdentifierProperty(); if (identifierProperty != null) { fieldComment(persistentClass, identifierProperty.getName()); } else { org.hibernate.mapping.Component component = persistentClass.getIdentifierMapper(); if (component != null) { //noinspection unchecked Iterator<Property> iterator = component.getPropertyIterator(); while (iterator.hasNext()) { fieldComment(persistentClass, iterator.next().getName()); } } } // Process fields with Comment annotation. //noinspection unchecked Iterator<Property> iterator = persistentClass.getPropertyIterator(); while (iterator.hasNext()) { fieldComment(persistentClass, iterator.next().getName()); } } } /** * Process @{code comment} annotation of field. * * @param persistentClass Hibernate {@code PersistentClass} * @param columnName name of field */ private void fieldComment(PersistentClass persistentClass, String columnName) { try { Field field = persistentClass.getMappedClass().getDeclaredField(columnName); if (field.isAnnotationPresent(Comment.class)) { String comment = field.getAnnotation(Comment.class).value(); String sqlColumnName= persistentClass.getProperty(columnName).getValue().getColumnIterator().next().getText(); Iterator<org.hibernate.mapping.Column> columnIterator = persistentClass.getTable().getColumnIterator(); while (columnIterator.hasNext()) { org.hibernate.mapping.Column column = columnIterator.next(); if (sqlColumnName.equalsIgnoreCase(column.getName())) { column.setComment(comment); break; } } } } catch (NoSuchFieldException | SecurityException ignored) { } } }
package cn.com.micro.qx.config; import cn.com.geoscene.micro.qx.comment.CommentIntegrator; import org.hibernate.jpa.boot.spi.IntegratorProvider; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.stereotype.Component; import java.util.Collections; import java.util.Map; @Component public class HibernateConfig implements HibernatePropertiesCustomizer { @Override public void customize(Map<String, Object> hibernateProperties) { hibernateProperties.put("hibernate.use_sql_comments", true); hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(CommentIntegrator.INSTANCE)); } }
package cn.com.micro.qx.entity; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.com.geoscene.micro.qx.comment.Comment; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.hibernate.annotations.ColumnTransformer; import org.hibernate.validator.constraints.Length; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.*; import java.io.Serializable; import java.util.Date; @Entity @Table(name = "XQYL", schema = "sde") @EntityListeners(AuditingEntityListener.class) @Data @ApiModel(description = "院落单元信息") @Comment("院落单元信息") public class CellUnit implements Serializable { @Id @JsonProperty("objectid") @ApiModelProperty(value = "主键") @Comment("主键") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long objectid; @Length(max = 20) @Excel(name = "XQYLDM") @JsonProperty("XQYLDM") @Column(name = "XQYLDM",length = 20) @Comment("小区院落代码") @ApiModelProperty(value = "小区院落代码") String XQYLDM; @Length(max = 100) @Excel(name = "XQYLMC") @JsonProperty("XQYLMC") @Column(name = "XQYLMC",length = 100) @Comment("小区院落名称") @ApiModelProperty(value = "小区院落名称") String XQYLMC; }
当postgres数据库的schema和table名称都是大写的时候,在
CommentIntegrator里面使用这个代码。问题是使用这个代码会报异常数据库超过连接数。暂时还没有想到办法解决。还有一个问题是,使用下面这个代码要先屏蔽下面的代码,执行程序先创建好了表,才能在重新运行程序执行添加注释的功能
private void processComment2(Metadata metadata, SessionFactoryImplementor sessionFactory) { for (PersistentClass persistentClass : metadata.getEntityBindings()) { Class<?> clz = persistentClass.getMappedClass(); String tableName = persistentClass.getTable().getName().toUpperCase(); System.out.println("-----------table " + tableName); try { String schema = persistentClass.getTable().getSchema().toUpperCase(); if (clz.isAnnotationPresent(Comment.class)) { Comment comment = clz.getAnnotation(Comment.class); String value = comment.value(); if (StringUtils.isNotBlank(value)) { String sql = String.format( "COMMENT ON TABLE \"%s\".\"%s\" IS '%s'", schema, tableName, value); try { sessionFactory.getServiceRegistry().getService(ConnectionProvider.class) .getConnection().createStatement().execute(sql); } catch (SQLException e) { e.printStackTrace(); } } } Property identifierProperty = persistentClass.getIdentifierProperty(); if (identifierProperty != null) { fieldComment(persistentClass, identifierProperty.getName(), sessionFactory); } else { org.hibernate.mapping.Component component = persistentClass.getIdentifierMapper(); if (component != null) { Iterator<Property> iterator = component.getPropertyIterator(); while (iterator.hasNext()) { fieldComment(persistentClass, iterator.next().getName(), sessionFactory); } } } Iterator<Property> iterator = persistentClass.getPropertyIterator(); while (iterator.hasNext()) { fieldComment(persistentClass, iterator.next().getName(), sessionFactory); } // sessionFactory.close(); }catch (Exception e){ e.printStackTrace(); } } }