Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
一种绑定Java映射的方法<;字符串,对象>;到JDBI INSERT语句中的sql varchar_Java_Sql_Jdbi - Fatal编程技术网

一种绑定Java映射的方法<;字符串,对象>;到JDBI INSERT语句中的sql varchar

一种绑定Java映射的方法<;字符串,对象>;到JDBI INSERT语句中的sql varchar,java,sql,jdbi,Java,Sql,Jdbi,在JDBI@BindBean注释中,有没有一种方法可以将javaMap绑定到varchar 例如,我有一个classSomething.class,我创建了一个 @SqlBatch(“插入到某物(名称、负载)值(:名称、负载)”) 现在在我的java类中,name是String类型,payload是Map类型,我希望在DB表中类型是varchar(…)。现在我想把Map对象作为一个JSON对象插入到列中,这是不是可以通过创建我自己的复杂绑定器来实现的,如中所定义的?而不是让我的负载在java中是

在JDBI@BindBean注释中,有没有一种方法可以将java
Map
绑定到varchar

例如,我有一个class
Something.class
,我创建了一个

@SqlBatch(“插入到某物(名称、负载)值(:名称、负载)”)


现在在我的java类中,
name
String
类型,
payload
Map
类型,我希望在DB表中类型是
varchar(…)
。现在我想把
Map
对象作为一个JSON对象插入到列中,这是不是可以通过创建我自己的复杂绑定器来实现的,如中所定义的?而不是让我的负载在java中是String类型

修复了中建议的创建ArgumentFactory活页夹的问题

因此,我需要创建一个只包含一个类型为
Map
的字段的类,从
org.skife.jdbi.v2.tweak实现
arumment
接口

public class NotificationPayloadArgument implements Argument {
  private NotificationPayload payload;

  NotificationPayloadArgument(NotificationPayload payload) {
      this.payload = payload;
  }
    
  @Override
  public void apply(int i, PreparedStatement preparedStatement, StatementContext statementContext)
    throws SQLException {
      preparedStatement.setString(i, toString());
  }

  @Override
  public String toString() {
      return new JSONObject(payload).toString();
  } 

}
为了完成这项工作,我当然需要实现一个Factory类,该类使用我新创建的类型实现
org.skife.jdbi.v2.tweak.ArgumentFactory
接口,因此工厂最终是这样的:

public class NotificationPayloadFactory implements ArgumentFactory<NotificationPayload> {

    @Override
    public boolean accepts(Class<?> expectedType, Object value, StatementContext ctx) {
        return value instanceof NotificationPayload;
    }

    @Override
    public Argument build(Class<?> expectedType, NotificationPayload value, StatementContext ctx) {
        return value;
    }

}
我试着用一个工厂来制作一张
地图
,但没能做到这一点,NPE有风险

编辑 我之所以在
NotificationPayload
中重写
toString()
,是因为我需要json格式的有效负载,在某些地方我需要字符串对象。但也可以删除它,然后在调用
toString()
preparedStatement.setString()
中使用
新的JSONObject(有效负载).toString()

公共类映射参数实现参数{
    public class MapArgument implements Argument {

    private Map<String, Object> payload;

    private ObjectMapper objectMapper;

    public MapArgument(ObjectMapper objectMapper, Map<String, Object> payload) {
        this.objectMapper = objectMapper;
        this.payload = payload;
    }

    @Override
    public void apply(int i, PreparedStatement statement, StatementContext statementContext) throws SQLException {
        try {
            statement.setString(i, objectMapper.writeValueAsString(payload));
        } catch (JsonProcessingException e) {
            log.info("Failed to serialize payload ", e);
        }
    }
}

    public class MapArgumentFactory implements ArgumentFactory<Map<String, Object>> {

    private ObjectMapper mapper;

    public MapArgumentFactory(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public boolean accepts(Class<?> type, Object value, StatementContext statementContext) {
        return value instanceof Map;
    }

    @Override
    public Argument build(Class<?> type, Map<String, Object> map, StatementContext statementContext) {
        return new MapArgument(mapper, map);
    }
}
专用地图有效载荷; 私有对象映射器对象映射器; 公共映射参数(ObjectMapper ObjectMapper,映射负载){ this.objectMapper=objectMapper; 这个有效载荷=有效载荷; } @凌驾 public void apply(inti、PreparedStatement语句、StatementContext语句)引发SQLException{ 试一试{ statement.setString(i,objectMapper.writeValueAsString(有效负载)); }捕获(JsonProcessingException e){ log.info(“未能序列化有效负载”,e); } } } 公共类MapArgumentFactory实现ArgumentFactory{ 私有对象映射器映射器; 公共MapArgumentFactory(ObjectMapper映射器){ this.mapper=mapper; } @凌驾 公共布尔接受(类类型、对象值、语句上下文语句上下文){ 映射的返回值实例; } @凌驾 公共参数生成(类类型、映射映射、语句上下文语句上下文){ 返回新的映射参数(映射器、映射); } }
然后将地图转换为JSON对象,正如您所说的x)检查我不能这样做,Nathan,因为我需要它作为其他东西的地图。但无论如何,谢谢你的建议。如果你试图将
地图
存储在一行中,它显然设计得不好。。。每个键/值应以一行的形式存储在辅助表中,链接到
Something.name
(或每个
name+playload\u键一行)。由此,可以很容易地迭代映射以创建每一行,但也可以很容易地获得用于构建映射的行。无需将地图解析为某些格式的
字符串
sort@AxelH谢谢-是的,这是一个糟糕的设计,但我现在不允许改变它,因为如果改变它将打破许多传统的东西,这是我们目前不允许做的。首先,当我们摆脱了所有遗留的东西,我可以做任何我想做的改变:)。但是我发现了这一点,所以我要尝试做一些全局绑定,看看它是否有效:)。我认为它应该是地图的值实例,如这里所述@arpitagaral你是对的,我编辑了我的答案,使之正确,所以现在
value instanceof NotificationPayload
是正确的。现在它看起来是正确的,你也可以参考我的答案。
    public class MapArgument implements Argument {

    private Map<String, Object> payload;

    private ObjectMapper objectMapper;

    public MapArgument(ObjectMapper objectMapper, Map<String, Object> payload) {
        this.objectMapper = objectMapper;
        this.payload = payload;
    }

    @Override
    public void apply(int i, PreparedStatement statement, StatementContext statementContext) throws SQLException {
        try {
            statement.setString(i, objectMapper.writeValueAsString(payload));
        } catch (JsonProcessingException e) {
            log.info("Failed to serialize payload ", e);
        }
    }
}

    public class MapArgumentFactory implements ArgumentFactory<Map<String, Object>> {

    private ObjectMapper mapper;

    public MapArgumentFactory(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public boolean accepts(Class<?> type, Object value, StatementContext statementContext) {
        return value instanceof Map;
    }

    @Override
    public Argument build(Class<?> type, Map<String, Object> map, StatementContext statementContext) {
        return new MapArgument(mapper, map);
    }
}