且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-06-17 08:32:24

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

JPA specification contains the Metamodel API that allows you to query information about the managed types and their managed fields. It does not however cover the underlying database. So, there is nothing out-of-the-box in JPA yet for querying the database metadata.

每个方式RDBMS存储元信息也是不同的,所以不能有一个简单的,与数据库无关的解决方案。

The way each RDBMS stores meta information is also different so there cannot be a simple, database-agnostic solution.

你想要什么通过一些跳跃来实现。

What you want can however be achieved through a few hops.

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

Step 1: Define an entity class that will hold metadata information.

@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步:添加实体的存储库。

Step 2: Add the repository for the entity.

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

第3步:定义名为 table_metadata 。这必须使用特定于数据库的查询来定义(因为每个数据库都有不同的存储元数据的方式)。

Step 3: Define a database view named table_metadata to be mapped to the entity class. This will have to be defined using a database-specific query (because each database has a different way of storing its metadata).

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

Database-specific optimizations can be performed on this step, such as, using materialized views with Oracle for faster access, etc.

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

Alternatively, a table named table_metadata can be created with the required columns and populated periodically using a SQL script.

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

Now the application has full access to the required metadata.

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






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


One issue to be noted is that not all tables in a schema may be mapped as JPA entities or not all columns in all tables may be mapped as entity fields. Therefore, directly querying the database metadata may give results that do not match the entity classes and fields.