我如何在 MyBatis Dynamic SQL 的注释映射器中使用 XML ResultMap?

How do I use an XML ResultMap in an annotated mapper for MyBatis Dynamic SQL?

我正在尝试将 MyBatis Dynamic SQL 用于我的应用程序,并且在遵循有关如何将 XML 映射器与带注释的映射器一起使用的指南时 运行 遇到了一些问题映射器,如 this page 上的 "XML Mapper for Join Statements" 中所述。

我正在尝试使以下查询起作用:

SessionMapper mapper = sqlSession.getMapper(SessionMapper.class);
SessionTableSupport sessionMaster = new SessionTableSupport();

SelectStatementProvider stmt = select(
        sessionMaster.sessionId,
        sessionMaster.module,
        sessionMaster.startTime,
        sessionMaster.endTime,
        sessionMaster.eventId,
        sessionMaster.userId)
        .from(sessionMaster.sessionTable)
        .where(sessionMaster.module, isEqualTo("sample_module"))
        .build()
        .render(RenderingStrategy.MYBATIS3);

List<SessionResult> sampleSessions = mapper.selectMany(stmt);

供您参考,配置文件如下所示:

<configuration>
    <settings> ... </settings>
    <environments> ... </environments>
    <mappers>
        <mapper resource="./mappers/SessionResultMapper.xml"/>
        <package name="mappers"/>
    </mappers>
</configuration>

然后,这是我的 xml 映射器 SessionResultMapper.xml:

<mapper namespace="SessionResultMapper">
    <resultMap id="SimpleResults" type="results.SessionResult">
        <id column="session_id" jdbcType="VARCHAR" property="sessionId" />
        <result column="module" jdbcType="VARCHAR" property="module" />
        <result column="start_time" jdbcType="BIGINT" property="startTime" />
        <result column="end_time" jdbcType="BIGINT" property="endTime" />
        <result column="event_id" jdbcType="INTEGER" property="eventId" />
        <result column="user_id" jdbcType="VARCHAR" property="userId" />
        <result column="institute" jdbcType="VARCHAR" property="institute" />
    </resultMap>
</mapper>

这是带注释的映射器界面SessionMapper.java:

@Mapper
public interface SessionMapper {
    @SelectProvider(type=SqlProviderAdapter.class, method="select")
    @ResultMap("SimpleResults")
    List<SessionResult> selectMany(SelectStatementProvider selectStatement);
}

最后,SessionResult.java

public class SessionResult {

    private String sessionId;
    private String module;
    private long startTime;
    private long endTime;
    private int eventId;
    private String userId;
    private String institute;

    public SessionResult(
            String sessionId,
            String module,
            long startTime, 
            long endTime,
            int eventId, 
            String userId, 
            String institute) {

        super();
        this.sessionId = sessionId;
        this.module = module;
        this.startTime = startTime;
        this.endTime = endTime;
        this.eventId = eventId;
        this.userId = userId;
        this.institute = institute;
    }

    public SessionResult() {}

    // Getters and Setters
    ...
}

当运行上面同时使用xml和注解时,抛出如下异常:

Exception in thread "main" org.apache.ibatis.builder.IncompleteElementException: Could not find result map mappers.SessionMapper.SimpleResults
    at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346)
    at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290)
    at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(MapperAnnotationBuilder.java:364)
    at org.apache.ibatis.builder.annotation.MethodResolver.resolve(MethodResolver.java:33)
    at org.apache.ibatis.session.Configuration.lambda$buildAllStatements(Configuration.java:795)
    at java.util.Collection.removeIf(Collection.java:414)
    at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:794)
    at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:763)
    at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:758)
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.resolveMappedStatement(MapperMethod.java:254)
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:224)
    at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:50)
    at org.apache.ibatis.binding.MapperProxy.lambda$cachedMapperMethod[=17=](MapperProxy.java:62)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:62)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:57)
    at com.sun.proxy.$Proxy5.selectMany(Unknown Source)
    at test.TestMyBatisDynamic.main(TestMyBatisDynamic.java:70)
Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for mappers.SessionMapper.SimpleResults
    at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:933)
    at org.apache.ibatis.session.Configuration.getResultMap(Configuration.java:645)
    at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:344)
    ... 17 more

但是当我使用纯注释结果图时,一切正常。不幸的是,我正在尝试使用集合和关联构建更复杂的结果映射,因此使用纯注释似乎不是一个选项。

我已尽力尽可能地遵循文档中的示例。我在这里完全不知所措......有谁知道如何解决这个问题?任何帮助或提示将不胜感激!感谢您提前抽出时间!

感谢评论中的 post,我了解到我的代码中存在命名空间冲突。为了修复它,我更改了 xml 和注释映射器,如下所示:

SessionResultMapper.xml

<mapper namespace="SessionResultMapper">
    <resultMap id="SimpleResults" type="results.SessionResult">
        ...
    </resultMap>
</mapper>

因此,在 SessionMapper.java:

@ResultMap("SessionResultMapper.SimpleResults")

基本上,确保 [namespace].[resultMap id] 路径在 xml 和带注释的映射器之间是一致的。