一.最基本的配置文件

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers></configuration>

二.生命周期与作用域

一次请求对应一个Session,如果在一次请求中多次从SessionFactory打开Session是一种浪费(虽然有连接池不至于重新建立连接,但函数调用过程也是一种损耗)。

不要在多个线程中访问同一个Session,SqlSession与一次请求是一对一的关系。

三.更改

要考虑更改,当更改一个地方时,是不是要更改好多个地方,是不是需要自己费力的去找并且一旦遗漏一处就会导致运行时错误。不论做何种事,不要觉得它现在很美观,很漂亮简洁,要使它易维护,易更改,而更改之后依旧能维持开始的美观状态。

如果修改了resultType中的类名并且不想费力的全改掉,那就可以使用typeAliases

类型处理器必不可少,然而不要自己去碰它,因为系统把常用的基本数据类型都给封装好了,尽量使用简单的类型,把复杂的转化和控制放到java代码中去。比如,不要在数据库定义中使用数据库的日期时间类型,因为日期时间在不同语言中大大不同,而long这种类型十分通用.

不要使用枚举类型,用数字来代替,不仅简单,而且不会出错,而且便于交流。

四.映射器三种注册方式

Mybatis中注册映射器有三种方式:Xml,Class,Url

<!-- Using classpath relative resources -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- Using url fully qualified paths -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- Using mapper interface classes -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

把一个包下的全部接口都注册

<!-- Register all interfaces in a package as mappers -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

要注册最原始的那一个!如果写了xml及其对应的封装接口,那么应该注册xml;如果通过注解+接口方式实现,那么需要注册class。

五.增删改示例

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>
<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>

在这三中涉及到更改数据库的行为中,insert变化最多:

使用自动生成主键

首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就OK了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

经验告诉我,主键生成的权力还是要牢牢掌握在Java手中,不要让数据库自动生成主键,因为有些数据库不支持自增长类型的主键.对于主键的处理不同数据库各有差异,经验就是,使用UUID作为主键,通过代码来生成.

多行插入

实际上foreach标签相当于产生一个字符串,需要规定好字符串之间的间隔符号

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach></insert>

自定义主键

允许在插入主键时,先执行一次查询语句:

<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})</insert>

六. Sql+include语句

Sql+include相当于简单的文本复制粘贴,include还可以通过property给sql标签传参数

<sql id="sometable">
  ${prefix}Table</sql>
<sql id="someinclude">
  from
    <include refid="${include_target}"/></sql>
<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include></select>

七.#{}和${}

#{}是值代入,${}相当于字符串替换.默认情况下,使用#{}格式的语法会导致 MyBatis 创建预处理语句属性并安全地设置值(比如?)。这样做更安全,更迅速,通常也是首选做法,不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:

ORDER BY ${columnName}

这里 MyBatis 不会修改或转义字符串。

NOTE 以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

八.高级结果映射:会这一个就足够了

一个博客Blog,用B表示,它的作者Author是A,博客中有很多篇博文Post,用P表示,博文下面有很多评论Comment,用C表示.博文有很多标签Tag,用T表示.于是就有了BlogDetails这个VO,它包括Blog,Author,Post,Comment,Tag五个实体的属性.也就是说,传入一个参数BlogId,返回关于这个博客的所有信息,这是一个树形结构的信息.

<!-- Very Complex Statement -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
  select
       B.id as blog_id,
       B.title as blog_title,
       B.author_id as blog_author_id,
       A.id as author_id,
       A.username as author_username,
       A.password as author_password,
       A.email as author_email,
       A.bio as author_bio,
       A.favourite_section as author_favourite_section,
       P.id as post_id,
       P.blog_id as post_blog_id,
       P.author_id as post_author_id,
       P.created_on as post_created_on,
       P.section as post_section,
       P.subject as post_subject,
       P.draft as draft,
       P.body as post_body,
       C.id as comment_id,
       C.post_id as comment_post_id,
       C.name as comment_name,
       C.comment as comment_text,
       T.id as tag_id,
       T.name as tag_name
  from Blog B
       left outer join Author A on B.author_id = A.id
       left outer join Post P on B.id = P.blog_id
       left outer join Comment C on P.id = C.post_id
       left outer join Post_Tag PT on PT.post_id = P.id
       left outer join Tag T on PT.tag_id = T.id
  where B.id = #{id}</select>

这个查询语句的resultMap可以这么写

<!-- Very Complex Result Map -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection></resultMap>

九.id & result

id&result是结果集映射中常用的标签,例如

<id property="id" column="post_id"/>

<result property="subject" column="post_subject"/>

id 和 result 都映射一个单独列的值到简单数据类型(字符串,整型,双精度浮点数,日期等)的单独属性或字段。这两者之间唯一不同是 id 表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和嵌入结果映射(也就是联合映射) 。

十.动态Sql

动态Sql之if

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

动态Sql之switch

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

Mybatis主要功能是结果集映射,附加功能【动态sql】+【sql语句构建器】

十一.动态Sql之trim

where和set相当于trim的另一种写法,trim就是简单的字符串处理。

where是trim在查询语句select中的用法

set是trim在更新语句update中的用法

trim可以设定prefix和sufix作为前缀和后缀,还可以prefixOverride和sufixOverride擦除某种前缀和后缀。擦除前缀后缀时,可以使用“|”作为或符号,如and|or

十二.bind元素

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

如果只有一个参数,无需使用@Param()注解

你可以传递多个参数给一个映射器方法。 如果你这样做了, 默认情况下它们将会以它们 在参数列表中的位置来命名,比如:#{param1},#{param2}等。如果你想改变参数的名称(只在多参数 情况下) ,那么你可以在参数上使用@Param(“paramName”)注解.

Mybatis使用总结的更多相关文章

  1. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  2. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  3. [原创]mybatis中整合ehcache缓存框架的使用

    mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...

  4. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  5. mybatis plugins实现项目【全局】读写分离

    在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...

  6. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

  7. Mybatis XML配置

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  8. MyBatis源码分析(一)开篇

    源码学习的好处不用多说,Mybatis源码量少.逻辑简单,将写个系列文章来学习. SqlSession Mybatis的使用入口位于org.apache.ibatis.session包中的SqlSes ...

  9. (整理)MyBatis入门教程(一)

    本文转载: http://www.cnblogs.com/hellokitty1/p/5216025.html#3591383 本人文笔不行,根据上面博客内容引导,自己整理了一些东西 首先给大家推荐几 ...

  10. MyBatis6:MyBatis集成Spring事物管理(下篇)

    前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基 ...

随机推荐

  1. jquery获取关于宽度和高度的尺寸问题

    作者原创,转载请出名出处! console.log("可视区高度:"+$(window).height()); console.log("可视区宽度:"+$(w ...

  2. 基于WebGL的三维地形渲染

    1.生成WebMap页面 #!/usr/bin/env python # -*- coding: utf-8 -*- import subprocess from jinja2 import Envi ...

  3. HTML5中地图矢量化

    我们可以获取canvas对象为var c=document.getElementById("myCanvas");其应有js属性方法如下列举:1:绘制渲染对象, c.getCont ...

  4. ToolWindow工具类

    package com.dute.dutenews.utils; import android.app.Activity; import android.content.Context; import ...

  5. 项目管理详细任务(PMBOK2008)

    启动 规划 执行 监控 收尾 选择项目经理 确定你将如何做计划-作为项目管理计划的一部分 组建最终项目团队 根据绩效基线进行绩效测量 确定收尾过程 确定公司文化和现存组织形式 创建项目范围说明书 执行 ...

  6. Windows Phone App Studio发布重要更新-支持Windows 8.1 源代码生成

    自2013年8月Apps Team发布Windows Phone App Studio以来,由于其低入门门槛和较好的易用性,用户和项目数量增长迅速,从Windows Phone Developer B ...

  7. 人工智能与3A

    我在Tid2014上的一个小视频: 下一代的码农会是什么样的呢?且听咕咚老王的“3A”畅谈——“Ai.Art.Any”. 在艺术的视角下,世界是沉寂的.美丽的: 在码农的眼中,世界是有“码”的朦胧美吗 ...

  8. .NET Framework各版本比较

    (1)本文比较了.NET Framework多个版本之间的区别,方便各位选择和切换.NET Framework. 版本号 发布日期 Visual Studio的版本 Windows上的默认情况 CLR ...

  9. Failed to create AppDomain 'xxx'. Exception has been Failed to create AppDomain

    一服务器上的数据库全部被置于紧急模式(EMERGENCY),在错误日志里面能看到大量下面的错误 Failed to create AppDomain "YourSQLDba.dbo[runt ...

  10. 解决问题:The context cannot be used while the model is being created

    使用Entity Framework (v6.1.3)突然遇到这个问题了,之前一直好好的,怎么破? 此处省略了多次在“好”与“坏"的项目中试验的过程(苦啊),直接给出答案.答案是:没有按Db ...