如何将Jdbi @GeneratedKeys与@RegisterMapper结合起来

时间:2016-09-03 00:35:49

标签: jdbi

@RegisterMapper(PhoneNumberMapper.class)
public interface PhoneNumberJdbiDAO
{
    @Transaction
    @GetGeneratedKeys(columnName = "ID", value = OracleGeneratedKeyMapper.class)
    @SqlUpdate("INSERT INTO PHONE_NUMBER (ID, COUNTRY_CODE_ISO2, PHONE_NUMBER, CREATE_DATETIME, UPDATE_DATETIME) " +
           "VALUES (PHONE_NUMBER_SEQ.NEXTVAL, :countryCode, :phoneNumber, :createDateTime, :updateDateTime)")
    PhoneNumber save(@BindBean PhoneNumber phoneNumber);
}

OracleGeneratedKeyMapper.classPhoneNumberMapper.class可以共存以返回映射的bean吗?当我执行此操作时,正在抛出java.lang.ClassCastException: java.math.BigDecimal cannot be cast to me.nave.persistence.domain.PhoneNumber

目的是返回一个带有生成ID的bean。

PhoneNumberMapper

public class PhoneNumberMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<PhoneNumber>
{
    @Override
    public PhoneNumber map(int index, ResultSet rs, StatementContext ctx) throws SQLException
    {
        CountryCode countryCodeIso2 = CountryCode.getByCodeIgnoreCase(rs.getString("COUNTRY_CODE_ISO2"));

        DateTime phoneNumberCreateDatetime =
            new DateTime(rs.getTimestamp("CREATE_DATETIME").getTime(), DateTimeZone.UTC);

        DateTime phoneNumberUpdateDatetime =
            new DateTime(rs.getTimestamp("UPDATE_DATETIME").getTime(), DateTimeZone.UTC);

        return new PhoneNumber
            .Builder(countryCodeIso2, rs.getString("PHONE_NUMBER"))
            .id(rs.getBigDecimal("ID"))
            .createDateTime(phoneNumberCreateDatetime)
            .updateDateTime(phoneNumberUpdateDatetime)
            .build();
    }
}

这是OracleGeneratedKeyMapper。

public class OracleGeneratedKeyMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<BigDecimal>
{
    @Override
    public BigDecimal map(int index, ResultSet r, StatementContext ctx) throws SQLException
    {
        return r.getBigDecimal(1);
    }
}

表和序列

CREATE SEQUENCE  "PHONE_NUMBER_SEQ"  MINVALUE 1 INCREMENT BY 1;

CREATE TABLE "TEST"."PHONE_NUMBER"
(     "ID" NUMBER NOT NULL,
      "COUNTRY_CODE_ISO2" VARCHAR2(2 CHAR) NOT NULL,
      "PHONE_NUMBER" VARCHAR2(32 CHAR) NOT NULL,
      "CREATE_DATETIME" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP(0) NOT NULL,
      "UPDATE_DATETIME" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP(0) NOT NULL,
  CONSTRAINT "PHONE_NUMBER_PK" PRIMARY KEY ("ID")
);

1 个答案:

答案 0 :(得分:1)

获取插入的id时,不使用@Mapper和@RegisterMapper。如果您希望在插入后返回PhoneNumber对象(仅包含id),则可以使用以下映射器。

public class PhoneNumberIdMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<BigDecimal>
{
  @Override
  public BigDecimal map(int index, ResultSet r, StatementContext ctx) throws SQLException
  {
    return new PhoneNumber(r.getBigDecimal(1));
  }
}

但是如果你想获得整个PhoneNumber对象,我们需要手动完成。我可以想到两个选择,

public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
    BigDecimal id = save(phoneNumber);
    phoneNumber.setId(id)
}

或者再次从DB中读取它。

public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
    BigDecimal id = save(phoneNumber);
    getPhoneNumber(id); // reading it from DB
}