四、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可配置的子标签:
- cache –命名空间的二级缓存配置
- cache-ref – 其他命名空间缓存配置的引用。
- resultMap – 自定义结果集映射
- parameterMap – 已废弃!老式风格的参数映射
- sql –抽取可重用语句块。
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- 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