MyBatis:动态sql

动态SQL

在sql语句中使用if等流程控制函数时,需要使用OGNL表达式

  • 使用标签完成sql语句拼接时,mybatis会去掉多出来的and或者or

    • 只会去掉第一个多出来的and或者or
    • 使用标签时,将and或者or写在前面
  • 标签

    • prefix:给拼串后的字符串加前缀

    • prefixOverRides:去掉字符串前面多余的部分

    • suffix:给拼串后的字符串加后缀

    • suffixOverRides:去掉字符串后面多余的部分

      <prefix="where" suffixOverrides="and">
      
    • choose

      <where>
           <choose>
               <when test="id!=null">
                   id=#{id}
               </when>
               <when test="lastName!=null">
                   id=#{lastName}
               </when>
           </choose>
      </where>
      
    • set

      UPDATE employees
         <set>
             <if test="lastName!=null">
                 last_name=#{lastName},
             </if>
             <if test="email!=null">
                 last_name=#{lastName},
             </if>
      </set>
      
      • 也可以使用trim使用set
    • foreach

      • collection:遍历什么
      • items:将当前遍历出的元素指定的变量
      <foreach collection="emps" items="emp" >
      	<!--一些表达式-->
      </foreach>
      
    • :可以将OGNL表达式的值绑定到一个变量中

      <!--做模糊查询时,出了使用'%${}%'还可以使用<bind>标签,前者不安全,可能存在注入问题-->
      <!--name是变量名,value是变量的值-->
      <bind name="_lastName" value="'%'+lastName+'%''"></bind>
      
  • 标签:抽取相同可重复使用的sql语句

    <sql id="select">
    	select * from emp
    </sql>
    <!--然后通过include引用添加-->
    <include refid="select"></include>
    
  • MyBatis 两个内置参数

不止是方法传说来的参数可以进行判断,取值。MyBatis默认还有两个内置参数

  • _parameter:代表整个参数
    • 单个参数时,代表该参数
    • 多个参数时,底层会封装成Map,则代表整个Map
  • _databaseId:如果全局配置文件中配置了databaseIdProvider标签,则该属性代表数据库的别名

MyBatis的缓存机制

  • 一级缓存(本地缓存):sqlSession级别的缓存。

    • 与数据库同一次会话查询到的数据会存放在本地中

    • 以后如果需要获取相同的数据,直接从缓存中拿,没必要去数据库

      //拿过相同的两个数据emp1和emp2
      System.out.println(emp1==emp2);
      //打印结果为true。
      
    • 以及缓存失效的情况

      1. sqlsession不同
      2. sqlsession相同,查询条件不同。
      3. sqlsession相同,但是两次查询之间执行了增删改操作(增删改可能会对数据库产生变化)本质原因是每一次增删改操作都会清除缓存flushCashe=true
      4. sqlsession相同,手动清除了一级缓存。openSession.clearCashe()
  • 二级缓存:基于namespace级别的缓存:一个namespace对应一个二级缓存

    • 工作机制
      1. 一个会话查询一条数据,这个数据会被放在当前打的一级缓存中
      2. 如果会话结束,一级缓存中的数据就会被保存到二级缓存中;新的会话查询信息可以参照二级缓存
      3. 不同的namespace查出的数据会放在自己对应的缓存下(map)
    • 使用:
      1. 开启全局二级缓存配置:<setting name="casheEnabled" value="true">
      2. 在mapper.xml中配置使用二级缓存<cashe></cashe>
      3. 由于缓存会采用序列化和反序列化,所以pojo需要实现序列化接口
    • 注意
      1. 查出的数据都会先放在以及缓存中,只有在数据提交或者会话关闭后,才会进入二级缓存
      2. casheEnabled=falseuserCashe=false对一级缓存无效
      3. flushCashe=true会将一级和二级缓存都清除。
      4. openSession.clearCashe()只能清除一级缓存,因为二级缓存是基于namespace进行存储的
      5. 新会话进来,首先在二级缓存中寻找,然后进入一级缓存中,如果缓存中都没有数据,则进入数据库。
posted @ 2022-01-10 22:17  Boerk  阅读(97)  评论(0)    收藏  举报