四、MyBatis-映射文件

映射文件指导着MyBatis如何进行数据库增删改查,有着非常重要的意义。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">

</mapper>

 

以下是maper可配置的子标签:

  1. cache –命名空间的二级缓存配置
  2. cache-ref – 其他命名空间缓存配置的引用。
  3. resultMap – 自定义结果集映射
  4. parameterMap – 已废弃!老式风格的参数映射
  5. sql –抽取可重用语句块。
  6. insert – 映射插入语句
  7. update – 映射更新语句
  8. delete – 映射删除语句
  9. select – 映射查询语句

 

cache : 配置mybatis的二级缓存 (作用域为当前的命名空间)

前提需要启用二级缓存,开启方式,只需要在全局配置文件的setting中添加cacheEnabled属性为true:

<settings>
    <!--显式的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
    <setting name="cacheEnabled" value="true"/>
</settings>

示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">

    <!-- 
        mybatis内置缓存,默认使用的是org.apache.ibatis.cache.impl.PerpetualCache (相当于一个Map)
        自定义缓存,需要实现org.apache.ibatis.cache.Cache接口,交由第三方处理
    -->
    <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> 
    
    <!--  
    eviction:缓存的回收策略:
        • LRU – 最近最少使用的:移除最长时间不被使用的对象。
        • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
        • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
        • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
        • 默认的是 LRU。
    flushInterval:缓存刷新间隔
        缓存多长时间清空一次,默认不清空,设置一个毫秒值
    readOnly:是否只读:
        true:只读;mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
                 mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
        false:非只读:mybatis觉得获取的数据可能会被修改。
                mybatis会利用序列化&反序列的技术克隆一份新的数据给你。安全,速度慢
    size:缓存存放多少元素;
    type="":指定自定义缓存的全类名;
            实现Cache接口即可;
    -->
    
    <!-- 使用第三方Ehcache缓存, mybatis与Ehcache整合 -->
    <!-- <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache> -->
    
    <!-- 即使开启了全局缓存,也可以通过 flushCache、useCache属性来控制当前SQL的存机制,
        flushCache: true (一级缓存就清空了;二级也会被清除,缓存失效)
        useCache:false (一级缓存任然有用,二级缓存失效)
     -->
     <select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee" 
         flushCache="false"
         useCache="true">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>

 

cache-ref : 其他命名空间缓存配置的引用

<!-- 引用缓存:namespace:指定和哪个名称空间下的缓存一样 -->
<cache-ref namespace="com.atguigu.mybatis.dao.EmployeeMapper"/>

引用其他命名空间的缓存。

 

mybatis 如何引入java调用时传入的参数?

1)当java方法参数没有@Param指定时,可以按照参数的顺序索引和内部名称获取参数值,如:

  • #{0},#{1},#{2}....#{n索引}
  • #{param1},#{param2},#{param3}....#{param(n+1)}

2)当java方法参数有@Param指定时,参数就用@Param中value值进行引用,当然也可以同时使用上面的形式,因为java的方法参数大于1的时候最终会被转化为Map对象的形式交给mybatis。

 

3)单个参数:mybatis不会做特殊处理,#{参数名/任意名}:取出参数值。多个参数:mybatis会做特殊处理。多个参数会被封装成 一个map,key:param1...paramN,或者参数的索引也可以,value:传入的参数值,#{}就是从map中获取指定的key的值;

 

4)案例

public Employee getEmp(@Param("id")Integer id,String lastName);
    取值:id==>#{id/param1/0}   lastName==>#{param2/1}

public Employee getEmp(Integer id,@Param("e")Employee emp);
    取值:id==>#{param1/0}    lastName===>#{param2.lastName/e.lastName/1.lastName}

##特别注意:如果是Collection(List、Set)类型或者是数组,也会特殊处理。也是把传入的list或者数组封装在map中。
            key:Collection(collection),如果是List还可以使用这个key:list,数组用array
public Employee getEmpById(List<Integer> ids);
    取值:取出第一个id的值:   #{list[0]}

 

5)源码分析

 

insert自增主键的配置方式

1) 带自增的数据库如:mysql

<!-- parameterType:参数类型,可以省略, 
获取自增主键的值:
    mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();
    useGeneratedKeys="true";使用自增主键获取主键值策略
    keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性
-->
<insert id="addEmp" parameterType="com.atguigu.mybatis.bean.Employee"
    useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
    insert into tbl_employee(last_name,email,gender) 
    values(#{lastName},#{email},#{gender})
</insert>

 

2)不带自增的数据库如:oracle

<!-- 
获取非自增主键的值:
    Oracle不支持自增;Oracle使用序列来模拟自增;每次插入的数据的主键是从序列中拿到的值;如何获取到这个值;
 -->
<insert id="addEmp" databaseId="oracle">
    <!-- 使用selectKey功能:
    keyProperty:查出的主键值封装给javaBean的哪个属性
    order="BEFORE":当前sql在插入sql之前运行  AFTER:当前sql在插入sql之后运行
    resultType:查出的数据的返回值类型
    
    BEFORE运行顺序:
        先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
        在运行插入的sql;就可以取出id属性对应的值
    AFTER运行顺序:
        先运行插入的sql(从序列中取出新值作为id);
        再运行selectKey查询id的sql;
     -->
    <selectKey keyProperty="id" order="BEFORE" resultType="Integer">
        <!-- 编写查询主键的sql语句 -->
        <!-- BEFORE-->
        select EMPLOYEES_SEQ.nextval from dual 
    </selectKey>
    
    <!-- 插入时的主键是从序列中拿到的 -->
    <!-- BEFORE:-->
    insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL) 
    values(#{id},#{lastName},#{email}) 
</insert>

 

posted @ 2019-01-01 19:25  kancy  阅读(206)  评论(0编辑  收藏  举报