为给定的 pojo 类型为 myBatis3 设计 INSERT 映射器

Designing INSERT mapper for myBatis3 for given pojo type

如果我有一个像

这样的 pojo 模型,myBatis3 中的 INSERT 映射器会是什么样子
class DR {
 FormatType format;
}

class SQLDR extends DR{
 String sql;
}

class PDR extends DR {
 Predicate predicate;
}

class Download {
 DR request;
 String status;
 long size;
}

我想在 table 中插入下载对象,如何在 myBatis3 中设计 INSERT 映射器,因为我在运行时设置了 SQLDR 和 PDR 类型的下载,它应该能够根据格式类型获取值,并且设置它。

我正在尝试这样的映射器,它不起作用

<sql id="DOWNLOAD_FIELD_TYPES">
    #{key,jdbcType=VARCHAR},
    <choose>
        <when test="format = 'SQL'"> #{request.sql,jdbcType=VARCHAR},</when>
        <otherwise> #{request.predicate,jdbcType=VARCHAR}, </otherwise>
    </choose>
    #{status,jdbcType=OTHER},
    #{size,jdbcType=BIGINT},
    #{request.format,jdbcType=OTHER},
</sql>

<sql id="DOWNLOAD_FIELDS">
    key,filter,status,size,format
</sql>

 <insert id="create" parameterType="Download">
    INSERT INTO download(<include refid="DOWNLOAD_FIELDS"/>)
    VALUES(<include refid="DOWNLOAD_FIELD_TYPES"/>)
 </insert>

原因:org.apache.ibatis.reflection.ReflectionException:没有 getter for 属性 named 'sql';在‘class DR’

在这种情况下,最简单的方法是使 DR 抽象并向其添加一个方法:

abstract class DR {
   public String getFilter();
}

class SQLDR {
   String sql;
   public String getFilter() {
       return sql;
   }
}

class PDR {
   Predicate predicate;
   public String getFilter() {
       return toString(predicate);
   }
}

然后在映射器中无条件地使用这个新的属性:

<sql id="DOWNLOAD_FIELD_TYPES">
    #{key,jdbcType=VARCHAR},
    #{request.filter},
    #{status,jdbcType=OTHER},
    #{size,jdbcType=BIGINT},
    #{request.format,jdbcType=OTHER},
</sql>