如何结合 Jdbi @GeneratedKeys 和 @RegisterMapper
how to combine Jdbi @GeneratedKeys with @RegisterMapper
@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.class
和 PhoneNumberMapper.class
可以共存到 return 映射 bean 吗?当我执行这个时,java.lang.ClassCastException: java.math.BigDecimal cannot be cast to me.nave.persistence.domain.PhoneNumber
被抛出。
目的是 return 具有生成 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);
}
}
table 和序列
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")
);
@Mapper 和@RegisterMapper 在取回插入的 id 时未被使用。如果您希望在插入后返回 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)
}
或者再从数据库读取。
public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
BigDecimal id = save(phoneNumber);
getPhoneNumber(id); // reading it from DB
}
@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.class
和 PhoneNumberMapper.class
可以共存到 return 映射 bean 吗?当我执行这个时,java.lang.ClassCastException: java.math.BigDecimal cannot be cast to me.nave.persistence.domain.PhoneNumber
被抛出。
目的是 return 具有生成 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);
}
}
table 和序列
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")
);
@Mapper 和@RegisterMapper 在取回插入的 id 时未被使用。如果您希望在插入后返回 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)
}
或者再从数据库读取。
public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
BigDecimal id = save(phoneNumber);
getPhoneNumber(id); // reading it from DB
}