java - 如何在 MyBatis 动态 SQL 的带注释映射器中使用 XML ResultMap?

标签 java mybatis dynamic-sql

我正在尝试为我的应用程序使用 MyBatis 动态 SQL,并且在遵循有关如何将 XML 映射器与带注释的映射器一起使用的指南时遇到了一些问题,如“用于 Join 语句的 XML 映射器”中所述this page

我正在尝试让以下查询工作:

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>

这是带注释的映射器接口(interface)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$3(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$0(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

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

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

最佳答案

感谢评论中的帖子,我了解到我的代码中存在命名空间冲突。为了解决这个问题,我更改了 xml 和带注释的映射器,如下所示:

SessionResultMapper.xml

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

相应地,在 SessionMapper.java 中:

@ResultMap("SessionResultMapper.SimpleResults")

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

关于java - 如何在 MyBatis 动态 SQL 的带注释映射器中使用 XML ResultMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55480826/

相关文章:

java - 在java代码中的myBatis配置中添加xml映射器,路径与接口(interface)不同

java - mybatis:将映射器接口(interface)与 XML 配置一起用于全局参数

sql-server - 在动态 SQL 中将 varchar 转换为日期时间

sql - 动态 SQL "USE [DB]"不起作用

java - 在 Java 中膨胀 GZip 字符串并在 iOS 中再次收缩

java - 如何通过循环迭代来模拟服务方法?

java - MyBatis 映射器直接注入(inject)到服务类中。异常(exception)情况呢?

java - 从给定文本中提取英语动词

java - JUnit 测试——是什么让它比手动测试更有用?

postgresql - plpgsql 函数中 IF EXISTS 内标识符的变量