通过jdbi将UDT数组插入Postgres

时间:2019-07-17 22:54:22

标签: java postgresql jdbi

我正在尝试使用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();
    });
}

0 个答案:

没有答案