Mybatis使用的常见问题

本文主要探讨了Mybatis在实际使用中遇到的常见问题,包括数据库字段名与实体类属性名不一致的解决方案,参数占位符的优缺点,特殊字符的转义方法,以及如何处理接收多个和单个参数的情况。推荐使用注解和标签来简化字段映射,并建议使用#{ }避免SQL注入问题。

#博学谷IT学习技术支持#


一、数据库字段名和实体类属性名不同

  • 问题: 因为我们习惯设计数据库字段时,使用下划线来进行命名,例如:品牌名称(brand_name)
    但是当我们编写java代码中的实体类时,又习惯使用大驼峰命名,例如:品牌名称(brandName)
    这样的命名不一致就会出现封装遗漏数据的问题。

  • 解决:
    1、 sql语句中字段起别名(不推荐):就是在编写sql语句的时候使用as来起别名

    <select id="selectAll" resultType="brand">
        select id, brand_name as brandName, company_name as companyName from tb_brand;
    </select>
    
    • 不推荐原因: 编写繁琐,万一有很多方法,需要写很多的sql语句,而每一条都需要起别名,这是繁琐而且毫无意义的工作;也显得不够精炼

    2、 sql片段(不推荐):将需要复用的sql片段抽取出来

    <sql id="brand_column">
    	id, brand_name as brandName, company_name as companyName
    </sql>
    
    • 使用:使用 include 标签引用上述的 SQL 片段,而 refid 指定上述 SQL 片段的id值。
    <select id="selectAll" resultType="brand">
        select
        <include refid="brand_column" />
        from tb_brand;
    </select>
    
    • 不推荐原因: 业务需求中如果需要查询多种属性组合的话,就需要编写很多条sql片段,十分繁琐

    3、 使用resultMap标签来解决(推荐):定义 字段 和 属性 的映射关系

    <resultMap id="brandResultMap" type="brand">
        <!--
            id:完成主键字段的映射
                column:表的列名
                property:实体类的属性名
            result:完成一般字段的映射
                column:表的列名
                property:实体类的属性名
            -->
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
    
    • 推荐原因: 只需要一次编写,定义的字段便会进行自动匹配,即使不同的字段很多,也只需要在该标签里编写一次,不会影响sql语句的正常编写;而且只需要编写命名不匹配的即可

二、参数占位符

  • #{ }:在执行sql时,会将 #{} 占位符替换为?,将来自动设置参数值。可以看出使用#{} 底层使用的是 PreparedStatement
  • ${ }:拼接SQL。底层使用的是 Statement,会存在SQL注入问题。

注: 所以推荐使用 #{ } 参数占位符

三、特殊字段的处理

  • 大于 > 或者其他特殊字符

    <select id="selectById" resultMap="brandResultMap">
        select *
        from tb_brand where id > #{id};
    </select>
    

    这样会进行报错,因为这些符号在xml文件中有特殊含义,所以我们要进行转义

    • 使用转义符号:> ----- &lt 每个特殊符号都有自己的转义符号
    • 使用<![CDATA[内容]]>
    <select id="selectById" resultMap="brandResultMap">
        select *
        from tb_brand where id <![CDATA[  >   ]]> #{id};
    </select>
    

四、接收参数(多个)

  • 在进行接口方法定义时,需要使用@Param(“”)注解来给参数起名,如果不进行取名的话,取参数会使代码可读性变差
  • 在底层,mybatis对于参数的存放使用map集合来存放的,值就是参数的值。键的话分两种命名
    • 一种是arg开头,第一个参数便是arg0,第二个是arg1,以此类推。
      所以进行取值时便是 #{arg0} ,让人难以见名知意。
    • 第二种是以param开头,第一个参数是param1,第二个是param2,以此类推。
      所以进行取值时便是 #{param1} 。
  • 而我们使用了@Param进行起名,便可以使用起的名字来替换默认的键,从而进行取值

五、接收参数(单个)

  • POJO 类型
    直接使用。要求 属性名参数占位符名称 一致

  • Map 集合类型
    直接使用。要求 map集合的键名参数占位符名称 一致

  • Collection 集合类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,collection集合);

    map.put(“collection”,collection集合;

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • List 集合类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,list集合);

    map.put(“collection”,list集合);

    map.put(“list”,list集合);

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • Array 类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,数组);

    map.put(“array”,数组);

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • 其他类型

    比如int类型,参数占位符名称 叫什么都可以。尽量做到见名知意

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值