用法

将 JDBC 驱动程序添加到您的应用程序,例如作为 Gradle 依赖项

列表 1. 在基于 Gradle 的项目中将完整捆绑包用作运行时依赖项
dependencies {
    runtimeOnly(org.neo4j:neo4j-jdbc-full-bundle:6.5.1) (1)
}
1 Maven 项目的坐标相同。

然后,您可以像使用任何其他 JDBC 驱动程序一样使用 Neo4j JDBC 驱动程序

如果任何工具询问您具体驱动程序类的名称,它是 org.neo4j.jdbc.Neo4jDriver
列表 2. 获取连接并执行查询
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。以下示例展示了如何操作

列表 3. 配置 JDBC 驱动程序以自动将 SQL 翻译为 Cypher。
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 实例,您需要像这样指定参数

列表 4. 将参数与 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 的翻译机制无关

列表 5. 将参数与 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

列表 6. 将命名参数与 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

列表 7. 从环境变量获取连接
// 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 请注意,我们在此处直接使用具体的驱动程序类,以及方法如何返回一个 Optional:如果找不到所需的连接变量,则无法创建连接。

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 驱动程序一起使用

列表 8. 使用 AuraDB 中的 .env 文件
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"));
    }
}
© . All rights reserved.