mybatis嵌套查询中There is no getter for xxx..的相关问题解答

        这里说点题外话,网上找的那些资料真的坑,问题和答案牛头不对马嘴,到处复制粘贴,都没有回答到点子上,气死人了!!!这里我对自己目前所遇到的问题做一个总结

一、为什么会出现上面这种情况?

        其实出现这个情况的原因是因为使用了错误的属性名称,要么是因为你的拼写真的写错了(大写的滑稽),要么就是因为你使用了错误的传参

二、大家在使用嵌套查询,遇到<collection> <association>需要传参的时候,怎么办呢?简单啊,column="colField",然后到子查询去取??什么鬼?怎么运作的?

       在嵌套标签中,column="colField"其实只是面向一个参数的简写,当父查询向子查询只传递一个参数的时候,就可以这么写,就像框架中,接口方法只有一个参数的时候,可以省略掉@Param注解一样。本质上,column="colField"的格式应该是  column="property=colField",property是指你的参数传递到子查询后的参数名称,colField是父查询中映射出来的column的值,也就是<result column="" property="">中的column中查询得到的值。

        那么,如果简写了呢,简写了就没有property了呀?子查询怎么取值呢?如果进行了简写,默认会使用父查询个中的<result column="" property="">中的property进行映射,但是子查询校验中不能使用property != null来校验,具体校验方式看后面,我测出来结果是这样,源码由于时间原因没有去读。

        PS:单个参数的传递方式,可以使用column="colField"或者column="property=colField"进行传值

        我们再来说说多个参数的传值,触类旁通,多个参数的传值可以通过column="co1,co2,co3"或者column="pro1=co1,pro2=co2,pro3=co3"吗?当然是不行的,

        PS:多个参数的传值只能用后者的写法:column="pro1=co1,pro2=co2,pro3=co3",没有道理!!

        说完了传值,我们再来看看取值,这里取值就有意思了,针对<if test="">的校验判断和#{ }

取值其实也是差不多的,我总结了一下取值的方式:

        1.column="xxx"传一个值:使用_paramete、数字0位置索引进行<if>校验,使用_paramete、数字0位置索引和父查询property进行SQL条件拼接

        2.column="xxx,xxx,xxx"传多个值:没成功过!!!!

        3.column="prop=col"传一个值:使用_paramete、数字0位置索引、prop进行<if>校验,使用_paramete、数字0位置索引或prop进行SQL条件拼接

        4.column="pro1=co1,pro2=co2,pro3=co3"传多个值:使用_paramete.get(数字位置索引)、数字位置索引、prop进行<if>校验,使用_paramete.get(数字位置索引)、数字位置索引或prop进行SQL条件拼接

三、下面附上测试用的xml

<select id="findList" resultMap="teacherMap">
    select id,name as myName, update_time as time from tb_teacher
</select>
<select id="findStudent" resultType="com.fengwuJ.entity.Student">
    select * from tb_student
    <where>
        <!--<if test="0 != null">and name = #{name}</if>-->
        <if test="0 != null">and id != #{id}</if>
    </where>
</select>

<!--教师表,一个教师有下有一个学校信息和多个学生-->
<!--column:数据库字段名一般和数据库字段名相同,也可以是select语句中起的别名-->
<!--property:实体的属性名字,通过Map配置进行关系映射-->
<resultMap id="teacherMap" type="com.fengwuJ.entity.Teacher">
    <id column="id" property="id" />
    <result column="myName" property="name" />
    <result column="time" property="updateTime"/>
    <!--<association>一对一实体引用映射标签-->
    <!--javaType:指定该引用的类型,实测可以不指定,mybatis应该可以自动推断-->
    <!--property:指定属性名称-->
    <!--column:嵌套查询传参,传参格式:
        1.参数名称=列名称,参数名称:传到子查询sql的参数名称,子查询中通过#{参数名称}取值,列名称:实际代表父查询中当前行该列的值
        2.直接写列名称(只能用于一个参数),会默认使用父查询的result或id进行property=column构造,通过mybatis内置对象_parameter取参,当只有一个参数时,在<if test="">使用_parameter进行判断,使用#{_parameter}取值
          当有多个参数时,使用_parameter.get(0)进行判断,使用#{_parameter.get(0)}取值,或者使用0,1,2的参数位置判断,使用#{0}取值
        总结:在子查询中使用<if>的,可以通过_parameter(单个参数),_parameter.get(0/1/2....)(多个参数),直接使用位置下标0,1,2,或者使用property名称(自定义的,或者父查询定义的)
              在子查询中使用#{}取值的,可以通过#{_parameter},#{_parameter.get(0/1/2...)},#{0/1/2...},#{property(自定义或默认使用父查询的property)}-->
    <!--<association javaType="com.fengwuJ.entity.Student" property="student" column="myName,id" select="findStudent">
    </association>-->
    <!--<collection> 一对多List<Model>映射标签-->
    <!--ofType:List<Model> 中 Model实体的类型-->
    <!--其余同上,经测,ofType也可以不用写,暂时不明原因-->
    <collection property="students" ofType="com.fengwuJ.entity.Student" column="id=id" select="findStudent"></collection>
</resultMap>

    补充一句:如果是使用select查询,ofType和javaType可以不用配置,如果使用where连表查询,就需要配置这两个东西了,还有就是,一对一关系建议连表,一对多关系建议使用子查询,但需要把子查询的条件筛选想办法转移到主表中,这样可以解决条件分页问题。  

    最后还有一点,是关于mybatis和tk.mapper的。这两个既有关系也没关系。tk.mapper主要用的是单表,一般配合PageHelper进行单表的分页查询,tk.mapper的映射主要是通过Model实体@Column注解映射,不使用注解则会进行自动映射,必须要是数据库的字段才行,因为数据库操作被tkmapper做完了,没办法为字段起别名,PageHelper则是实现了mybatis的拦截器。而mybatis的映射,一是自动映射,而则是使用resultMap映射,resultMap中,<result column="" property="">,在这个标签中,column指的是select查出来的字段名,如果取了别名就使用别名,没取别名就使用数据库的字段名,和@Column注解没有什么关系,property则是只该字段要映射到的实体的属性名字。

    收获还是有的,就是时间花得多,,,我也只是简单的测了下,大家遇到问题了欢迎反馈,一起交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值