• 四、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>
    kancy
  • 相关阅读:
    “无法更新EntitySet“*****”,因为它有一个DefiningQuery,而元素中没有支持当前操作的元素”问题的解决方法
    Web.Config全攻略
    C#常用的正则
    Asp.Net MVC2 Json
    webservice+Jquery返回Json格式【原创】
    JAVA线程池介绍以及简单实例
    从程序员到项目经理(17):你不是一个人在战斗思维一换天地宽
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    多表对应更新(跨服务器).sql
    sql导出excel.sql
  • 原文地址:https://www.cnblogs.com/kancy/p/10205599.html
Copyright © 2020-2023  润新知