zoukankan      html  css  js  c++  java
  • Mybatis常见问题整理(一)

    前言

    记录开发过程中遇到过的问题。

    一、简介

    二、常见问题

    1.1自定义resultMap中id和result区别

    • id和result都是映射单列值到一个属性或字段的简单数据类型。
    • id是作为唯一标识的,当和其他对象实例对比的时候,这个id很有用,尤其是应用到缓存和内嵌的结果映射。

    1.2resultMap和resultType区别

    MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,将数据库中列数据复制到对象的相应属性上,可以用于复制查询,两者不能同时用。
    resultMap:适合使用返回值是自定义实体类的情况
    resultType:适合使用返回值得数据类型是非自定义的,即jdk的提供的类型。

    //resultType:返回单个实例
    <select id="selectUser" parameterType="int" resultType="User">
    select * from user where id = #{id}
    </select>
    //返回List集合
    <select id="selectUserAll" resultType="User" > <!-- resultMap="userMap" -->
    select * from user
    </select>
    
    //resultMap
    //简单查询:
    <resultMap type="User" id="userMap">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    </resultMap>
    //resultMap的唯一标识
    //column: 库表的字段名
    //property: 实体类里的属性名

    1.3mybatis${ } 和 #{ }区别

    好了,真正做开发也差不多一年了。一直都是看别人的博客,自己懒得写,而且也不会写博客,今天就开始慢慢的练习一下写博客吧。前段时间刚好在公司遇到这样的问题。

    1、举例说明

    1 select * from user where name = "dato"; 
    2 
    3 select * from user where name = #{name}; 
    4 
    5 select * from user where name = '${name}'; 

    一般情况下,我们都不会注意到这里面有什么不一样的地方。因为这些sql都可以达到我们的目的,去查询名字叫dato的用户。

    2、区别

    动态 SQL 是 mybatis 的强大特性之一,也是它优于其他 ORM 框架的一个重要原因。mybatis 在对 sql 语句进行预编译之前,会对 sql 进行动态解析,解析为一个 BoundSql 对象,也是在此处对动态 SQL 进行处理的。在动态 SQL 解析阶段, #{ } 和 ${ } 会有不同的表现

    select * from user where name = #{name}; 

    #{} 在动态解析的时候, 会解析成一个参数标记符。就是解析之后的语句是:

    select * from user where name = ?; 

    那么我们使用 ${}的时候

    select * from user where name = '${name}'; 

    ${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中,就会变成下面的语句

    select * from user where name = "dato"; 

    预编译之前的 SQL 语句已经不包含变量了,完全已经是常量数据了。相当于我们普通没有变量的sql了。

    综上所得, ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。

    这是 #{} 和 ${} 我们能看到的主要的区别,除此之外,还有以下区别:

    • #方式能够很大程度防止sql注入。
    • $方式无法防止Sql注入。
    • $方式一般用于传入数据库对象,例如传入表名.
    • 一般能用#的就别用$.

    所以我们在使用mybatis的时候,尽量的使用#方式!!!这是大家要注意的地方。

    参看链接:https://www.cnblogs.com/dato/p/7027949.html

    1.4Mybatis用Map类型传入多参数

    1、Mybatis传入多参数查询ParameterType=Map问题
    //想用ParameterType=Map传入多个参数构造SQL进行查询
    <select id="getList" resultMap="ListMap" parameterType="java.util.Map">  
            select *
            from t_assess_treaty 
            where 1=1 
            and treatyid = #{treatyid}  
            and assessdate = #{assessdate,jdbcType=DATE} 
            order by treatyid 
        </select>  
    2、调试时报 Parameter not found异常
    //解决方法,使用此方式传参,必须在对应的接口方法用@Param标签定义参数value才行
    public List<Assess> getList(
                @Param(value = "treatyid") String treatyid,   
                @Param(value = "assessdate") Date ssessdate  
                ) ; 

    1.5mybatis查询与插入字段可变

    insert into t_relatedtransactions 
        (relatedPartyCode, relatedPartyName, businesscode,businesstypecode,
        relevancetype,businesstype,transactionsum,transactiondate,transactionyear,
        transactionname,status,remarks,amountscale,transactionstratdate,transactionenddate
        <if test="boardcheckdate != null and boardcheckdate !=''">
          ,boardcheckdate
        </if>
        <if test="reportdate != null and reportdate !=''">
          ,reportdate
        </if>
        <if test="messagepublishdate != null and messagepublishdate !=''">
          ,messagepublishdate
        </if>
        <if test="boardname != null and boardname !=''">
          ,boardname
        </if>
        <if test="reportcode != null and reportcode !=''">
          ,reportcode
        </if>
        <if test="messagepublishcode != null and messagepublishcode !=''">
          ,messagepublishcode
        </if>
        )
    values
        (#{relatedPartyCode,jdbcType=VARCHAR}, #{relatedPartyName,jdbcType=VARCHAR},
        #{businessCode,jdbcType=VARCHAR},#{businessTypeCode,jdbcType=VARCHAR},
        #{relevanceType,jdbcType=VARCHAR},#{businessType,jdbcType=VARCHAR},
        #{transactionSum,jdbcType=DECIMAL},DATE_FORMAT(#{transactionDate,jdbcType=VARCHAR},'%Y-%m-%d'),
        #{transactionYear,jdbcType=VARCHAR},#{transactionName,jdbcType=VARCHAR},
        '0', #{remarks,jdbcType=VARCHAR}
        ,1,DATE_FORMAT(#{transactionstratdate,jdbcType=VARCHAR},'%Y-%m-%d'),
        DATE_FORMAT(#{transactionenddate,jdbcType=VARCHAR},'%Y-%m-%d')
        <if test="boardcheckdate != null and boardcheckdate!=''">
          ,DATE_FORMAT(#{boardcheckdate,jdbcType=VARCHAR},'%Y-%m-%d')
        </if>
        <if test="reportdate != null  and  reportdate!=''">
          ,DATE_FORMAT(#{reportdate,jdbcType=VARCHAR},'%Y-%m-%d')
        </if>
        <if test="messagepublishdate != null  and messagepublishdate!=''">
          ,DATE_FORMAT(#{messagepublishdate,jdbcType=VARCHAR},'%Y-%m-%d')
        </if>
        <if test="boardname != null  and boardname!=''">
          ,#{boardname,jdbcType=VARCHAR}
        </if>
        <if test="reportcode != null  and reportcode!=''">
          ,#{reportcode,jdbcType=VARCHAR}
        </if>
        <if test="messagepublishcode != null and messagepublishcode!=''">
          ,#{messagepublishcode,jdbcType=VARCHAR}
        </if>
        )
    View Code

    三、拓展

    如果错过太阳时你流了泪,那你也要错过群星了。
    在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
    不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。
  • 相关阅读:
    ScrollView嵌套EditText联带滑动的解决的方法
    POJ 2003 Hire and Fire (多重链表 树结构 好题)
    leetcode笔记:Bulls and Cows
    PHP中使用ActiveMQ实现消息队列
    WPF模拟键盘输入和删除
    DLLImport的用法C#
    Net Core 的配置模式以及热重载配置
    简体与繁体转换
    Webdings字体、Wingdings字体对照表、用CSS3绘制的各种小图标
    查询大于2分钟的数据
  • 原文地址:https://www.cnblogs.com/szrs/p/15257881.html
Copyright © 2011-2022 走看看