哪些你不曾留意的mybatis细节?

本文深入探讨MyBatis的高级配置与使用技巧,包括延迟加载、二级缓存、预编译SQL与变量替换的区别,以及如何处理SQL注入风险。同时,解析列名与关键字冲突、列名与bean属性名不匹配等问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis可以说是java 后端最基本掌握得技能,但是当我们平时复制粘贴多了,就会忘记一些细节的处理:
比如为什么要将上这个注解,作用是什么!首先是mybatsi的配置文件

<configuration>
   <!-- 加载属性文件 -->
   <properties resource="jdbc.properties">
       <!--properties中还可以配置一些属性名和属性值  -->
       <!-- <property name="jdbc.driver" value=""/> -->
   </properties>

   <!-- 全局配置参数,需要时再设置 -->
   <settings>
       <!-- 打开延迟加载的开关,默认为false -->
       <setting name="lazyLoadingEnabled" value="true"/>
       <!-- 开启二级缓存,默认为true -->
       <setting name="cacheEnabled" value="true"/>
       <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
       <setting name="useGeneratedKeys" value="true"/>
   </settings>

   <!-- 别名定义 -->
   <typeAliases>
       <!-- 针对单个别名定义
       type:类型的路径,alias:别名。示例:-->
       <typeAlias type="com.czd.mybatis.po.User" alias="user"/>
       <!-- 批量别名定义
       指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)-->
       <package name="com.czd.mybatis.po"/>

   </typeAliases>

   <!-- 和spring整合后 environments配置将废除-->
   <environments default="development">
       <environment id="development">
           <!-- 使用jdbc事务管理,事务控制由mybatis-->
           <transactionManager type="JDBC"/>
           <!-- 数据库连接池,由mybatis管理-->
           <dataSource type="POOLED">
               <property name="driver" value="${jdbc.driver}"/>
               <property name="url" value="${jdbc.url}"/>
               <property name="username" value="${jdbc.username}"/>
               <property name="password" value="${jdbc.password}"/>
           </dataSource>
       </environment>
   </environments>

<!--加载映射文件有 3 种方法,如下所示-->
<mappers> 
<mapper resource="sqlmap/User.xml"/>
       <!--1. 通过 resource 方法一次加载一个映射文件 -->
       <!-- <mapper resource="mapper/UserMapper.xml"/> -->

       <!-- 2. 通过 mapper 接口加载单个映射文件
       遵循一些规范:需要将 mapper 接口类名和 mapper.xml 映射文件名称保持一致,且在一个目录中
        -->
       <!-- <mapper class="com.iot.mybatis.mapper.UserMapper"/> -->

       <!-- 3. 批量加载 mapper
       指定 mapper 接口的包名,mybatis 自动扫描包下边所有 mapper 接口进行加载
       遵循一些规范:需要将 mapper 接口类名和 mapper.xml映射文件名称保持一致,且在一个目录中
        -->
       <package name="com.czd.mybatis.mapper"/>

<mappers/>

2.# 和 $ 的区别
使用#{parameterName} 引用参数时候,mybatsi会吧参数认为是一个字符串,例如下面的参数"corey" 是一个字符串
Select from emp where name = #{employeeName} 则会转意为 Select from emp where name = 'corey'

同理在下面sql传入参数"corey"
Select from emp where name = ${employeeName} 则会装化为 Select from emp where name = corey

所以可以说#{}是经过预编译的 是安全的,而${} 是没有经过预编译的,仅仅是变量的取值,并不是安全的,存在sql
注入的危险,#将传入的数据当成一个字符穿,会对自动传入的数据加上一个引号
而是用${}的情况下, order by , like 语句只能${}了,用#{} 会多一个'' 导致sql语句失效,此外动态拼接sql,
模糊查询也要用${}

例如举个例子: name=徐,那么该sql就是.....like '%徐%'
DELETE FROM stu WHERE `name` LIKE '%${name}%'


所以总结下:
#{}:编译好sql语句再执行
${}:取之后再去编译sql语句


3.sql语句中的列明和关键字冲突怎么办?
例如:name 字段
解决方法:在列明两边加上 ' 即可
DELETE FROM stu WHERE `name` LIKE '%${name}%'


4.列明和bean属性名不一样,导致获取不到数据时怎么办?

因为mybatis 会通过反射得到bean,由于字段名和属性名不一样,导致无法将查询到的
表字段数据set到bean熟悉中


解决办法:
    1.修改表字段或者对应的bean属性名称,使他们同名即可
    2.修改标签中的内容


     <!--当实体属性与表字段名不相同的时候,必须书写一下代码
        当尸体属性与表字段名相同时候,一下代码可选
    -->
    <resultMap id="student" type="arraylist">
        <id property="id" column="student_id"/>
        <result property="name" column="student_name"/>
        <result property="sal" column="student_sal"/>
                <!--bean 属性名字   bean表字段名-->
    </resultMap>


5.@param 参数的作用
作用:相当于给其修饰的参数指定一个别名
若接口只有一个参数,则可以不用指定别名,list参数除外,当有多个参数时候 一定要指定,否则mybatis
映射不到对应的字段

如代码:
List<Book> queryAll(@Param("offset")int offset, @Param("limit")int limit);

该接口方法对应mapper如下:

<select id="queryAll" resultType="Book">
       SELECT
           book_id,
           `name`,
           `number`
       FROM
           book
       ORDER BY
           book_id
       LIMIT #{offset}, #{limit}
</select>

可以看到#{} 里面的值是和@Param("value") 保持一致的,也一定要一直,否则mybatsi会找不到这个值而报错
另外@Param("value") 中的value可以是任意的

    
    
    
    

 


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值