PostgreSQL 教程: 在 Java 中处理数组类型的数据

九月 9, 2024

摘要:在本教程中,您将学习如何在 Java 中处理 PostgreSQL 数组。

目录

介绍

在 Java 和 PL/pgSQL 中,数组是开发人员经常使用的一项强大的编程特性。但是,当两者尝试相互通信时,接口可能会变得棘手。本节探讨了如何使用 java.sql.Array 接口编写简单的代码,在 PostgreSQL 中插入、检索和更新数组。

为了说明该功能,让我们设置一个简单的表,该表将国家名称以 TEXT 类型存储在一列中,将国家的一些城市列表以 TEXT ARRAY 类型存储在第二列中。

CREATE TABLE city_example (
  country TEXT, 
  cities TEXT[]
);

现在,我们将使用 JDBC 接口将数据插入到此表中,检索数据并更新数据。

插入 ARRAY

任何熟悉 Java 的人都曾使用过一种或另一种形式的数组。但是,在将这些数组存储到 PostgreSQL 中之前,需要将它们映射到 java.sql 包中提供的接口:Array。

JDBC 驱动提供了将 Java 数组映射到其相应的 PostgreSQL 数组的函数。映射是特定于数据库的,并定义在 PostgreSQL JDBC 的 org.postgresql.jdbc2.TypeInfoCache 文件中。请务必注意,映射区分大小写。例如,“INTEGER” 与 “integer” 不同。

在下面的代码中,使用 Connection 接口的 createArrayOf 函数,在插入前将 Java 中的 String 数组转换为 PostgreSQL 中的 TEXT 数组。

try {
  String[] usa = {"New York", "Chicago", "San Francisco"};
  String[] canada = {"Montreal", "Toronto", "Vancouver"};
  String[] uk = {"London", "Birmingham", "Oxford"};

  /* Convert String[] to java.sql.Array using JDBC API */
  Array arrayUSA = conn.createArrayOf("text", usa);
  Array arrayCanada = conn.createArrayOf("text", canada);
  Array arrayUK = conn.createArrayOf("text", uk);
  String sql = "INSERT INTO city_example VALUES (?, ?)";
  PreparedStatement pstmt = conn.prepareStatement(sql);

  pstmt.setString(1, "USA");
  pstmt.setArray(2, arrayUSA);
  pstmt.executeUpdate();

  pstmt.setString(1, "Canada");
  pstmt.setArray(2, arrayCanada);
  pstmt.executeUpdate();
  pstmt.setString(1, "UK");
  pstmt.setArray(2, arrayUK);
  pstmt.executeUpdate();

  conn.commit();
} catch (Exception e) {
  System.out.println(e.getMessage());
  e.printStackTrace();
}

请注意,在 Connection.createArrayOf 中指定的数据类型必须是 PostgreSQL 类型,而不是 java.sql.Types。JDBC 驱动在运行时会查找数据类型,以创建 java.sql.Array 对象。

执行此代码时,将在 city_example 表中产生以下数据:

select * from city_example;
 country | cities
---------+--------------------------------------
 USA     | {"New York",Chicago,"San Francisco"}
 Canada  | {Montreal,Toronto,Vancouver}
 UK      | {London,Birmingham,Oxford}
(3 rows)

检索 ARRAY

检索数组的过程与插入数组的过程完全相反。在下面的示例中,第一步是获取包含所需数据的 ResultSet,第二步是将 PostgreSQL 中的 TEXT 数组转换为 Java 中的 String 数组。

try {
  String sql = "SELECT * FROM city_example";
  PreparedStatement ps = conn.prepareStatement(sql);
  ResultSet rs = ps.executeQuery();

  while (rs.next()) {
    System.out.println("Country: " + rs.getString(1));
    System.out.println("---------------");

    Array cities = rs.getArray(2);
    String[] str_cities = (String[])cities.getArray();

    for (int i = 0; i < str_cities.length; i++)
      System.out.println(str_cities[i]);
    System.out.println("");
  }
} catch (Exception e) {
  System.out.println(e.getMessage());
  e.printStackTrace();
}

对于上面的代码,输出到标准输出窗口的是:

Country: USA
---------------
New York
Chicago
San Francisco

Country: Canada
---------------
Montreal
Toronto
Vancouver

Country: UK
---------------
London
Birmingham
Oxford

更新 ARRAY

在 PostgreSQL 中更新数组的过程与插入数组的过程非常接近。在下面的代码中,一组新的美国城市被声明为 Java 中的 String 数组,然后在更新现有行之前将其转换为 PostgreSQL 中的 TEXT 数组。

try {
  String[] usa = {"New York", "Chicago", "San Francisco", "Miami", "Seattle"};
  Array arrayUSA = conn.createArrayOf("text", usa);

  String sql = "UPDATE city_example SET cities = ? WHERE country = 'USA'";
  PreparedStatement pstmt = conn.prepareStatement(sql);

  pstmt.setArray(1, arrayUSA);
  pstmt.executeUpdate();

  conn.commit();
} catch (Exception e) {
  System.out.println(e.getMessage());
  e.printStackTrace();
}

执行此代码后,数据库中的表数据如下所示:

select * from city_example;
 country | cities
---------+----------------------------------------------------
 Canada  | {Montreal,Toronto,Vancouver}
 UK      | {London,Birmingham,Oxford}
 USA     | {"New York",Chicago,"San Francisco",Miami,Seattle}
(3 rows)