The JDBC standard is inherently oriented towards relational databases and SQL queries. However, Polypheny extends beyond these limitations, supporting multiple data models and languages. To accommodate this, the JDBC standard has been extended in a feature known as the Multimodel Extension which goes beyond what is traditionally available through JDBC.
Supported Data Models
The Multimodel Extension of the Polypheny JDBC Driver is designed to accommodate a diverse range of data models. Specifically, it supports the Relational model, the Labeled Property Graph model (LPG), and the Document model. This allows Java applications to interact with all data models currently supported by Polypheny using a single driver.
Supported Query Languages
The Polypheny JDBC Driver officially supports the following query languages. While other query languages supported by Polypheny might work as well, they are not tested for compatibility.
Query Language | Name used for the languageName parameter |
---|---|
SQL | sql |
MongoDB Query Language | mql |
Cypher | cypher |
When using the execute
method, the languageName
parameter needs to be set to one of these strings.
Unwrapping for Multi-Model Support
To access the features of the Multimodel Extension, the JDBC Connection
object must be unwrapped to a PolyConnection
object, which provides Polypheny-specific features. Specifically, you can use the createPolyStatement
method to generate a statement object aligned with the Multimodel Extension.
For detailed documentation on the PolyStatement object, please refer to the corresponding documentation.
Usage:
try (
Connection connection = DriverManager.getConnection("jdbc:polypheny://localhost:20590");
) {
if (connection.isWrapperFor(PolyConnection.class)) {
PolyConnection polyConnection = connection.unwrap(PolyConnection.class);
PolyStatement polyStatement = polyConnection.createPolyStatement();
// You can now use polyStatement to execute multi-model queries...
}
} catch (SQLException e) {
e.printStackTrace();
}
Executing an MQL Query
The PolyStatement yielded by the unwrapping process above can now be used to execute statements in any of the supported languages. An example for the MongoDB Query Language (MQL) is given below.
For detailed documentation on the PolyStatement object, please refer to the corresponding documentation.
Imagine a collection of documents, each storing information about a specific person. To retrieve all people in our database and print them to System.out
, we can use the code below.
DocumentResult result = polyStatement.execute("mongotest", "mongo", "db.people.find({})").unwrap(DocumentResult.class);
Iterator<PolyDocument> documents = result.iterator();
while (documents.hasNext()) {
PolyDocument document = documents.next();
System.out.println("ID: " + document.get("_id").asInt());
System.out.println("Name: " + document.get("name").asString());
}
Executing an SQL Statement
The PolyStatement yielded by the unwrapping process can now be used to execute statements in any of the supported languages. An example for SQL is given below.
For detailed documentation on the PolyStatement object, please refer to the corresponding documentation.
Imagine a collection of documents, each storing information about a specific person. To retrieve all people in our database and print them to System.out
, we can use the code below.
RelationalResult result = polyStatement.execute("sqltest", "sql", "SELECT * FROM people").unwrap(RelationalResult.class);
Iterator<PolyRow> rows = result.iterator();
while (rows.hasNext()) {
PolyRow row = rows.next();
System.out.println("ID: " + row.get("id").asInt());
System.out.println("Name: " + row.get("name").asString());
}
Executing a Cypher Query
The PolyStatement yielded by the unwrapping process can now be used to execute statements in any of the supported languages. An example for Cypher (for the Graph data model) is given below.
For detailed documentation on the PolyStatement object, please refer to the corresponding documentation.
Imagine a graph containing nodes representing people. To retrieve all nodes labeled as Person
and print their names, we can use the code below:
GraphResult result = polyStatement.execute("cyphertest", "cypher", "MATCH (n:Person) RETURN n ORDER BY n.id").unwrap(GraphResult.class);
Iterator<PolyGraphElement> elements = result.iterator();
while (elements.hasNext()) {
PolyGraphElement element = elements.next();
System.out.println("Name: " + element.get("name").asString());
System.out.println("Labels: " + element.getLabels());
}
Executing a Cypher Query Returning a Relational Result
It is possible for queries in the Labeled Property Graph model (LPG) to return a relational result. Their handling and processing is identical to the results of the relational model. Below, an example of such a statement in LPG and the handling of its result is given:
Imagine a graph containing nodes representing people. To retrieve the name and ID of a person named Alice
, we can use the code below:
RelationalResult result = polyStatement.execute("cyphertest", "cypher", "MATCH (n:Person {name: 'Alice'}) RETURN n.name, n.id").unwrap(RelationalResult.class);
Iterator<PolyRow> rows = result.iterator();
while (rows.hasNext()) {
PolyRow row = rows.next();
System.out.println("Name: " + row.get("n.name").asString());
System.out.println("ID: " + row.get("n.id").asString());
}
Unwrapping Result Types
As shown in the examples above. The result returned by the execute
method is then unwrapped into one of the concrete result types RelationalResult
, DocumentResult
, GraphResult
or ScalarResult
. The type to unwrap to must match the type of result returned by the query and is not of the users’ choice.
Trying to unwrap to a different result type will cause an exception to be thrown.
To determine the type of result, the method getResultType
provided by the result object can be used.