繁体   English   中英

在 Spring Data JPA 中,有没有最简单的方法来获取表元数据(列名列表)信息? 我可以在通用数据库上使用哪个

[英]Is there any Simplest way to get Table metadata (column name list) information, in Spring Data JPA ? which could I use on universal database

我想使用 spring 数据 jpa 获取所有表的列列表,我的数据库很灵活,因此查询应该适用于所有类型的数据库。

JPA规范包含Metamodel API,允许您查询有关托管类型及其托管字段的信息。 但它不包括底层数据库。 因此,JPA中没有任何开箱即用的查询数据库元数据。


每个RDBMS存储元信息的方式也不同,因此不能存在简单的,与数据库无关的解决方案。


但是,您可以通过几次跳跃来实现。

步骤1 :定义将保存元数据信息的实体类。

@Entity
@IdClass(TableMetadataKey.class)
@Table(name = "table_metadata")
class TableMetadata {
  @Column(name = "column_name")
  @Id
  String columnName;

  @Column(name = "table_name")
  @Id
  String tableName;

  public static class TableMetadataKey implements Serializable {
    String columnName;
    String tableName;
  }
}

第2步 :添加实体的存储库。

public interface TableMetadataRepository extends JpaRepository<TableMetadata, TableMetadataKey>
{
  TableMetadata findByTableName(String tableName);
}

步骤3 :定义名为table_metadata的数据库视图以映射到实体类。 这必须使用特定于数据库的查询来定义(因为每个数据库都有不同的存储元数据的方式)。

可以在此步骤中执行特定于数据库的优化,例如,使用Oracle的物化视图以便更快地访问等。

或者,可以使用所需列创建名为table_metadata的表,并使用SQL脚本定期填充该表。

现在,应用程序可以完全访问所需的元数据。

List<TableMetadata> metadata = tableMetadataRepository.findAll()
TableMetadata metadata = tableMetadataRepository.findByTableName("myTable");

需要注意的一个问题是,并非模式中的所有表都可以映射为JPA实体,或者并非所有表中的所有列都可以映射为实体字段。 因此,直接查询数据库元数据可能会产生与实体类和字段不匹配的结果。

SchemaCrawler有一个 Java API,它允许您以通用方式处理数据库元数据,也就是说,无需关心特定的数据库平台。

http://www.schemacrawler.com

您可以使用您的实体或模型获取列名称列表 我们需要的是@Column ,它应该在你的实体中使用。 您将获得在@Column指定的所有详细信息。 所有参数都是可选的,尽管定义所有参数都很好。

@Column(name,columnDefinition,insertable,length,nullable,precision,scale,table,unique,updatable)

我们可以通过User.class.getDeclaredFields()获取在Entity中声明的所有字段(通常为ModelName.class.getDeclaredFields()) 获得所有的feilds之后我们可以使用field.getAnnotation(Column.class)获取特定的Column,我们也可以获得@Column指定的所有细节,如下所示

Columns: @javax.persistence.Column(nullable=false, precision=2, unique=true, name=id, length=2, scale=1, updatable=false, columnDefinition=, table=, insertable=true)
Columns: @javax.persistence.Column(nullable=true, precision=0, unique=false, name=client_id, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
Columns: @javax.persistence.Column(nullable=true, precision=0, unique=false, name=firstname, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
Columns: @javax.persistence.Column(nullable=true, precision=0, unique=false, name=lastname, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)

根据需要创建endPoint或方法

@GetMapping(value= "/columns/name")
    public List<String> tableColumnsName()
    {   
        List<String> Columns = new ArrayList<String>();
        Field[] fields = User.class.getDeclaredFields();

        for (Field field : fields) {
            Column col = field.getAnnotation(Column.class);
            if (col != null) {
                Columns.add(col.name());
                System.out.println("Columns: "+col);
            }
         }
          return Columns;   
    } 

实体/型号

@Entity
@Table
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Column(name="id")
    public int id;

    @Column(name="client_id")
    private int clientId;

    @Column(name="firstname")
    private String firstname;

    @Column(name="lastname")
    private String lastname;

    //AllArgConstructor-Constructor
    //Getters-Setters

}

通过Postman测试 邮差结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM