乐趣区

关于mybatis:MuBatis框架的使用解析数据库相关API的基本介绍

动静 SQL

if

  • 依据条件蕴含 where 子句的一部分

    <select id="findActiveBlogLike" resultType="Blog">
      SELECT * FROM BLOG WHERE state = 'ACTIVE'
      <where>
          <if test="title != null">
              AND title like #{title}
          </if>
          <if test="author != null and author.name != null">
              AND author_name like #{author.name}
          </if>
      </where>
    </select>
  • 紧接着 < where > 的第一个条件不要加AND

    choose-when-otherwise

  • 不应用所有的条件, 只是想从多个条件中抉择一个应用

    <select id="findActiveBlogLike" resultType="Blog">
      SELECT * FROM BLOG WHERE state = 'ACTIVE'
      <choose>
          <when tset="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>

    where

  • where元素只会在子元素返回内容的状况下才会插入 WHRER 的子语句
  • 若子语句的结尾为 AND 或者 OR,where 元素会将这些去除

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

    trim

  • 能够通过自定义 trim 元素来定制 where 元素的性能

    • 比方和 where 元素等价的自定义 trim 元素. 会移除所有 prefixOverrides 属性中指定的内容, 并且插入 prefix 属性中指定的内容:

      <trim prefix="WHERE" prefixOverrides="AND |OR">
         ...
      </trim>

      prefixOverrides属性会疏忽通过管道符宰割的文本序列 , 不同的文本序列之间必须要有空格.

      • set 元素等价的自定义 trim 元素. 笼罩了后缀值设置, 并且自定义前缀值:
      <trim prefix="SET" suffixOverrides=",">
          ...
      </trim>

      set

  • 用于动静更新语句的叫作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>
  • set元素会动静地进行行首插入 SET 关键字, 并会删掉额定的逗号, 这些逗号是在应用条件语句给列赋值时引入的

    foreach

  • 对汇合进行遍历的时候应用 foreach, 特地是在构建IN 条件语句的时候

    <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>
  • foreach 容许指定一个汇合:

    • 申明能够在元素体内应用的汇合项 item 和索引 index 变量
    • 指定结尾 open 与结尾 close 的字符串以及汇合项迭代之间的分隔符separator
    • foreach 不会谬误地增加多余的分隔符
  • 应用 foreach 时:

    • 能够将任何可迭代对象, 比方 List,Set,Map 对象或者数组对象 作为汇合参数传递给foreach
    • 当应用 可迭代对象 或者 数组 时:

      • index是以后迭代的序号
      • item的值是本次迭代获取到的元素
    • 当应用 Map 对象或者 Map.Entry 对象的汇合

      • index是键
      • item是值

        script

  • 要是想要在带注解的接口类中应用动静 SQL 语句, 能够应用 script 元素

    @update({"<script>",
              "update Author",
                  "<set>",
                      "<if test='username != null'>username=#{username},</if>",
                      "<if test='password != null'>password=#{password},</if>",
                      "<if test='email != null'>email=#{email},</if>",    
                  "</set>",
                  "where id=#{id}",
                  "</script>"})    
    })
    void updateAuthorValues(Author author);

    bind

  • 能够应用 bind 元素在 OGNL 表达式以外创立一个变量, 并绑定到上下文中

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

    多数据库反对

  • 如果配置了databaseIdProvider, 就能够在动静代码中应用名为 “_databaseId” 的变量来为不同的数据库构建特定的语句

    <insert id="insert">
      <selectKey keyProperty="id" resultType="int" order="BEFORE">
          <if test="_databaseId =='oracle'">
              select seq_users.nextval from dual
          </if>
          <if test="_databaseId =='db2'">
              select nextval for seq_users from sysibm.sysdummy1
          </if>
      </selectKey>
      insert into users values (#{id}, #{name})
    </insert>

    动静 SQL 中插入脚本语言

  • MyBatis 3.2 版本开始反对插入脚本语言
  • 容许插入一种语言驱动, 并基于这种语言来编写动静 SQL 查问语句
  • 通过实现 LanguageDriver 接口插入语言:

    public interface LanguageDriver {ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
      
      SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
      SqlSource crateSqlSource(Configuration configuration, String script, Class<?> parameterType);
    }
  • 实现自定义语言驱动后, 能够在 mybatis-config.xml 文件中设置为默认语言:

    <typeAliases>
      <typeAliase type="com.oxford.MyLanguageDriver" alias="myLanguage" />
    </typeAliases>
    <settings>
      <setting name="defaultScriptingLanguage" value="myLanguage" />
    </settings>
  • 也能够应用 lang 属性为特定的语句指定语言:

    <select id="selectBlog" lang="myLanguage">
      SELECT * FROM BLOG
    </select>
  • 或者在 mapper 接口上应用 @Lang注解:

    public interface Mapper {@Lang(MyLanguageDriver.class)
      @Select("SELECT * FROM BLOG")
      List<Blog> selectBlog();}
  • MyBatis 中的 xml 文件中的所有 xml 标签都由默认 MyBatis 语言提供, 是由语言驱动org.apache.ibatis.scripting.xmltags.XmlLanguageDriver, 别名为xml. 提供的.

    Java API

  • MyBatis 的执行办法在 SqlSession 类中

    语句执行办法

  • 这些办法被用来执行定义在 SQL 映射 XML 文件中的 SELECT,INSERT,UPDATE 和 DELETE 语句

    • 每一个办法都接管语句的 ID 以及 参数对象
    • 参数能够是 原始类型(反对主动装箱), 包装类,JavaBean,POJO 或者 Map

      selectOne
      <T> T selectOne(String statement, Object parameter);
      selectList
      <E> List<E> selectList(String statement, Object parameter);
  • selectOne 和 selectList 的不同点是:

    • selectOne必须返回 一个对象或者 null 值, 如果返回值多于一个就会抛出异样
    • 如果不分明返回对象会有多少个, 就应用selectList

      selectCursor
      <T> Cursor<T> selectCursor(String statement, Object parameter);
  • 游标 Cursor 与列表 List 返回的后果雷同, 不同的是: 游标借助 迭代器 实现了数据的惰性加载

    try (Cursor<Entity> entities = session.selectCursor(statement, param)) {for (Entity entity : entities) {// 解决单个实体}
    }
       
    selectMap
    <K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey); 
  • selectMap会将返回对象的其中一个属性作为 key 值, 将对象作为 value 值, 从而将多个后果集转为 Map 类型值

    insert
    int insert(String statement, Object parameter);
    update
    int update(String statement, Object parameter);
    delete
    int delete(String statement, Obejct parameter);
  • 如果须要 查看某个对象是否存在, 最好的方法就是 查问一个 count 值, 应用 0 或者 1
  • 因为不是所有语句都须要参数, 所以这些办法都具备一个不须要参数的重载模式
  • insert, updatedelete 办法返回值示意受该语句影响的行数

    select 高级版本

  • 容许限度返回行数的范畴
  • 提供自定义后果解决逻辑
  • 通常是在数据集十分宏大的情景下应用

    selectList
    <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
    selectCursor
    <T> List<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
    selectMap
    <K, V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
    select
    void select(String statement, Object parameter, ResultHandler<T> handler);
    select
    void select(String statement Object parameter, RowBounds rowBounds, ResultHandler<T> handler);
  • RowBounds参数:

    • 指定 MyBatis 略过指定数量的记录, 并限度返回后果的数量
    • RowBounds 类的 offset 和 limit 值只有在构造函数时能力传入, 其余时候是不能批改的

      int offset = 100;
      int limit = 25;
      RowBounds rowBounds = new RowBounds(offset, limit);
  • ResultHandler参数:

    • 容许自定义每行后果的处理过程
    • 能够增加到 List 中, 创立 Map 和 Set. 甚至抛弃每个返回值, 只保留计算后的统计后果
  • ResultHandler 接口:

    package org.apache.ibatis.session;
    public interface ResultHandler<T> {void handlerResult(ResultContext<? extends T> context);
    }
  • ResultContext参数:

    • 容许拜访后果对象和以后已被创立的对象数目
    • 提供一个返回值为 Booleanstop办法, 能够应用这个 stop 办法来进行 MyBatis 加载更多的后果
  • 应用 ResultHandler 要留神两条限度:

    • 应用带 ResultHandler 参数的办法时, 收到的数据不会被缓存
    • 当应用高级的后果映射集 resultMap,MyBatis很可能须要数行后果来结构一个对象. 如果这时应用了 ResultHandler, 可能会接管到关联association 或者汇合 collection 中尚未被残缺填充的对象

      革除批量更新办法

  • ExecutorType 设置为 ExecutorType.BATCH 时, 能够应用 flushStatements 革除缓存在 JDBC 驱动类中的批量更新语句

    flushStatements
    List<BatchResult> flushStatements();

    事务管制办法

  • 管制事务作用域的办法有四个, 如果曾经 设置了主动提交或者应用了内部事务管理器, 就不须要应用这些办法
  • 如果正在应用 Connection 实例管制的 JDBC 事务管理器, 就能够应用以下的四个办法:

    void commit();
    
    void commit(boolean force);
    
    void rollback();
    
    void rollback(boolean force);
  • 默认状况下 ,MyBatis不会主动提交事务, 除非发现到调用了 插入, 更新或删除 办法扭转了数据库
  • 如果没有应用这些办法提交批改, 那么就能够在 commitrollback办法参数传入 true 值来保障事务被失常提交

    • 留神: 在主动提交模式或者应用了内部事务管理器的状况下, 设置 force 值对 session 有效
  • 大部分状况下, 无需调用 rollback(), 因为MyBatis 会在没有调用commit() 时实现回滚操作
  • 然而, 当要在一个可能屡次提交或回滚的 session 中具体管制事务, 就要应用到回滚 rollback 操作
退出移动版