Java MyBatis类型处理程序导致表插入不兼容

Java MyBatis类型处理程序导致表插入不兼容,java,mybatis,typehandler,Java,Mybatis,Typehandler,可能是我误解/误用了MyBatis类型处理程序,但我发现它们可能会导致与表插入方法相关的不兼容问题 考虑课程: public class TableA { int idA; String name; // constructors, getters, etc. } public class TableB { int idB; TableA objA; Date startDate; // constructors, getters, et

可能是我误解/误用了MyBatis类型处理程序,但我发现它们可能会导致与表插入方法相关的不兼容问题

考虑课程:

public class TableA {
    int idA;
    String name;
    // constructors, getters, etc.
}

public class TableB {
    int idB;
    TableA objA;
    Date startDate;
    // constructors, getters, etc.
}
我声明关联的表,其中对于表B,Id_A是表行的外键:

create table Table_A ( int Id_A int auto_increment primary key, name varchar(50) );
create table Table_B ( int Id_B int auto_increment primary key, Id_A int, Start_Date datetime );
我为TableA声明了一个简单的映射器,TableAMapper.java,方法如下:

@Insert({ "insert into Table_A ( Id_A, name ) values ( #{idA}, #{name} )" })
@Options(useGeneratedKeys=true, keyProperty="idA")
int insertReturnPK( TableA record );
对于TableBMapper,类型处理程序用于填充TableB.objA,类似的insertReturnPK方法使用类型处理程序填充objA字段:

<resultMap id="BaseResultMap" type="TableA">
    <id column="Id_B" jdbcType="INTEGER" property="idB" />
    <result column="Id_A" jdbcType="INTEGER" property="objA" typeHandler="TableATypeHandler" />
    <result column="Start_Date" jdbcType="TIMESTAMP" property="startDate" />
</resultMap>

@Insert({ "insert into Table_B ( Id_A, Id_B, Start_Date )",
    "values ( #{idB},",
    "#{objA,typeHandler=TableATypeHandler}, #{startDate} )" })
@Options(useGeneratedKeys=true, keyProperty="idA")
int insertReturnPK( TableA record );

@Insert({“Insert into Table_B(Id_A,Id_B,Start_Date)”,
“值(#{idB},”,
“{objA,typeHandler=TableATypeHandler},{startDate}”)
@选项(useGeneratedKeys=true,keyProperty=“idA”)
int insertReturnPK(表A记录);
TableA类型处理程序如下所示:

public class TableATypeHandler extends extends BaseTypeHandler<TableA> {
    ...

    @Override
    public void setNonNullParameter( PreparedStatement ps, int colIdx, TableA parameter, JdbcType jdbcType ) throws SQLException {
        // code to set the specified column indexed by colIdx in Table_A
    }
}
公共类TableTypeHandler扩展了BaseTypeHandler{
...
@凌驾
public void setNonNullParameter(PreparedStatement ps,int colIdx,TableA参数,JdbcType JdbcType)引发SQLException{
//设置表A中由colIdx索引的指定列的代码
}
}
问题终于解决了TableA.insertReturnPK和TableB.insertReturnPK不兼容。或者更具体地说,它们调用TableATypeHandler.setNonNullParameter有两个截然不同的用途:

  • TableBMapper.insertReturnPK使用colIdx=2调用它,将第2列设置为Table_B,主键为Table_A,即Table_A.Id_A(整数)
  • MyBatis隐式地使用TableBMapper.insertReturnPK调用中的TableTypeHandler填充表A的列。 换句话说,当调用colIdx=2的TableATypeHandler.setNonNullParameter时,它希望使用tableA.name值(字符串)设置prepare语句。此外,在此上下文中,为表_A中的每一列调用setNonNullParameter,而在1中。仅调用一次is以获取表_A的主键
  • 通过MyBatis而不是在2中隐式使用TableTypeHandler,可以很容易地避免这个问题。或者将setNonNullParameter更改为具有两个列索引,即一个属于ps(目标列索引),另一个属于参数(源列索引)


    有人见过这个吗?还有解决方法吗?

    首先:在映射器中为表B插入ReturnPK应该将表B作为参数。第二:为什么需要使用handler呢?只是在将外键插入到表#B中的A时不要使用它,该表使用#{objA.id}填充该列。谢谢。是的,打字错误。争论应该是一个表格。关于使用#{objA.id}的观点也很好。使用handler是因为MyBatis生成器的配置。是的,一个解决办法是绕过这一点。同样,这也是一个好的地方。第一:表B的映射器中的insertReturnPK应该将表B作为参数。第二:为什么需要使用handler呢?只是在将外键插入到表#B中的A时不要使用它,该表使用#{objA.id}填充该列。谢谢。是的,打字错误。争论应该是一个表格。关于使用#{objA.id}的观点也很好。使用handler是因为MyBatis生成器的配置。是的,一个解决办法是绕过这一点。再说一次,好地方。