如何使用 JDBI 将二维数组从 PostgreSQL 数据库转换为 java 二维数组?
How to convert 2d array from PostgreSQL DB to java 2d array using JDBI?
如何将二维字符数组从我的 Postgres 数据库转换为本机 Java 字符[][]?这是我基于 this answer:
的尝试
import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
public class GameMapper implements ResultSetMapper<Game>{
public Game map(int index, ResultSet resultSet, StatementContext statementContext) throws SQLException
{
Array board = resultSet.getArray("BOARD");
return new Game(resultSet.getInt("ID"),
resultSet.getInt("WHOSE_TURN"),
resultSet.getInt("WINNER"),
(char[][]) board.getArray());
}
}
数据class:
public class Game {
protected int id;
protected int whoseTurn;
protected int winner;
protected char[][] board;
public Game(int id, int turn, int winner, char[][] board ) {
this.id=id;
this.whoseTurn=turn;
this.winner=winner;
this.board=board;
}
@JsonProperty
public int getId() {
return id;
}
@JsonInclude(Include.NON_NULL)
public int getWhoseTurn() {
return whoseTurn;
}
@JsonInclude(Include.NON_NULL)
public int getWinner() {
return winner;
}
public char[][] getBoard() {
return board;
}
}
DAO:
@RegisterMapper(GameMapper.class)
public interface GameDAO {
@SqlUpdate("create table if not exists GAMES (ID integer, WHOSE_TURN varchar(10), WINNER varchar(10), BOARD char(1)[][])")
void createTableIfNotExists();
@SqlUpdate("insert into GAMES (ID, WHOSE_TURN, WINNER, BOARD) values (:id, :whoseTurn, :winner, :board)")
void insert(@BindBean Game game);
}
但这会导致转换错误:
java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [[C
我需要改用 ResultSet 吗?
[[Ljava.lang.String; cannot be cast to [[C
Time to learn what Java array type names mean.
[
是 array-of
。所以 [[
是数组的数组,即两个类型名称都是二维数组。
L
表示引用类型,后跟class名称。
C
是原始类型 char
.
所以在这里,我们看到您正试图将 java.lang.String
的二维数组转换为 char
的二维数组。那没有任何意义。看起来 JDBI 将 Java 数据类型 char
映射到 SQL 字符串类型,如 character
或 character varying
,(通过检查 table在数据库中)。如果是这样,JDBC 驱动程序将从数据库中 return 作为 java.lang.String
。
因此您需要覆盖该映射以使用数据库数据类型 "char"
- 单个字符 - 或者,更简单地说,断言字符串的长度为一个字符并将它们解压缩为一个字符。所以你必须复制数组。
我查看了 postgres JDBC 驱动程序。如果列类型是 CHAR 或 VARCHAR,它会尝试将其转换为字符串数组。
else if (type == Types.CHAR || type == Types.VARCHAR)
{
Object[] oa = null;
ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(String.class, dimsLength) : new String[count]);
}
所以你会得到二维字符串数组。您需要在映射器中将其转换为 char[][]。
如何将二维字符数组从我的 Postgres 数据库转换为本机 Java 字符[][]?这是我基于 this answer:
的尝试import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
public class GameMapper implements ResultSetMapper<Game>{
public Game map(int index, ResultSet resultSet, StatementContext statementContext) throws SQLException
{
Array board = resultSet.getArray("BOARD");
return new Game(resultSet.getInt("ID"),
resultSet.getInt("WHOSE_TURN"),
resultSet.getInt("WINNER"),
(char[][]) board.getArray());
}
}
数据class:
public class Game {
protected int id;
protected int whoseTurn;
protected int winner;
protected char[][] board;
public Game(int id, int turn, int winner, char[][] board ) {
this.id=id;
this.whoseTurn=turn;
this.winner=winner;
this.board=board;
}
@JsonProperty
public int getId() {
return id;
}
@JsonInclude(Include.NON_NULL)
public int getWhoseTurn() {
return whoseTurn;
}
@JsonInclude(Include.NON_NULL)
public int getWinner() {
return winner;
}
public char[][] getBoard() {
return board;
}
}
DAO:
@RegisterMapper(GameMapper.class)
public interface GameDAO {
@SqlUpdate("create table if not exists GAMES (ID integer, WHOSE_TURN varchar(10), WINNER varchar(10), BOARD char(1)[][])")
void createTableIfNotExists();
@SqlUpdate("insert into GAMES (ID, WHOSE_TURN, WINNER, BOARD) values (:id, :whoseTurn, :winner, :board)")
void insert(@BindBean Game game);
}
但这会导致转换错误:
java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [[C
我需要改用 ResultSet 吗?
[[Ljava.lang.String; cannot be cast to [[C
Time to learn what Java array type names mean.
[
是 array-of
。所以 [[
是数组的数组,即两个类型名称都是二维数组。
L
表示引用类型,后跟class名称。
C
是原始类型 char
.
所以在这里,我们看到您正试图将 java.lang.String
的二维数组转换为 char
的二维数组。那没有任何意义。看起来 JDBI 将 Java 数据类型 char
映射到 SQL 字符串类型,如 character
或 character varying
,(通过检查 table在数据库中)。如果是这样,JDBC 驱动程序将从数据库中 return 作为 java.lang.String
。
因此您需要覆盖该映射以使用数据库数据类型 "char"
- 单个字符 - 或者,更简单地说,断言字符串的长度为一个字符并将它们解压缩为一个字符。所以你必须复制数组。
我查看了 postgres JDBC 驱动程序。如果列类型是 CHAR 或 VARCHAR,它会尝试将其转换为字符串数组。
else if (type == Types.CHAR || type == Types.VARCHAR)
{
Object[] oa = null;
ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(String.class, dimsLength) : new String[count]);
}
所以你会得到二维字符串数组。您需要在映射器中将其转换为 char[][]。