简体   繁体   English

MyBatis中的XML ResultMap与关联

[英]XML ResultMap in MyBatis with association

I see this issue very strange descibed on google or stack. 我觉得这个问题在google或stack上非常奇怪。 Let me explain. 让我解释。

I have Result Maps in annotations in my interface method. 我的界面方法中的注释中有结果映射。 Only in this particular case I need dynamic query, and that is the reason I decided to write the whole mapper for interface in xml file. 只有在这种特殊情况下我需要动态查询,这就是我决定在xml文件中为接口编写整个映射器的原因。 Below I paste the whole file. 下面我粘贴整个文件。 The select query should be ok, but I am occuring some difficulties with <resultMap> . 选择查询应该没问题,但我在<resultMap>遇到了一些困难。

On the different websides I was searching for a good explanation of one to one, one to many, many to one association and construct of this result map in general. 在不同的网站上,我一直在寻找一对一,一对多,多对一的关联和构造这个结果图的良好解释。

I saw there is some kind of possibility to part it into subqueries, subresultmaps. 我看到有一种可能性将它分成子查询,subresultmaps。 But I have that already done with myBatis annotations, and I want to use it. 但我已经完成了myBatis注释,我想使用它。 Could you direct me, how should the resultMap be constructed? 你能指点我,应该如何构造resultMap? I dont see need for constructor, discriminator, but it is still shouting... (that is why I added <collection> mark) - IntelliJ is underscoring the whole <resultMap> saying: "The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collection*,discriminator?)" 我不认为需要构造函数,鉴别器,但它仍然在喊......(这就是我添加<collection> mark的原因) - IntelliJ强调整个<resultMap>说: "The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collection*,discriminator?)"

I know it seems obvious, but I have completly no idea how to do it correctly. 我知道这似乎很明显,但我完全不知道如何正确地做到这一点。 Please help me. 请帮我。

xml mapper file: xml映射文件:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="pl.net.manager.dao.UsageCounterDAO">
    <select id="getUsageCounterList" resultType="pl.net.manager.domain.UsageCounter"
            resultMap="getUsageCounterListMap">
        SELECT * FROM usage_counter WHERE
        <if test="apiConsumerIdsList != null">
            api_consumer IN
            <foreach item="item" index="index" collection="apiConsumerIdsList"
                     open="(" separator="," close=")">
                #{item}
            </foreach>
            AND
        </if>
        <if test="serviceConsumerIdsList != null">
            service IN
            <foreach item="item" index="index" collection="serviceConsumerIdsList"
                     open="(" separator="," close=")">
                #{item}
            </foreach>
            AND
        </if>
        <if test="dateFrom != null">
            date &gt;= #{dateFrom} AND
        </if>
        <if test="dateTo != null">
            date &lt;= #{dateTo} AND
        </if>
        <if test="status != null">
            status = #{status}
        </if>
    </select>
    <resultMap id="getUsageCounterListMap" type="">

                    ofType="pl.net.manager.domain.UsageCounter">
            <id property="id" column="id"/>
            <result property="date" column="date"/>
            <result property="apiConsumer" column="api_consumer"
                    javaType="pl.net.manager.domain.ApiConsumer"/>
            <association property="apiConsumer" column="api_consumer"
                         resultMap="pl.net.manager.dao.ApiConsumerDAO.getApiConsumer"/>
            <result property="service" column="service" javaType="pl.net.manager.domain.Service"/>
        <association property="service" column="service"
                     resultMap="pl.net.manager.dao.ServiceDAO.getService"/>

            <result property="counterStatus" column="counter_status"/>
            <result property="ratingProcessId" column="rating_process_id"/>
            <result property="value" column="value"/>
            <result property="createdDate" column="created_date"/>
            <result property="modifiedDate" column="modified_date"/>

    </resultMap>
</mapper>

The XSD for the Mapper XML expects that in a <resultMap> : Mapper XML的XSD需要在<resultMap>

the <association> must come after all the <result> tags, which means you need to group <result> tags and then add <association> tags after that. <association>必须在所有<result>标记之后,这意味着您需要对<result>标记进行分组,然后在此之后添加<association>标记。

Secondly, You dont need both resultType and resultMap in the getUsageCounterList . 其次,你不需要getUsageCounterList中的resultTyperesultMap Use any one which in your case is resultMap 使用在您的情况下是resultMap任何一个

Third, Your WHERE clause in getUsageCounterList is broken. 第三, getUsageCounterList WHERE子句被破坏。 What if ONLY first condition is met, then in that case your SELECT will be something like: 如果只满足第一个条件,那么在这种情况下你的SELECT将是这样的:

SELECT * FROM usage_counter WHERE api_consumer IN (1,2,3) AND 

So as I mentioned in my previous answer to your query you can use <where> tags and follow the syntax mentioned in that answer. 正如我在上一个对您的查询的回答中提到的,您可以使用<where>标记并按照该答案中提到的语法进行操作。

Fourth, In the resultMap getUsageCounterListMap you just need type which will be your Java class you are trying to populate, so you can move the ofType to type . 第四,在resultMap getUsageCounterListMap您只需要type ,它将是您尝试填充的Java类,因此您可以将ofType移动到type

For One-One mapping , you can just use a <association> tag, or there's another approach, suppose you have a Java POJOs as given below: 对于One-One映射 ,您可以使用<association>标记,或者有另一种方法,假设您有一个Java POJO,如下所示:

public class Country{
    private String name;
    private City capital;
    //getters and setters
}
public class City{
    private String name;
    //getters and setters
}

You can write a Mapping in XML as shown below: 您可以使用XML编写映射,如下所示:

<select id="getCountries" resultType="Country">
    SELECT c.name, cy.name "capital.name" 
    FROM country c 
    JOIN city cy ON cy.name = c.capital
</select>

So Mybatis will make sure to create an instance of City and assign the value in capital.name to that instance's name property. 所以,MyBatis会确保创建的实例City和值分配capital.name到该实例的name属性。

For One to Many OR Many to Many Mapping you can explore the <collection> tag of the MyBatis result map. 对于一对多或多对多映射,您可以浏览MyBatis结果映射的<collection>标记。 For more information check Advacned Result Maps section in the link provided. 有关更多信息,请查看提供的链接中的Advacned Result Maps部分。

This happens with me - 这发生在我身上 -

The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collection*,discriminator?)". 元素类型“resultMap”的内容必须匹配“(构造函数?,id *,结果*,关联*,集合*,鉴别器?)”。

  1. When there is one or more typos 当有一个或多个拼写错误

  2. When there is unclosed head tag or unmatched closing tag exists 当存在未封闭的头标记或不匹配的结束标记时

  3. When you wrote <if></if> <case><case> type of tags inside <resultMap> tag at the time mapping for collection or association collectionassociation的时间映射中在<resultMap>标记内写入<if></if> <case><case>类型的标记时

  4. When you wrote some tags which are not mean to exists there in some other tags 当你在其他一些标签中写下一些并不存在的标签时

Hope these hints may help someone. 希望这些提示可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM