mybaits常用知识点

来源:互联网 发布:淘宝号升3心方法 编辑:程序博客网 时间:2024/06/08 06:07

Sql元素用来定义一个可以复用的SQL 语句段,供其它语句调用。比如:

[xml] view plaincopy
  1. <!-- 复用sql语句  查询student表所有字段 -->  
  2. <sql id="selectStudentAll">  
  3.         SELECT ST.STUDENT_ID,  
  4.                    ST.STUDENT_NAME,  
  5.                    ST.STUDENT_SEX,  
  6.                    ST.STUDENT_BIRTHDAY,  
  7.                    ST.CLASS_ID  
  8.               FROM STUDENT_TBL ST  
  9. </sql>  

 
   这样,在select的语句中就可以直接引用使用了,将上面select语句改成:

[xml] view plaincopy
  1. <!-- 查询学生,根据id -->  
  2. <select id="getStudent" parameterType="String" resultMap="studentResultMap">  
  3.     <include refid="selectStudentAll"/>  
  4.             WHERE ST.STUDENT_ID = #{studentID}   
    </select> 

1.获取自动增长的id在Mybatis Mapper文件中添加属性“useGeneratedKeys”和“keyProperty”,其中keyProperty是Java对象的属性名,而不是表格的字段名

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <insert id="insert" parameterType="Spares"     
  2.         useGeneratedKeys="true" keyProperty="id">    
  3.         insert into system(name) values(#{name})    
  4. </insert>   
2.Mybatis执行完插入语句后,自动将自增长值赋值给对象systemBean的属性id。因此,可通过systemBean对应的getter方法获取!
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. int count = systemService.insert(systemBean);    
int id = systemBean.getId(); //获取到的即为新插入记录的ID   

对于不支持自动生成类型的数据库或可能不支持自动生成主键 JDBC 驱动来说,MyBatis 有另外一种方法来生成主键。

这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):

<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>
在上面的示例中,selectKey 元素将会首先运行,Author 的 id 会被设置,然后插入语句会被调用。这给你了一个和数据库中来处理自动生成的主键类似的行为,避免了使 Java 代码变得复杂。

尽管所有这些强大的选项很多时候你只简单指定属性名,其他的事情 MyBatis 会自己去推断,最多你需要为可能为空的列名指定 jdbcType

#{firstName}#{middleInitial,jdbcType=VARCHAR}#{lastName}

字符串替换

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

ORDER BY ${columnName}

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

要记住类型别名是你的伙伴。使用它们你可以不用输入类的全路径。比如:

<!-- In mybatis-config.xml file --><typeAlias type="com.someapp.model.User" alias="User"/><!-- In SQL Mapping XML file --><select id="selectUsers" resultType="User">  select id, username, hashedPassword  from some_table  where id = #{id}</select>
fetchTypeOptional. Valid values are lazy and eager. If present, it supersedes the global configuration parameter lazyLoadingEnabled for this mapping.

缓存

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 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。

使用自定义缓存

除了这些自定义缓存的方式, 你也可以通过实现你自己的缓存或为其他第三方缓存方案 创建适配器来完全覆盖缓存行为。

<cache type="com.domain.something.MyCustomCache"/>

这个示 例展 示了 如何 使用 一个 自定义 的缓 存实 现。type 属 性指 定的 类必 须实现 org.mybatis.cache.Cache 接口。这个接口是 MyBatis 框架中很多复杂的接口之一,但是简单 给定它做什么就行。

public interface Cache {  String getId();  int getSize();  void putObject(Object key, Object value);  Object getObject(Object key);  boolean hasKey(Object key);  Object removeObject(Object key);  void clear();}

要配置你的缓存, 简单和公有的 JavaBeans 属性来配置你的缓存实现, 而且是通过 cache 元素来传递属性, 比如, 下面代码会在你的缓存实现中调用一个称为 “setCacheFile(String file)” 的方法:

<cache type="com.domain.something.MyCustomCache">  <property name="cacheFile" value="/tmp/my-custom-cache.tmp"/></cache>

你可以使用所有简单类型作为 JavaBeans 的属性,MyBatis 会进行转换。

记得缓存配置和缓存实例是绑定在 SQL 映射文件的命名空间是很重要的。因此,所有 在相同命名空间的语句正如绑定的缓存一样。 语句可以修改和缓存交互的方式, 或在语句的 语句的基础上使用两种简单的属性来完全排除它们。默认情况下,语句可以这样来配置:

<select ... flushCache="false" useCache="true"/><insert ... flushCache="true"/><update ... flushCache="true"/><delete ... flushCache="true"/>

因为那些是默认的,你明显不能明确地以这种方式来配置一条语句。相反,如果你想改 变默认的行为,只能设置 flushCache 和 useCache 属性。比如,在一些情况下你也许想排除 从缓存中查询特定语句结果,或者你也许想要一个查询语句来刷新缓存。相似地,你也许有 一些更新语句依靠执行而不需要刷新缓存。

参照缓存

回想一下上一节内容, 这个特殊命名空间的唯一缓存会被使用或者刷新相同命名空间内 的语句。也许将来的某个时候,你会想在命名空间中共享相同的缓存配置和实例。在这样的 情况下你可以使用 cache-ref 元素来引用另外一个缓存。

<cache-ref namespace="com.someone.application.data.SomeMapper"/>
批量操作

foreach是循环,用来读取传入的list参数。批量处理是parameterType的类型必须要注意。foreach标签中的collection属性表示传入的是什么集合类型。item表示的是集合中的一个量类似于

List<String>list;

for(String str:list){

     ……

}

item就相当于str的作用,用来遍历collection。index就是集合的索引。open表示标签以什么开始,close表示标签以什么结束。seprator表示元素之间的间隔。


1、插入
最近需要用到Mybatis批量新增oracle数据库,刚开始在网上找到的方法是都是更新mySQL的,试了一下发现不适合Oracle,后来发现正确的oracle批量新增的sql是:

<insert id="insertAttractionsBatch" parameterType="java.util.List">
insert into ATTRACTIONS (

ID, NAME, LONGITUDE, LATITUDE,  UPDATE_TIME

)

  <foreach collection="list" item="item" index="index" separator="union all" > 
      (select  
#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.longitude,jdbcType=DECIMAL}, #{item.updateTime,jdbcType=TIMESTAMP}
       from dual)
    </foreach>
</insert>

需要重点注意的是sql中没有values,和<foreach>标签中的(selece ..... from dual),MySql中的sql是这样的:


  1. <insert id="addTrainRecordBatch" useGeneratedKeys="true" parameterType="java.util.List">  
  2.     <selectKey resultType="long" keyProperty="id" order="AFTER">  
  3.         SELECT  
  4.         LAST_INSERT_ID()  
  5.     </selectKey>  
  6.     insert into t_train_record (add_time,emp_id,activity_id,flag)   
  7.     values  
  8.     <foreach collection="list" item="item" index="index" separator="," >  
  9.         (#{item.addTime},#{item.empId},#{item.activityId},#{item.flag})  
  10.     </foreach>  
  11. </insert>  
2、更新

oracle和mysql数据库的批量update在mybatis中配置不太一样:

oracle数据库:

?
1
2
3
4
5
6
7
8
9
10
11
<updateid="batchUpdate"  parameterType="java.util.List">
      
       <foreach collection="list"item="item"index="index"open="begin"close="end;"separator=";">
                updatetest
                <set>
                  test=${item.test}+1
                </set>
                whereid = ${item.id}
       </foreach>
          
    </update>

mysql数据库:

mysql数据库采用一下写法即可执行,但是数据库连接必须配置:&allowMultiQueries=true

例如:jdbc:mysql://192.168.1.236:3306/test?useUnicode=true&amp;characterEncoding=UTF-8&allowMultiQueries=true

?
1
2
3
4
5
6
7
8
9
10
11
<updateid="batchUpdate"  parameterType="java.util.List">
      
          <foreach collection="list"item="item"index="index"open=""close=""separator=";">
                updatetest
                <set>
                  test=${item.test}+1
                </set>
                whereid = ${item.id}
         </foreach>
          
    </update>
<update id="updateOrderIdToItemCode" >
UPDATE `ITEM_CODE`  
<set>
ORDER_ID=#{orderId},
</set>
WHERE
<foreach collection="codes" item="codes" open="" close="" separator="OR">  
  ITEM_CODE = #{codes}  
 </foreach>  
</update>
3、删除

删除就与MySql一样了如下:

<delete id="deleteAttractions" parameterType="java.util.List">
  delete from ATTRACTIONS
  <where>
  <foreach collection="list" index="index" item="item" open="(" separator="or" close=")">     
 id=#{item.id}
    </foreach>
  </where>
  </delete>


  

0 0