如何在Java中绑定hstore[]值

如何在Java中绑定hstore[]值,java,sql,postgresql,hstore,jdbi,Java,Sql,Postgresql,Hstore,Jdbi,我试图将人们的电话号码和地址存储在数据库表中。我想支持多个电话号码和地址,并希望格式在不同的国家是不同的。我决定使用hstore来实现这种灵活性,并允许通过特定字段进行高效查询。目前,我可以从数据库接收值,但找不到从Java插入值的方法。该表(简化)如下所示: CREATE TABLE IF NOT EXISTS contacts ( " + "id uuid NOT NULL, " + "title character varying NOT NULL DEFA

我试图将人们的电话号码和地址存储在数据库表中。我想支持多个电话号码和地址,并希望格式在不同的国家是不同的。我决定使用hstore来实现这种灵活性,并允许通过特定字段进行高效查询。目前,我可以从数据库接收值,但找不到从Java插入值的方法。该表(简化)如下所示:

CREATE TABLE IF NOT EXISTS contacts ( "
        + "id uuid NOT NULL, "
        + "title character varying NOT NULL DEFAULT '', "
        + "first_name character varying NOT NULL, "
        + "last_name character varying NOT NULL, "
        + "phones hstore[] NOT NULL DEFAULT '{}', "
        + "addresses hstore[]  NOT NULL DEFAULT '{}')"
我已经创建了一个定制的JDBI绑定器来绑定这些值,但是我尝试着无法执行该语句。当前活页夹代码段如下所示:

@Override
public void bind(SQLStatement<?> q, BindContactBean bind, ContactBean bean) {
        q.bind("phones",
                getHstoreArray(q, PhoneDetailMapper.toMapArray(bean.phones.get())));
        q.bind("addresses",
                getHstoreArray(q, AddressDetailMapper.toMapArray(bean.addresses.get())));
private Array getHstoreArray(SQLStatement<?> q, Map<String, String>[] map) {
    try {
        return q.getContext().getConnection().createArrayOf("hstore", map);
    } catch (SQLException e) {
        throw new IllegalArgumentException(e);
    }
}
查询扩展为:

INSERT INTO contacts ( 
id, first_name, last_name, status, phones ) 
VALUES ( '9be1a040-b408-11e3-bb43-00231832fa86',  'Maximum', 'Details', 4, 
'{"{type=mobile, extracted_number=extracted, number=07777 66 55 44}"}'
)
如果我尝试从PGAdmin的SQL编辑器运行它,返回的错误是:

ERROR:  Syntax error near 'm' at position 6
LINE 5: '{"{type=mobile, extracted_number=extracted, number=07777 66...
        ^
********** Error **********

ERROR: Syntax error near 'm' at position 6
SQL state: XX000
Character: 179
我曾考虑过使用JSON而不是hstore[],但这会使特定字段的查询速度变慢、准确性降低(本质上是文本搜索),我宁愿避免使用JSON。 我在hstore之前尝试过的另一个选项是UDT数组,但如果不为PGobject编写解析器,甚至无法从数据库中读取它,这看起来不像是一个简单的任务


编辑

我查看了数据库中的数据,并以以下方式进行了转义:

'{"\"type\"=>\"mobile\", \"number\"=>\"07777 66 55 44\", \"extracted_number\"=>\"777665544\""}'

我可以从SQL编辑器手动运行查询,但在Java中仍然不走运。

我找到了一个解决方案,Postgres驱动程序中有一个名为HStoreConverter的类,它可以将映射转换为字符串文字。不确定这是不是最好的方法,但似乎是可行的,修改了下面的助手函数

        private Array getHstoreArray(SQLStatement<?> q, Map<String, String>[] maps) {
            try {
                String[] hstores = new String[maps.length];
                for (int i = 0; i < maps.length; i++)
                    hstores[i] = HStoreConverter.toString(maps[i]);
                return q.getContext().getConnection().createArrayOf("hstore", hstores);
            } catch (SQLException e) {
                throw new IllegalArgumentException(e);
            }
        }
私有数组getHstoreArray(sqlq语句,Map[]maps){ 试一试{ String[]hstores=新字符串[maps.length]; 对于(int i=0;i
        private Array getHstoreArray(SQLStatement<?> q, Map<String, String>[] maps) {
            try {
                String[] hstores = new String[maps.length];
                for (int i = 0; i < maps.length; i++)
                    hstores[i] = HStoreConverter.toString(maps[i]);
                return q.getContext().getConnection().createArrayOf("hstore", hstores);
            } catch (SQLException e) {
                throw new IllegalArgumentException(e);
            }
        }