动态SQL

     动态SQL:根据查询条件,动态生成SQL

     动态标签: if, choose ,trim, foreach

     <if test="OGNL"/> test判断表达式, 从参数中取值进行判断,遇到特殊字符,使用转义字符,

<select id="getEmployee"  resultType="com.dong.service.employee" databaseId="mysql" >  
    select * from Blog where   
    <if test="id != null">  
        id = #{id}  
    </if>  
    <if test="last_name != null">  
        and lastname = #{lastName}  
    </if>  
 </select>  

     当拼装SQL查询条件时,如果某些情况出错,eg:直接where 后结and,(上面的例子中的id条件不成立) 这种情况下,则需要处理:

            1,在SQL前加一个真值  判断条件 : 1 = 1 ,

            2.Mybatis 可使用<where> 标签,将所有的查询条件包含在内即可,Mybatis会将SQL中多出来的and ,or 去掉 , where 只会去掉第一个多出来的and 或者or,

<select id="getEmployee"  resultType="com.dong.service.employee" databaseId="mysql" >  
        select * from Blog    
        <where>  
            <if test="id != null">  
                id = #{id}  
            </if>  
            <if test="last_name != null">  
                and lastname = #{lastName}  
            </if>  
        </where>  
     </select>  

 3.trim 标签,当SQL语句后面多出一个or ,and ,则可以使用trim 标签:

prefix: 前缀, trim标签体中是整个字符串拼接后的结果, prexfix 给拼接后的整个字符串一个前缀,

prefixOverrides: 前缀覆盖,去掉整个字符串前面多余的字符,

suffix: 后缀,给拼接后的字符串加后缀,

suffixOverrides: 后缀覆盖,去掉整个字符串后面多余的字符,

 <select id="getEmployee"  resultType="com.dong.service.employee" databaseId="mysql" >  
        select * from Blog   
        <trim prefix="where" suffixOverrides="and">  
            <if test="id != null">  
                id = #{id} and  
            </if>  
            <if test="last_name != null">  
                lastname = #{lastName} and  
            </if>  
            <if test="first_name != null">  
                first_name = #{firstName}  
            </if>  
        </trim>  
 </select>  

choose: 分支选择,,类似与switch,

  <select id="getEmployees" resultType="com.dong.service.employee">  
    select * from BLog where   
    <choose>  
        <when test="id != null">  
            id = #{id}  
        </when>  
        <when test="last_name != null">  
            last_name= #{lastName}  
        </when>  
        <otherwise>  
            gender = 1  
        </otherwise>  
    </choose>  
</select>  

当有多个分支,则选择第一个,当没有条件满足,则选择otherwise,

trim:where标签 和 set标签

where用来封装查询条件, set 封装修改条件, eg:

      <update id="updateEmployee" parameterType="com.dong.service.employee">  
        update  tbl_employee set  
        <if test="lastname != null">  
            lastname=#{lastName},  
        </if>  
        <if test="email != null">  
            email=#{email}  
        </if>       
     </update>  

当email为空时,执行出错,因为会多出多余的逗号,可使用set标签将其包含,自动去掉逗号,

  <update id="updateEmployee" parameterType="com.dong.service.employee">  
        update  tbl_employee  
        <set>  
            <if test="lastname != null">  
                lastname=#{lastName},  
            </if>  
            <if test="email != null">  
                email=#{email}  
            </if>   
        </set>      
     </update>  

注意:也可使用trim标签,时候后缀参数,去掉逗号,

foreach:

collection:指定遍历集合,  list类型的参数会特殊封装到Map中,Map的key就叫list,

                    item:将当前遍历的元素赋值给指定的变量,  #{变量名}就可以取出变量的值,

                    separator: 元素的分隔符,

                    open:遍历所有结果,拼接一个开始的字符,

                    close:遍历所有结果,拼接一个结束字符

                    index:索引,遍历list的时候的索引,item就是当前值,

                    遍历Map的时候,则index则表示key, item就是Map的值,

<select id="getEmployee2" resultType="com.dong.service.employee">  
    select * from BLog where id in  
    <foreach collection="ids" item="vids" separator="," open="(" close=")">  
        #{vids}  
    </foreach>  
 </select>  

批量插入

      1.利用foreach循环插入的值

 <insert id="addEmployee" parameterType="com.dong.service.employee" useGeneratedKeys="true" keyProperty="id">  
    insert into tbl_employee(last_name,email,gendar) values  
    <foreach collection="emps" item="emp" separator=",">  
        (#{emp.id},#{emp.firstname},#{emp.lastname})  
    </foreach>  
 </insert>  

      2.利用foreach循环执行语句

<delete id="deleteEmployee" >  
    <foreach collection="emps" item="emp" separator=",">  
        delete from tbl_employee where id = #{emp.id}         
    </foreach>  
</delete>  

在这里使用删除语句,如果是想插入语句,需设置mySQL属性, allowMultiQueries = true; 可以用于其他的批量操作,批量删除,批量修改,

Oracle数据库批量操作:(同Mysql一个实现原理,之不过需要修改SQL语句)

Oracle不支持values(),(),(),..

1.Oracle支持的批量方式:  1.多个insert放到begin - end 之间,2.利用中间表,实现方式,

<insert id = "addemp" databaseId= "oracle">  
   <foreach collection ="emps"  item ="emp"  open = "begin" close= " end;" >       insert into table_name (last_name,email,gender,d_id) values  
       ( employee_seq.nextval,#{emp.lastname},#{emp.email},#{emp.gender},#{emp.d_id})  
   </foreach>  
</insert> 

内置参数

Mybatis:默认两个参数:

_parameter:代表整个参数, 单个参数, _parameter 就是这个参数,如果多个,则被封装为Map,

_databaseId:如果配置了databaseIdProvider标签, , _databaseId就代表当前数据库的别名,

 

注意:

bind标签

value:为绑定的值, name:名,value中可以写OGNL表达式.

       <bind  name = "_lastname"  value = "'%'+lastName+'%'"/>

     在sql语句中使用%#{}%是不可以实现拼接,使用%$%可以.

sql标签

抽取重用的SQL片段,方便后面使用

<sql id="insertCloumn" >(id,name,gender)</sql>  

       再select,insert,update等语句中可引用,通过<include ></include>引入即可. 

<insert id="addEmployee" parameterType="com.dong.service.employee" useGeneratedKeys="true" keyProperty="id">  
    insert into tbl_employee  
    <include refid="insertCloumn"></include>  
    values  
    <foreach collection="emps" item="emp" separator=",">  
        (#{emp.id},#{emp.firstname},#{emp.lastname})  
    </foreach>  
 </insert> 

       include还可以自定义一些propery, <sql>标签内部就可使用自定义的属性,注意:include 使用${prop}取值, ,#{不可用},

       注意,bind标签内部也可以进行判断.

Mybatis缓存机制

默认两级缓存

一级缓存:本地缓存, 一级缓存默认是一直开的,与数据库同一次会话期间查询的数据会被放入到本地缓存中,以后如果想要获取相同的数据,直接从缓存中拿,没必要在去数据库查.

      一级缓存失效:

1.SQLSession不同,因为一级缓存是session级别,只在同一个会话中有效,

      2.如果session相同,查询条件不同,则当然不会相同,因为当前session没有,所以自然会在重新查询

    3.SQLSession相同,两次查询之间进行了增删改,(这次增删改有可能改变查询数据)

      4.SQLSession相同,但是手动清除一级缓存,

二级缓存(全局缓存): 基于namespace的级别的缓存,一个namespace对应一个二级缓存,

      工作机制:

1.一个会话,查询一条数据,数据被放到一级缓存

      2.如果会话关闭,一级缓存中的数据会被保存到二级缓存,新的会话,参考二级缓存,不同namespace查询的数据会放到自己对应的缓存中.

             ......       

 

 

如有异议,敬请指出,谢谢观看,与君共勉.(观看https://www.bilibili.com/video/av45816095?t=113&p=36)