嘿大家。 🤩 我写这篇文章是为了指导你以编程方式创建一个动态 GraphQL 模式作为 java 代码。为此,我们将主要使用graphql-java库。

GraphQL 架构

GraphQL 有它的类型系统,用于定义 API 的模式。编写模式的语法称为模式定义语言 (SDL)。我们可以使用 SDL 定义模式,也可以以编程方式将其定义为 java 代码。但它们都是静态的表示方式。如果您在运行时构建模式,则很难将新字段递归地添加到预定义的定义中。

SDL 架构定义

type Customer {
   name : String
   address : String
   contact : Int 
}

编程模式定义

GraphQLObjectType.Builder graphQLObjectType = GraphQLObjectType.newObject();
graphQLObjectType.name("Customer")
                 .field(newFieldDefinition()
                       .name("name")
                       .type(Scalars.GraphQLString))
                 .field(newFieldDefinition()
                       .name("address")
                       .type(Scalars.GraphQLString))
                 .field(newFieldDefinition()
                       .name("conatct")
                       .type(Scalars.GraphQLInt)
                 .build();

我们将重点介绍如何提取您要连接的数据源的元数据。元数据表征您的数据,并使任何人都更容易理解和使用它。简而言之,元数据是描述存储在数据源中的数据的数据。它通常包括数据库中每个表的名称、大小和行数,以及每个表中的列、它们的数据类型、精度等。

让我们开始吧! 🚀

为了读取和存储数据库元数据,我们将使用两个接口DatabaseMetaDataResultSet。DatabaseMetaData 接口很大,包含数百种读取 DBMS 功能的方法。您可以参考Javadoc获取完整的方法列表。

获取DatabaseMetaData实例

这里我使用 jdbc-url 为Teiid,你也可以选择其他的。我们从Connection对象中获取DatabaseMetaData对象,如下所示:

String URL = "jdbc:teiid:customer@mm://localhost:31000";
String USERNAME = "sa";
String PASSWORD = "sa";
Connection connection = DriverManager.getConnection(URL, USERNAME ,PASSWORD );
DatabaseMetaData databaseMetaData = connection.getMetaData();

列出数据库表

我们可以借助 DatabaseMetaData 获取数据库或数据源中已定义表的列表。这是如何完成的:

String table[] = {"TABLE"};

ResultSet resultSet = databaseMetaData.getTables(null,null,null,table);
ArrayList<String> tables = new ArrayList();

    while(resultSet.next()) {
        tables.add(resultSet.getString("TABLE_NAME"));
    }

列出数据库列

我们可以通过 DatabaseMetaData 对象以这种方式获取表的列:

ResultSet columns = databaseMetaData.getColumns(null,null, tableName, null);
     while(columns.next()) {
         String columnName = columns.getString("COLUMN_NAME");
         String datatype = columns.getString("DATA_TYPE");
         String columnsize = columns.getString("COLUMN_SIZE");

         System.out.println(columnName + "---" + datatype + "---" + columnsize);
      }

创建架构

下一步是使用GraphQLObjectType对象创建一个模式,将其对应的元数据存储在 HashMap 中,并从下一节定义的ReturnType类中读取它的类型。

ResultSet resultSet = databaseMetaData.getColumns(null, null, (String) tableName, null);

     GraphQLObjectType objectType = null;
     GraphQLObjectType.Builder graphQLObjectType = GraphQLObjectType.newObject();

     System.out.println("-------Schema for Table " + tableName + "-------");
     HashMap <String,String> data  = new HashMap<>();

      while (resultSet.next()) {
           data.put(resultSet.getString("COLUMN_NAME"), resultSet.getString("TYPE_NAME"));

           for (Map.Entry<String, String> hm : data.entrySet()) {

                graphQLObjectType
                        .name(tableName)
                        .field(GraphQLFieldDefinition.newFieldDefinition()
                                .name(hm.getKey())
                                .type(ReturnType(hm.getValue())));
                objectType = graphQLObjectType.build();

            }
        }

在架构中定义字段类型

该类返回每种情况下的字段类型,这里我只定义了GraphQLLongGraphQLString两种类型,其他类型可以相应定义。

public static GraphQLScalarType ReturnType(String type) {
      if(type.equals("long"))
           return Scalars.GraphQLLong;
      else if (type.equals("string"))
           return Scalars.GraphQLString;
      return null;
    }
}

构建和打印模式

打印模式是一种定义的方式,我们使用SchemaPrinter对象,它采用 GraphQLSchema 类型的对象。

GraphQLSchema graphQLSchema = GraphQLSchema.newSchema()
                    .query(objectType)
                    .build();

SchemaPrinter schemaPrinter = new SchemaPrinter();
String printer = schemaPrinter.print(graphQLSchema);
System.out.println(printer);

结论

你有它!您已成功连接到数据源以获取数据库元数据并使用您构建的 graphQL 模式的数据。

您可以访问 Github RepoSchema Builder查看源代码。另请查看GraphQL Java网站以了解更多信息。

你在学习。我在学。我们都在学习。让我们继续学习,一起变得更好。谢谢你。快乐阅读! 🎉

您可以通过Twitter和LinkedIn与我联系❤️

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐