简体   繁体   English

MyBatis:布尔参数:MyBatis使用的是Getter

[英]MyBatis: Boolean Parameter: MyBatis is using Getter

Subject: MyBatis: Boolean Paraeter: MyBatis is using Getter 主题:MyBatis:布尔参数:MyBatis使用的是Getter

Content: 内容:

Hello everyone, 大家好,

I have been searching for a while for a solution to my nearly-simple MyBatis problem: 我一直在寻找解决我近乎简单的MyBatis问题的方法:


Given code (only the necessary parts): 给定代码(仅必要部分):

mybatis-config.xml: mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <!-- Model types. -->
        <typeAlias type="com.blockhaus2000.bh2k.portal.data.model.Navigation" alias="Navigation" />
        <!-- ... more types ... --->
    </typeAliases>
    <mappers>
        <mapper resource="mapper/NavigationDAO.xml" />
        <!-- ... more mappers ... -->
    </mappers>
</configuration>

NavigationDAO.xml: NavigationDAO.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="com.blockhaus2000.bh2k.portal.data.dao.NavigationDAO">
    <resultMap type="Navigation" id="navigationResultMap">
        <id property="id" column="navigationId" />
        <result property="title" column="navigationTitle" />
        <result property="order" column="navigationOrder" />
        <result property="visible" column="navigationVisible" />
        <discriminator javaType="String" column="resolve">
            <case value="yes" resultMap="enhancedNavigationResultMap" />
        </discriminator>
    </resultMap>
    <resultMap type="Navigation" id="enhancedNavigationResultMap" extends="navigationResultMap">
        <collection property="navigationEntries" ofType="NavigationEntry">
            <id property="navigationId" column="navigationId" />
            <id property="pageId" column="pageId" />
            <result property="title" column="navigationEntryTitle" />
            <result property="order" column="navigationEntryOrder" />
            <result property="visible" column="navigationEntryVisible" />
        </collection>
    </resultMap>

    <!-- Methods from BaseDAO. -->
    <insert id="insert" parameterType="Navigation" useGeneratedKeys="true" keyProperty="id" keyColumn="navigationId">
        <!-- SQL -->
    </insert>
    <insert id="save" parameterType="Navigation">
        <!-- SQL -->
    </insert>
    <delete id="delete" parameterType="Navigation">
        <!-- SQL -->
    </delete>
    <select id="exists" parameterType="Navigation" resultType="boolean">
        <!-- SQL -->
    </select>

    <!-- Methods from UpdateableDAO. -->
    <update id="update" parameterType="Navigation">
        <!-- SQL -->
    </update>

    <!-- Methods from NavigationDAO. -->
    <select id="findVisibleNavigations" parameterType="boolean" resultMap="navigationResultMap">
        SELECT
            N.navigationId,
            N.navigationTitle,
            N.navigationOrder,
            N.navigationVisible,
        <if test="resolve">
            NE.pageId,
            NE.navigationEntryTitle,
            NE.NavigationEntryOrder,
            NE.navigationEntryVisible,
        </if>
            IF (
                #{resolve} = 'true',
                'yes',
                'no'
            ) AS resolve
        FROM
            Navigation AS N
        <if test="resolve">
        INNER JOIN NavigationEntry AS NE ON N.navigationId = NE.navigationId
        </if>
        WHERE
            N.navigationVisible = TRUE
        <if test="resolve">
            AND
            NE.navigationEntryVisible = TRUE
            AND
            NE.navigationEntryTitle IS NOT NULL
        </if>
    </select>
    <select id="findHiddenNavigations" parameterType="boolean" resultMap="navigationResultMap">
        <!-- SQL -->
    </select>
    <select id="findNavigation" parameterType="Map" resultMap="navigationResultMap">
        <!-- SQL -->
    </select>
</mapper>

NavigationDAO.java: NavigationDAO.java:

package com.blockhaus2000.bh2k.portal.data.dao;

import java.util.SortedSet;

import com.blockhaus2000.bh2k.portal.data.model.Navigation;

public interface NavigationDAO extends BaseDAO<Navigation>, UpdateableDAO<Navigation> {
    SortedSet<Navigation> findVisibleNavigations(final boolean resolve);

    SortedSet<Navigation> findHiddenNavigations(final boolean resolve);

    Navigation findNavigation(final int id, final boolean resolve);
}

BaseDAO.java: BaseDAO.java:

package com.blockhaus2000.bh2k.portal.data.dao;

import com.blockhaus2000.bh2k.portal.data.model.BaseModel;

public interface BaseDAO<T extends BaseModel<T>> {
    int insert(final T obj);

    int save(final T obj);

    int delete(final T obj);

    boolean exists(final T obj);
}

UpdateableDAO.java: UpdateableDAO.java:

package com.blockhaus2000.bh2k.portal.data.dao;

import com.blockhaus2000.bh2k.portal.data.model.BaseModel;

public interface UpdateableDAO<T extends BaseModel<T>> extends BaseDAO<T> {
    int update(final T obj);
}

Everything is starting correctly, but on an invocation of 一切都正常启动,但是在调用

NavigationDAO.findVisibleNavigations(true) // Or false.

the following Exception is thrown: 抛出以下异常:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'resolve' in 'class java.lang.Boolean'
    at org.mybatis.(...)
    at org.apache.ibatis.(...)
    at com.blockhaus2000.bh2k.portal.data.test.NavigationDAOSpec.test findVisibleNavigations(NavigationDAOSpec.groovy:224)
Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'resolve' in 'class java.lang.Boolean'
    at org.apache.ibatis.(...)
    at org.mybatis.(...)
    ... 5 more

That said, the solution may be to change the "parameterType" to "Map" and replacing "resolve" with "param1". 也就是说,解决方案可能是将“ parameterType”更改为“ Map”,并用“ param1”替换“ resolve”。 But that does not work either. 但这也不起作用。 Also, if I remove the 另外,如果我删除了

<if test="..."> ... </if>

it does execute correctly (except for the functionaility, of course). 它确实可以正确执行(当然,除了功能以外)。


I am happy about every single answer. 我对每个答案都很满意。

Thanks for your help Fabian 感谢您的帮助Fabian


Edit 1 : 编辑1

Here is my data model for "Navigation": 这是我的“导航”数据模型:

package com.blockhaus2000.bh2k.portal.data.model;

import java.util.SortedSet;

public class Navigation implements BaseModel<Navigation>, Comparable<Navigation> {
    private static final long serialVersionUID = 4019792023891297733L;

    /**
     * <p>
     * <b> PRIMARY KEY </b>
     * <br>
     * <b> AUTO_INCREMENT </b>
     * </p>
     */
    private int id = -1;
    private String title;
    private int order;
    private boolean visible;

    // ~ non-persistent fields ~

    private transient SortedSet<NavigationEntry> navigationEntries;

    // compateTo()
    // toString()
    // hashCode()
    // equals(Object)

    public int getId() {
        return this.id;
    }

    public String getTitle() {
        return this.title;
    }

    public int getOrder() {
        return this.order;
    }

    public boolean isVisible() {
        return this.visible;
    }

    public SortedSet<NavigationEntry> getNavigationEntries() {
        return this.navigationEntries;
    }

    public Navigation setId(final int id) {
        this.id = id;

        return this;
    }

    public Navigation setTitle(final String title) {
        this.title = title;

        return this;
    }

    public Navigation setOrder(final int order) {
        this.order = order;

        return this;
    }

    public Navigation setVisible(final boolean visible) {
        this.visible = visible;

        return this;
    }

    public Navigation setNavigationEntries(final SortedSet<NavigationEntry> navigationEntries) {
        this.navigationEntries = navigationEntries;

        return this;
    }
}

I forgot to explain what "resolve" does: It is a simple boolean identifying whether to load the transient properties or not. 我忘了解释“解析”的作用:它是一个简单的布尔值,用于标识是否加载瞬态属性。

In your sample MyBatis tries to call getResolve() on the boolean parameter (which obviously cannot work) because the name of the formal parameter in your Java method declaration is not used all, so your "resolve" in xml does not match the parameter name "resolve". 在您的示例MyBatis中,尝试对boolean参数(显然不起作用)调用getResolve() ,因为您的Java方法声明中的形式参数名称并未全部使用,因此xml中的“ resolve”与参数名称不匹配“解决”。

To give your parameter the MyBatis name resolve choose parameterType="map" in your NavigationDAO.xml: 为了让您的参数MyBatis的名称resolve选择parameterType="map"在你的NavigationDAO.xml:

...
<select id="findVisibleNavigations" parameterType="map" resultMap="navigationResultMap">
...
<select id="findHiddenNavigations" parameterType="map" resultMap="navigationResultMap">

And annotate your parameter in NavigationDAO.java with @Param("resolve") , maybe you have to remove final, but I don't know that for sure: 并使用@Param("resolve")在NavigationDAO.java中注释您的参数,也许您必须删除final,但是我不确定:

....
SortedSet<Navigation> findVisibleNavigations(@Param("resolve") final boolean resolve);
SortedSet<Navigation> findHiddenNavigations(@Param("resolve") final boolean resolve);
...

Update 1: 更新1:

According to this description you might leave parameterType at all but I have never used that. 根据此描述,您可能会保留parameterType,但我从未使用过。

You should merely remove the parameterType="boolean" from the select statement. 您应该只从select语句中删除parameterType="boolean" Then Mybatis will use actual boolean value for parameter #{resolve} (or what ever the name). 然后Mybatis将使用实际的布尔值作为参数#{resolve} (或名称)。 Specifying parameterType forces Mybatis to look up a resolve property into parameter. 指定parameterType会强制Mybatis在参数中查找resolve属性。 It is actually only required for complex types. 实际上,只有复杂类型才需要它。

Alternatively naming parameter by using annotation @Param("resolve") in mapper interface will also do the work. 另外,通过在mapper界面中使用注解@Param("resolve")来命名参数也可以完成此工作。

您可以将#{resolve}补充为#{1},或使用注释@Param(“ resolve”)

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

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