MyBatis和Generics:返回类型ArrayList <! - ? extends MyClass - >返回Nulls

时间:2013-10-11 01:16:37

标签: java generics arraylist wildcard mybatis

我正在尝试使用MyBatis返回从超类扩展的类型:

Mapper.java

@Select("SELECT * FROM ${type} WHERE objectId >= ${start} AND objectId <= ${end}")
ArrayList<? extends ContentProviderBean> getFeed(@Param("type") String type, @Param("start") int start, @Param("end") int end);

但它会返回ArrayListnull

用于访问它的DAO使用相同的扩展通配符语法,所以我假设问题是MyBatis映射器不喜欢它。但是,我无法找到任何说明情况的文件。

是否有人对此问题有任何建议或解决方法?

1 个答案:

答案 0 :(得分:2)

您可以尝试将类型添加到结果列并配置@TypeDiscriminator以向mybatis提供要实例化的类的提示:

@Select("SELECT t.*, ${type} as type_discriminator" + 
        " FROM ${type} as t " +
        " WHERE objectId >= ${start} AND objectId <= ${end}")
@TypeDiscriminator(column = "type_discriminator",
    cases = {
        @Case (value="SomeContentProviderBeanSubclass", 
               type=SomeContentProviderBeanSubclass.class,
            results={
                @Result(property="someField", column="some_field"),
                // other columns mapping
        }),
        @Case (value="OtherContentProviderBeanSubclass", 
               type=OtherContentProviderBeanSubclass.class,
            results={
                @Result(property="otherField", column="other_field"),
        }),
        // @Cases for other ContentProviderBean subclasses
})
ArrayList<? extends ContentProviderBean> getFeed(@Param("type") String type,
       @Param("start") int start, @Param("end") int end);

请注意,Case中的value属性应与getFeed的类型参数匹配。

您可能会遇到几个陷阱:

  1. 必须复制许多类型的结果字段映射
  2. 使用mybatis annotations时无法使用自动列映射
  3. 您可以尝试使用xml映射配置来克服这些问题。它可能看起来像:

    <resultMap id="resultContentProviderBean"
               type="ContentProviderBean"
               autoMapping="true">
        <id property="id" column="id"/>
        <discriminator javaType="string" column="employee_type">
            <case value="SomeContentProviderBeanSubclass"
                  resultType="SomeContentProviderBeanSubclass"
                  autoMapping="true"/>
            <case value="OtherContentProviderBeanSubclass" 
                  resultType="OtherContentProviderBeanSubclass"
                  autoMapping="true"/>
        </discriminator>
    </resultMap> 
    
    <select id="getFeed" resultMap="resultContentProviderBean">
        SELECT t.*, ${type} as type_discriminator
          FROM ${type} as t 
        WHERE objectId >= ${start} AND objectId <= ${end}
    </select>