ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MyBatis常见问题汇总

2021-10-04 18:29:56  阅读:107  来源: 互联网

标签:语句 常见问题 映射 汇总 接口 缓存 sql MyBatis


文章目录

JDBC的不足之处 & MyBatis的解决方案

  • 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能。
    • 解决方案:在mybatis-config.xml中配置数据连接池,使用连接池管理数据库连接。
  • Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
    • 解决方案:将Sql语句配置在XXXXmapper.xml文件中与java代码分离开。
  • 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
    • 解决方案:Mybatis自动将java对象映射至sql语句。
  • 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历。
    • 解决方案:Mybatis自动将sql执行结果映射至java对象。

MyBatis中Dao接口和XML文件的SQL如何建立关联

  • MyBatis会把每个SQL标签封装成SqlSource对象,XML文件中的每一个SQL标签就对应一个MappedStatement对象,其中有两个属性非常重要:
    • id:全限定类名+方法名组成的ID。
    • sqlSource:当前SQL标签对应的SqlSource对象。
  • Dao接口的工作原理是JDK动态代理,MyBatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。
    • Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement
举个栗子:
接口方法:com.mybatis3.mappers.StudentDao.findStudentById
就会找到:namespace 为 com.mybatis3.mappers.StudentDao 下面的 id = findStudentById 的 MappedStatement

MyBatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

方式一:使用标签,逐一定义列名和对象属性名之间的映射关系

<resultMap type="com.pojo.User" id="myResult">
    <id property="uid" column="uid"/>
    <result property="uName" column="uName"/>
</resultMap>
<select id="selectUser" resultMap="myResult">
    select * from user
</select>

方式二:使用sql列的别名功能,将列别名书写为对象属性名

<select id="selectUser" resultType="com.pojo.User">
    select uid AS id, uName AS name from user
</select>
  • resultMap是手动提交,resultType是自动提交。
  • MyBatis查询在进行select映射的时候,返回类型可以用resultType,也可以用resultMapresultType直接表示返回类型,而resultMap则是对外部ResultMap的引用,但resultTyperesultMap不能同时存在。

MyBatis的动态sql

MyBatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。

if

<if test="name!=null and name!=''">
    e.emp_name = #{name, jdbcType=VARCHAR}
</if>

where

将sql放入where动态标签内,至少有一个条件符合的时候,就会插入where语句并且会将条件语句前的 and 去掉。

<where>
    <if test="name!=null and name!=''">
        and e.emp_name=#{name,jdbcType=VARCHAR}
    </if>
    <if test="dep!=null">
        and e.emp_dep=#{dep.id,jdbcType=INTEGER}
    </if>
</where>

set

set 可用于动态包含需要更新的列,而舍去其它的。

<update id="updateAuthorIfNecessary">update Author
    <set>
        <if test="username != null">username=#{username},</if>
        <if test="password != null">password=#{password},</if>
    </set>
    where id=#{id}
</update>

foreach

<select id="countByUserList" parameterType="list">
    SELECT COUNT(*) FROM users WHERE user_id IN
    <foreach item="userList" collection="list" separator="," open="(" close=")" index="">
        #{item.userId}
    </foreach>
</select>

MyBatis中一级缓存与二级缓存的区别

一级缓存是SqlSession级别的缓存:MyBatis对缓存提供支持,默认只开启一级缓存。

一级缓存在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中, 不同的sqlSession中的缓存是互相不能读取的。

image-20211004175759233

MyBatis的二级缓存是mapper级别的缓存,它可以提高对数据库查询的效率,提高应用的性能。

多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

image-20211004181047084

二级缓存开启方式:在mybatis.xml配置文件中加入:

<span style="font-size:18px;">
    <settings>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
</span>

MyBatis中的接口绑定方式

  • 通过注解绑定:在接口的方法上加上 @Select@Update等注解里面包含Sql语句来绑定(Sql语句比较简单的时候,推荐注解绑定)
  • 通过xml文件绑定:指定xml映射文件中的namespace为接口的全路径名(SQL语句比较复杂的时候,推荐xml绑定)

MyBatis与Hibernate的区别

  • MyBatis不完全是一个ORM框架,因为MyBatis需要开发者自己编写Sql语句。
  • MyBatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁。但灵活的前提是MyBatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。
  • Hibernate 对象/关系 映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用Hibernate开发可以节省很多代码,提高效率。

标签:语句,常见问题,映射,汇总,接口,缓存,sql,MyBatis
来源: https://blog.csdn.net/Chauncey_Ren/article/details/120606498

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有