mybatis从使用到了解(六)_mybatis的XML映射文件

Mapper XML文件介绍

Mybatis的强大只处在于它提供的强大的映射语句,和具有相同功能的JDBC代码对比,能大大减少重复代码。

insert

<insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyColumn="id">
    insert into student (student_name,student_age,student_phone,interests) values
    (#{student_name},#{student_age},#{student_phone},#{interests,javaType=[Ljava.lang.String;,jdbcType=VARCHAR})
</insert>
  • keyProperty
    selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
  • keyColumn
    匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
  • resultType
    结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。
  • order
    这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。
  • statementType
    与前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。

delete

<delete id="deleteById" parameterType="int">
   delete * from student where student_id = #{id}
</delete>

update

<update id = "updateById">
    update student set
        student_name = #{student_name},
        student_age = #{student_age},
        student_phone = #{student_phone},
        interests = #{interests}
    where student_id = #{student_id}
</update>

select

<select id="selectStudentById" parameterType="int" resultType="Student">
    <![CDATA[
        select * from student where student_id = #{id}
    ]]>
</select>
  • id
    命名空间中的唯一标识符,可被用来代表这条语句。
  • parameterType
    将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
  • flushCache
    将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。
  • timeout
    这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
  • statementType
    STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
  • useGeneratedKeys
    (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。
  • keyProperty
    (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
  • keyColumn
    (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
  • databaseId
    如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

sql

这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。可以被静态的参数化。

<sql id = "studentSql">
    student_id,student_name,student_age,student_phone,interests,teacher_id
</sql>
<select id="findById" parameterType="int" resultMap="studentResult">
    select
    <include refid="studentSql"/>
    from student where student_id = #{id}
</select>

resultMap

结果映射集,将数据表列数据映射成java对象,下面将提供一个两表级联查询的例子作为参考。

  • 数据格式
数据格式.png
  • java映射对象
public class Teacher {
    private Integer teacherId;
    private String teacherName;
    private String teacherAge;
    private String teacherPhone;
    private List<Student> students;
    public Integer getTeacherId() {
        return teacherId;
    }
    public void setTeacherId(Integer teacherId) {
        this.teacherId = teacherId;
    }
    public String getTeacherName() {
        return teacherName;
    }
    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }
    public String getTeacherAge() {
        return teacherAge;
    }
    public void setTeacherAge(String teacherAge) {
        this.teacherAge = teacherAge;
    }
    public String getTeacherPhone() {
        return teacherPhone;
    }
    public void setTeacherPhone(String teacherPhone) {
        this.teacherPhone = teacherPhone;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Teacher{" +
                "teacherId=" + teacherId +
                ", teacherName='" + teacherName + '\'' +
                ", teacherAge='" + teacherAge + '\'' +
                ", teacherPhone='" + teacherPhone + '\'' +
                ", students=" + students +
                '}';
    }
}
  • resultMap配置
 <resultMap id="teacherResult" type="com.yongssu.mybatis.demo1.Teacher">
    <id column="teacher_id" property="teacherId"/>
    <result column="teacher_name" property="teacherName"/>
    <result column="teacher_age" property="teacherAge"/>
    <result column="teacher_phone" property="teacherPhone"/>
    <association property="students" javaType="com.yongssu.mybatis.demo1.Student">
        <id column="student_id" property="studentId"/>
        <result column="student_name" property="studentName"/>
        <result column="student_age" property="studentAge"/>
        <result column="student_phone" property="studentPhone"/>
        <result column="interests" property="interests" javaType="[Ljava.lang.String;"/>
    </association>
</resultMap>

用association表示teacher和学生是1对1的关系,在Teacher中的Student只有一个学生,应该声明为Student student。

<resultMap id="studentResult" type="Student">
    <id column="student_id" property="studentId"/>
    <result column="student_name" property="studentName"/>
    <result column="student_age" property="studentAge"/>
    <result column="student_phone" property="studentPhone"/>
    <result column="interests" property="interests" javaType="[Ljava.lang.String;"/>
</resultMap>
<resultMap id="teacherResult" type="com.yongssu.mybatis.demo1.Teacher">
    <id column="teacher_id" property="teacherId"/>
    <result column="teacher_name" property="teacherName"/>
    <result column="teacher_age" property="teacherAge"/>
    <result column="teacher_phone" property="teacherPhone"/>
    <collection property="students" ofType="Student" resultMap="studentResult"/>
</resultMap>

用collection表示老师和学生是1对N的关系,在Teacher类中学生是一个列表。

  • sql多表联合查询语句
<select id="selectTeacher" parameterType="int" resultMap="teacherResult">
    select * from teacher
    left join student on student.teacher_id = teacher.teacher_id
    where teacher.teacher_id = #{id}
</select>

cache

mybatis包含了了一个非常强大的缓存特性,可以非常方便的配置和定制。在默认的情况下是没有开启缓存的。要开启缓存,需要在SQL映射文件中添加一行

<cache/>

缓存的效果如下

  • 映射语句文件中的所有 select 语句将会被缓存。
  • 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  • 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  • 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
    缓存的属性可以通过缓存元素的属性来修改。比如:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。

  • 可用的收回策略有:
    • LRU – 最近最少使用的:移除最长时间不被使用的对象。
    • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
    • 默认的是 LRU。
  • flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
  • size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。
  • readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。
    更详细的内容请参考文档:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容