• 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

    三、拓展

    如果错过太阳时你流了泪,那你也要错过群星了。
    在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
    不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。
  • 相关阅读:
    What is the difference between Serialization and Marshaling?
    IEEE Standard 754 for Binary Floating-Point Arithmetic
    没有单元测试,就很难有真正的积累。
    一般只用 20% 的代码就可以解决 80% 的问题。但要想解决剩下 20% 的问题的话,则需要额外 80% 的代码。
    为失败设计,大量引入对SRE的理解,鲁棒性高
    用git合并分支时,如何保持某些文件不被合并
    git 分支合并时如何忽略某个文件
    Golang拼接字符串的5种方法及其效率_Chrispink-CSDN博客_golang 字符串拼接效率 https://blog.csdn.net/m0_37422289/article/details/103362740
    Lua大量字符串拼接方式效率对比及原因分析
    干货 | 携程多语言平台-Shark系统的高可用演进之路
  • 原文地址:https://www.cnblogs.com/szrs/p/15257881.html
Copyright © 2020-2023  润新知