mybaits使用的基本介绍------xml映射文件配置
我们继续谈论mybaits使用的基本介绍,关于xml的配置已经在上一篇文章介绍了,如果你还没有阅读的话可以点击一下连接:mybaits使用的基本介绍------mybatis-config.xml配置。xml映射文件的配置如下:
1.在xml映射文件头部分中必须写上dtd文件,这是dtd是mybatis-config.xml的配置规则
<?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">
2.来看下面的例子进行分析解析<?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="UserMapper"> <resultMap id="resultmap" type="User" autoMapping="true"> <id column="id" property="id"/>
<!-- association中的property是在user实体类中的参数名,javaType是该参数名的类型 -->
<association property="role" javaType="Role"> <id property="role_id" column="roleId"/> <result property="name" column="name"/> </association> </resultMap> <select id="show" resultMap="resultmap"> SELECT u.*,r.name FROM user u LEFT JOIN role r ON u.role_id = r.role_id </select> <insert id="add" parameterType="User" useGeneratedKeys="true" keyProperty="id"> insert into user (username,password,age) values (#{username},#{password},#{age}) </insert> <select id="showById" parameterType="User" resultMap="resultmap"> SELECT r.*,u.id,u.age,u.`password`,u.username FROM role r LEFT JOIN user u ON r.role_id=u.role_id <where> <if test="id != null and id != ''"> id = #{id} </if> <if test="username != null and username != ''"> and username = #{username} </if> </where> </select> <select id="showByIdName" parameterType="User" resultMap="resultmap"> SELECT r.*,u.id,u.age,u.`password`,u.username FROM role r LEFT JOIN user u ON r.role_id=u.role_id <where> <choose> <when test="id != null and id != ''"> id = #{id} </when> <when test="username != null and username != ''"> and username = #{username} </when> <otherwise> and 1=1 </otherwise> </choose> </where> </select> </mapper>
(1)namespace这是命名空间,它必须是唯一的,跟id类似的,我们调用mapper里面的sql语句都是通过namespace.id才能调用,id是sql语句的id。如果有dao接口层和mapper之间映射的话,那么namespace的值为dao层中接口类的完整路径,否则会报错。
(2)resultMap中的column数据库表中的列名,property是实体类的属性名 。
(3)autoMapping:设置这个属性,MyBatis将会为这个ResultMap开启或者关闭自动映射。也就是在上面的resultmap中没有写出所有需要的数据库列名,设置这个属性后它会自动添加的。这个叫做自动映射,详细介绍请看第3点。
(4)association:关联元素处理“有一个”类型的关系。
关联中不同的是你需要告诉 MyBatis 如何加载关联。MyBatis 在这方面会有两种不同的 方式:
- 嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型。对于大型数据集合和列表将不会表现很好。 问题就是我们熟知的 “N+1 查询问题”。
- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。
(5)useGeneratedKeys:使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键
keyProperty:MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值
(6)foreach语句的使用
foreach:元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串以及在迭代中间放置分隔符。
注意 :你可以将任何可迭代对象(如列表、集合等)和任何的字典或者数组对象传递给foreach作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>
(7)a,在<where>中它会自动去掉where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
b,如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。prefixOverrides去掉前缀中的值,suffixOverrides去掉后缀中的值。
<trim prefix="" prefixOverrides=" " suffixOverrides=" "> ... </trim>
c,set 元素会动态前置 SET 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。
<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>
3.自动映射
在简单的场景下,MyBatis可以替你自动映射查询结果。 如果遇到复杂的场景,你需要构建一个result map。
在没有Mybatis中一些其他问题。
自动映射有两种策略:
(1)当自动映射查询结果时,MyBatis会获取sql返回的列名并在java类中查找相同名字的属性(忽略大小写)。 这意味着如果Mybatis发现了ID列和id属性,Mybatis会将ID的值赋给id。
(2)通常数据库列使用大写单词命名,单词间用下划线分隔;而java属性一般遵循驼峰命名法。 为了在这两种命名方式之间启用自动映射,需要将mapUnderscoreToCamelCase设置为true。
有三种自动映射等级:
- NONE - 禁用自动映射。仅设置手动映射属性。
- PARTIAL - 将自动映射结果除了那些有内部定义内嵌结果映射的(joins).
- FULL - 自动映射所有。
默认值是PARTIAL,这是有原因的。当使用FULL时,自动映射会在处理join结果时执行,并且join取得若干相同行的不同实体数据,因此这可能导致非预期的映射。
4.缓存
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
<cache/>
字面上看就是这样。这个简单语句的效果如下:
- 映射语句文件中的所有 select 语句将会被缓存。
- 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
- 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
- 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
- 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
- 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
MybatisDemo的代码我已经上传GitHub:https://github.com/javJoker/github/tree/master/mybatis
详细内容可以参考Mybatis官方文档:http://www.mybatis.org/mybatis-3/zh/index.html