使用
将 JDBC 驱动程序添加到您的应用程序中,例如作为 Gradle 依赖项
dependencies {
runtimeOnly(org.neo4j:neo4j-jdbc-full-bundle:6.0.0) (1)
}
1 | Maven 项目的坐标相同。 |
然后,您可以像使用任何其他 JDBC 驱动程序一样使用 Neo4j JDBC 驱动程序
如果任何工具要求您提供具体驱动程序类的名称,则为 org.neo4j.jdbc.Neo4jDriver 。 |
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
public final class Quickstart {
static void queryWithCypher() {
var query = """
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
RETURN m.title AS title, collect(p.name) AS actors
ORDER BY m.title
""";
var url = "jdbc:neo4j://localhost:7687";
var username = "neo4j";
var password = "verysecret";
try (var con = DriverManager.getConnection(url, username, password); (1)
var stmt = con.createStatement(); (2)
var result = stmt.executeQuery(query)) { (3)
while (result.next()) { (4)
var movie = result.getString(1); (5)
var actors = (List<String>) result.getObject("actors"); (6)
System.out.printf("%s%n", movie);
actors.forEach(actor -> System.out.printf("\t * %s%n", actor));
}
}
catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
}
1 | 实例化 JDBC 连接。无需事先执行任何类加载,驱动程序将自动注册 |
2 | 创建(可重用)语句 |
3 | 执行查询 |
4 | 迭代结果,就像使用任何其他 JDBC 结果集一样 |
5 | JDBC 的索引从 1 开始 |
6 | JDBC 还允许按名称检索结果列;Neo4j JDBC 驱动程序还支持复杂对象,例如列表 |
在上面的示例中,我们使用了 Neo4j 的通用语言 Cypher® 来查询数据库。Neo4j JDBC 驱动程序对使用 SQL 也提供了有限的支持。它可以自动或逐案执行此操作。要翻译单个,请调用 java.sql.Connection#nativeSQL(String)
并将结果用于您的查询。对于自动翻译,请实例化驱动程序并将可选的 URL 参数 sql2cypher
设置为 true
。以下示例说明了如何操作
var query = """
SELECT m.title AS title, collect(p.name) AS actors
FROM Person as p
JOIN Movie as m ON (m.id = p.ACTED_IN)
ORDER BY m.title
"""; (1)
var url = "jdbc:neo4j://localhost:7687?enableSQLTranslation=true";
try (var con = DriverManager.getConnection(url, username, password);
var stmt = con.createStatement();
var result = stmt.executeQuery(query)) {
while (result.next()) {
var movie = result.getString(1);
var actors = (List<String>) result.getObject("actors");
System.out.printf("%s%n", movie);
actors.forEach(actor -> System.out.printf("\t * %s%n", actor));
}
}
1 | 此 SQL 查询将转换为前一个示例中的相同 Cypher 查询。其余方法与之前相同。 |
有关更多信息,请参阅 SQL 到 Cypher 翻译。
JDBC 规范不支持命名参数,仅支持基于索引的参数,从 1
开始。因此,对于所有 PreparedStatement
实例,您需要像这样指定参数
PreparedStatement
中的参数var cypher = "CREATE (m:Movie {title: $1})";
try (var con = DriverManager.getConnection(url, username, password);
PreparedStatement stmt = con.prepareStatement(cypher);) {
stmt.setString(1, "Test");
stmt.executeUpdate();
}
这独立于 SQL 到 Cypher 的翻译机制
PreparedStatement
中的参数(SQL 变体)var sql = "INSERT INTO Movie (title) VALUES (?)";
try (var con = DriverManager.getConnection(url + "?enableSQLTranslation=true", username, password);
PreparedStatement stmt = con.prepareStatement(sql);) {
stmt.setString(1, "Test");
stmt.executeUpdate();
}
要使用命名参数,请将 PreparedStatement
向下转换为 Neo4jPreparedStatement
。
Neo4jPreparedStatement
中的命名参数var match = "MATCH (n:Movie {title: $title}) RETURN n.title AS title";
try (var con = DriverManager.getConnection(url, username, password);
Neo4jPreparedStatement stmt = (Neo4jPreparedStatement) con.prepareStatement(match);) {
stmt.setString("title", "Test");
try (var resultSet = stmt.executeQuery()) {
while (resultSet.next()) {
LOGGER.info(resultSet.getString("title"));
}
}
}
通过环境变量获取连接
如果您乐于直接依赖 org.neo4j.jdbc.Neo4jDriver
并希望尽可能轻松地获取连接,则可能希望使用 fromEnv
// import org.neo4j.jdbc.Neo4jDriver;
try (var con = Neo4jDriver.fromEnv().orElseThrow(); (1)
var stmt = con.createStatement();
var result = stmt.executeQuery(query)) {
// Same loop as earlier
}
catch (SQLException ex) {
throw new RuntimeException(ex);
}
1 | 请注意,我们在此处直接使用具体驱动程序类,以及方法如何返回可选值:如果未找到所需的连接变量,则无法创建连接。 |
fromEnv
方法查找一些特定的系统环境变量,并遵循 12 要素应用程序 原则
-
首先,它在系统环境中查找
-
其次,它在当前工作目录中查找名为
.env
的文件。有一些重载允许您配置要查找的目录和文件名。
支持的变量为
NEO4J_URI
-
要连接到的实例的地址或 URI。
NEO4J_USERNAME
-
(可选)用户名。
NEO4J_PASSWORD
-
(可选)密码。
NEO4J_SQL_TRANSLATION_ENABLED
-
(可选)是否启用完整的 SQL 到 Cypher 翻译,默认为
false
。
系统环境和 .env 文件中的信息将合并。例如,如果 NEO4J_SQL_TRANSLATION_ENABLED 位于系统环境中,但不在 .env 文件中,它仍将被获取。鉴于优先级顺序,系统环境中的信息始终优先于 .env 文件。 |
此功能在使用 Neo4j AuraDB 时特别有用。创建新的 AuraDB 实例时,您可以下载一个 .env
文件,您可以直接将其与 Neo4j JDBC 驱动程序一起使用
try (
var con = Neo4jDriver.fromEnv("Neo4j-cb3d8b2d-Created-2024-02-14.txt")
.orElseThrow();
var stmt = con.createStatement();
var movies = stmt.executeQuery("MATCH (n:Movie) RETURN n.title AS title")
) {
while (movies.next()) {
System.out.println(movies.getString("title"));
}
}