我正在尝试使用java / jdbi插入到包含一列的表中,该列是UDT的数组。当我运行下面的代码(最后一个块)时,出现以下异常:
org.postgresql.util.PSQLException: ERROR: malformed record literal: "test.jdbi.Account@376b4233"
Detail: Missing left parenthesis. [statement:"insert into Customer (name, accounts) values <customers>", rewritten:"insert into Customer (name, accounts) values (:__customers_0_name,:__customers_0_accounts)", parsed:"ParsedSql{sql='insert into Customer (name, accounts) values (?,?)', parameters=ParsedParameters{positional=false, parameterNames=[__customers_0_name, __customers_0_accounts]}}", arguments:{positional:{}, named:{__customers_0_name:bob,__customers_0_accounts:Account[] - [test.jdbi.Account@376b4233, test.jdbi.Account@6fb0d3ed]}, finder:[]}]
您知道我在做什么错吗?甚至支持UDT数组吗?
编辑:看来,如果我像这样入侵AccountType
,我可以插入硬编码的数组,那么有没有一种方法可以实现这种方法而又不易于进行sql注入?
@Override
public Object convertArrayElement(Account account) {
return String.format("(%s,%f)", account.getAccountId(), account.getBalance());
}
原始代码:
CREATE TYPE Account AS(
accountId VARCHAR(10),
balance NUMERIC(20, 8)
);
CREATE TABLE Customer (
name VARCHAR(20),
accounts Account[]
);
public class Customer {
private String name;
private List<Account> accounts;
public Customer() {}
public Customer(String name, List<Account> accounts) {
this.name = name;
this.accounts = accounts;
}
public String getName() { return name; }
public List<Account> getAccounts() { return accounts; }
}
public class Account {
private String accountId;
private BigDecimal balance;
public Account(String accountId, BigDecimal balance) {
this.accountId = accountId;
this.balance = balance;
}
public String getAccountId() { return accountId; }
public BigDecimal getBalance() { return balance; }
}
public class AccountType implements SqlArrayType<Account> {
@Override
public String getTypeName() {
return "Account";
}
@Override
public Object convertArrayElement(Account account) {
return account;
}
}
public static void main(String[] args) {
Jdbi jdbi = JdbiProvider.get();
Customer bob = new Customer("bob", Arrays.asList(
new Account("acc123", BigDecimal.valueOf(123)),
new Account("acc456", BigDecimal.valueOf(456))
));
jdbi.registerArrayType(Account.class, "Account");
jdbi.withHandle(h -> {
h.registerArrayType(new AccountType());
List<Customer> customers = new ArrayList<>();
customers.add(bob);
return h.createUpdate("insert into Customer (name, accounts) values <customers>")
.bindBeanList("customers", customers, Arrays.asList("name", "accounts"))
.execute();
});
}