Ibatis 3.0 之前使用的都是2.0 3.0与2.0的内容有很大的不同

以前用过ibatis2,但是听说ibatis3有较大的性能提升,而且设计也更合理,他不兼容ibatis2.尽管ibatis3还是beta10的状态,但还是打算直接使用ibatis3.0,
ibatis3.0应该更简单高效.最近还自己写了个ibatis3.0与spring集成的bean,运行还正常,还自鸣得意了一番,但是当独立使用ibatis时,在事务管理这个方面还是出现不少问题,所以还是打算再认真研究一番ibatis3.0

1.SqlSessionFactory

每个ibatis应用都应该只有一个SqlSessionFactory的实例对象,所以一般设置为static属性或者使用spring管理时返回singleton类型,与spring集成时其实也是写一个怎样构建SqlSessionFactory的Bean,

构建SqlSessionFactory一般是SqlSessionFactoryBuild通过读取ibatis的配置文件而进行build的:

Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuild().build(reader);

配置文件SqlMapConfig.xml的一般结构(元素顺序不能变)

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"

"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">

<configuration>

<properties resource="jdbc.properties" />

<settings>

<setting name="cacheEnabled" value="false" />

<setting name="lazyLoadingEnabled" value="true" />

<setting name="multipleResultSetsEnabled" value="false" />

<setting name="useColumnLabel" value="true" />

<setting name="defaultExecutorType" value="SIMPLE" />

</settings>

<typeAliases>

<typeAlias alias="Person" type="test.Person"/>

</typeAliases>

<environments default="dev">

<environment id="dev">

<transactionManager type="jdbc">

<property name="" value="" />

</transactionManager>

<dataSource type="POOLED">

<property name="driver" value="${driver}" />

<property name="url" value="${url}" />

<property name="username" value="${user}" />

<property name="password" value="${password}" />

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource="sqlMappers/Person.xml" />

<mapper resource="sqlMappers/UserShop.xml" />

</mappers>

</configuration>

<settings />是配置ibatis的具体行为属性的,

<typeAliases />是为了将较长的module类名简化,在<mappers />里可以使用

<environment />是配置transaction manager和connection pooling的

<mappers />是sql语句的构造地方,一般每个module对应一个文件

2.SqlSession

可以从SqlSessionFactory得到SqlSession: sessionFactory.openSession();

SqlSession是一切Sql相关数据库操作的中心,insert,select,update,delete...

SqlSession不是线程安全的(也就是有状态的),所以它的作用域最好是在一个Thread下,每个Thread有自己的SqlSession对象实例,彼此不相关.

Never keep references to a SqlSession instance in a static field or
even an instance field of a class.  Never keep references to a

SqlSession in any sort of managed scope, such as HttpSession of of the Servlet framework.

默认sessionFacory.openSession()拿到的SqlSession不是自动commit的,所以如果是更新操作必须自己执行session.commit()

关闭SqlSession很重要,必须保证在线程结束时关闭这个SqlSession,可以在finally中

session.close();

那跟Spring集成是怎样做到这一点的呢,因为dataSource是由spring管理的,所以他可以保证在一个Thread的每个方法中拿到的Connection是同一个对象,

虽然每个方法从sessionFactory.openSession()拿到的SqlSession对象是不同的,但是sqlSession对
象中的connection是相同的,所以spring就可以在service层的方法结束之前将这个connection
commit跟close,这样就实现了事务控制.

我们往往在dao层是一个方法对应一个sql语句的,不在这里控制事务,控制事务应该在service层, dao的每个方法拿到的sqlsession对象都是不相同的(尽管它的connection可能相同).

那我们应该怎样在没有spring的情况下实现ibatis的事务控制呢?还要保持dao的结构,以保持能跟spring随时切换?

看来ThreadLocal要派上用场了

---占位----

3.讲完了SqlSession这个大头,再来说说具体的配置信息

配置文件结构

configuration

properties

settings

typeAliases

typeHandlers

objectFactory

plugins

environments

environment

transactionManager

dataSource

mappers

4.ibatis可以配置多个environment环境

供开发,测试,上线等切换

但是一个SqlSessionFactory只能对应一个environment,

也就是 one SqlSessionFactory per database

5.transactionManager

There are two TransactionManager types (i.e. type=”?????”) that are included with iBATIS:

JDBC – This configuration simply makes use of the JDBC commit
and rollback facilities directly.  It relies on the connection retrieved
from the dataSource to manage the scope of the transaction.

MANAGED  – This configuration simply does nothing, quite
literally.  It never commits, rolls back or closes a connection. 
Instead, it lets the container manage the full lifecycle of the
transaction (e.g. Spring or a JEE Application Server context).

6.dataSource的配置

类型可使用UNPOOLED,POOLED,JNDI三种

7.接下来是重头戏mappers

这里是我们直接写sql的地方,ibatis在这里也花了最多功夫,特别是关于select的mapper.

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE mapper

PUBLIC "-//ibatis.apache.org//DTD mapper 3.0//EN"

"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="test.UserShop">

<insert ...> ... </insert>

<select ...> ... </select>

<update ...> ... </update>

<delete ...> ... </delete>

</mapper>

(1).select

<select id="getUser" parameterType="int" resultType="test.User">

select * from user where userId = #{value}

</select>

注意#{value},resultType可以换成resultMap,这个resultMap就比较复杂了,也是最强大的工具,可以完成复杂的mapper(resultSet->object)

(2).insert,update,delete

这几个操作都比较类似,返回的一般是受影响的行数.

insert 可以返回auto_increament的值

<insert id="insertPerson" parameterType="Person"

useGeneratedKeys="true" keyProperty="userId">

insert into person(name,age) values(#{name},#{age})

</insert>

这样,传入的Person类对象的userId就会被set成auto_increament那个值.

(3).可以使用<sql id="columns">name,age</sql>构造可重用的sql片段

这样就可以在那四个主要的元素里用<include refid="columns">引用这个常用sql片段

(4).resultMap很复杂,它可以处理一对一,一对多,多对多关系

比如一个blog对应一个author, 一个blog对应多个post, 一个post对应多个comment

resultMap的结构:

resultMap

constructor (向java构造函数设置值)

idArg

arg

id (id result,同result)

result (字段映射注入)

association (一对一关系,它里面有自己的result映射)

collection  (一对多关系, 它里面有自己的result映射,和可能的collection)

discriminator

(5).association (一个Blog对应一个Author)

<resultMap id="blogResult" type="Blog">

<association property="author" column="blog_author_id" javaType="Author">

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

<result property="username" column="author_username" />

</associaton>

</resultMap>

当然association也可以使用

<association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>

在Blog类定义里会有一个Author类字段,会自动装载数据

private Author author;

(6).collection (一个Blog对应多个Post)

<resultMap id="blogResult" type="Blog">

<collection property="posts" column="blog_id" ofType="Post" javaType="ArrayList" resultMap="postResult" />

</resultMap>

collection也可以精简为

<collection property="posts" ofType="Post" resultMap="postResult" />

相就地,在Blog类定义里会有:

private List<Post> posts

8.cache

其实我是不打算在ibatis这层做cache的,一般cache还是在service层做.

ibatis对于select才会进行cache,而我觉得这个时候cache没多大意义,因为多次請求相同的select語句(sql相同)而又没有进行表的相关update的情况并不多.

但还是看看ibatis是怎样处理cache的

要开启cache,需要在mapper文件中加上一句: <cache />

(1).cache所有select的結果

(2).在同一mapper文件中的insert,update,delete会flush cache

(3).cache使用least recently used(LRU)算法

(4).cache没有定时flush的功能

(5).cache保存1024个对象或list引用

(6).cache是read/write cache, 从cache拿出对象不是共享的,caller可以任意修改而不用担心其他caller也拿到相同的对象(相同的reference)

9.动态SQL

以前用jdbc时经常要根据输入条件而组装成不同的sql,这种就是动态sql

ibatis的动态sql关键词:

if, choose(when,otherwise),trim(where,set),foreach

(1).if

<if test="title != null">

AND title like #{title}

</if>

(2).choose(when,otherwise)只选择其中一种情况

<select ...>

<choose>

<when test="title != null">

AND title like #{title}

</when>

<when test="author != null and author.name != null">

AND title like #{author.name}

</when>

<otherwise>

AND featured = 1

</otherwise>

</choose>

</select>

(3).trim, where, set

<select id="findBlog" paramaterType="Blog" 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 title like ${author.name}

</if>

</where>

</select>

<update id="updateAuthorIfNecessary"

parameterType="domain.blog.Author">

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>

(4).foreach

<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>

10.ibatis的annotation

ibatis3.0也增加了annotation,主要还是推荐使用xml配置

时间: 2024-08-12 19:10:26

Ibatis 3.0 之前使用的都是2.0 3.0与2.0的内容有很大的不同的相关文章

页码0~N ,其中0,1....9都出现了几次

/* 这道题目可以暴力解答:对1~n的每个数进行从低位到高位分析 一旦这个数字num出现,a[num]++即可 第二种方法: 由0,1,...9组成的所有n位数,从n个0到n个9共10^n个数,0,1,...9 出现的次数一样设为a(n),那么易得: a(n)=10a(n-1)+10^(n-1) (n>1) a(n)=1(n==1)化简可得到 a(n)=n*10^(n-1). 那么这道题目从高位到低位依次处理,最后减去多余的前导零即可 */ #include <bits/stdc++.h>

android 127.0.0.1/localhost connection refused,在模拟器上应该用10.0.2.2访问你的电脑本机

调试中通过android simulator模拟器链接localhost或者127.0.0.1,因为我在电脑上面建立了apache,我的代码大概就是URL url = new URL(urlString);     URLConnection urlconn = url.openConnection(); 但是报错了!! Exception 1:java.net.ConnectException: localhost/127.0.0.1:8080 - Connection refused 问题是

Zend Studio 12.0.2正式版发布和破解方法,zend studio 12.0.1汉化,相式设置为Dreamweaver,空格缩进为4个, 代码默认不折叠的设置,Outline中使用的图形标志,代码颜色之eot设置。

背景:zend studio 12.0.2 修复了一个12.0.1的:  Fixed problem with referenced variables marked as undefined,我都说好像有问题,刚开始还以为是破解得有问题呢. AddTime:2015-4-5zend studio 12.0.2 破解&keygen:http://download.csdn.net/detail/wfstock/8418635 破解ZendStudio 10.1:刚才装了个ZendStudio 1

coco2d-x 3.0游戏实例学习笔记 《跑酷》 二 游戏界面--全新的3.0物理世界

从这里开始,就和之前前辈的有很多不同啦. 在MainScene中,开始按钮中,我们就要通过回调函数,进入到我们的游戏场景啦. 那么在游戏场景中我们定义为:PlayScene ,而且是一个带物理世界的场景,cocos2d-x 3.0中要创建物理Scene是很简单的,因为它都帮我们封装好了. 那么这一步,我们在PlayScene 中主要完成以下功能: 1.物理世界创建 2.创建一个地面的物理刚体 相关知识个人见解: 所谓的创建物理世界,个人觉得是一个抽象的东东,作为新手,开始并不能理解,开始你可以就

.Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器

原文:.Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器 目标:使用.net core最新的3.0版本,借助httpclient和本机的host域名代理,实现网络请求转发和内容获取,最终显示到目标客户端! 背景:本人在core领域是个新手,对core的使用不多,因此在实现的过程中遇到了很多坑,在这边博客中,逐一介绍下.下面进入正文 正文: 1-启用httpClient注入: 参考文档:https://docs.microsoft.c

Atitit..jdk&#160;java&#160;各版本新特性&#160;1.0&#160;1.1&#160;1.2&#160;1.3&#160;1.4&#160;1.5(5.0)&#160;1.6(6.0)&#160;7.0&#160;8.0&#160;9.0&#160;attilax&#160;大总结

Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结 1.1. Java的编年史2 1.2. Java版本:JDK 1.02 1.3. Java版本:JDK 1.13 1.4. Java版本:JDK 1.2 (Java 2)4 1.4.1. 1999年5 1.4.2. 2000年5 1.5. Java版本:JDK 1.35 1.5.1. 2001年6 1.5.2. 2002年7

Spark 1.0.0企业级开发动手:实战世界上第一个Spark 1.0.0课程,涵盖Spark 1.0.0所有的企业级开发技术

课程介绍 2014年5月30日发布了Spark 1.0.0版本,而本课程是世界上第一个Spark1.0.0企业级实践课程,课程包含Spark的架构设计.Spark编程模型.Spark内核框架源码剖析.Spark的广播变量与累加器.Shark的原理和使用.Spark的机器学习.Spark的图计算GraphX.Spark SQL.Spark实时流处理.Spark的优化.Spark on Yarn.JobServer等Spark 1.0.0所有的核心内容 最后以一个商业级别的Spark案例为基础,实战

图像细化函数(背景为黑色像素值为0,前景为白色像素值255,必须只含有0和255的像素值,即二值化后的图像)

procedure thinimage(srcimage:pIplImage);var count:Integer; //表示迭代次数 Zhangmude:array [1..9] of Integer; deletelist1,deletelist2:Tlist<Tcvpoint>; //存放着要删除的点 idx,i,j:Integer; whitepointtotal,ap:Integer; tempoint:TCvPoint;begin deletelist1:=Tlist<Tcv

Atitit.你这些项目不都是模板吗?不是原创&#160;&#160;集成和整合的方式大总结

Atitit.你这些项目不都是模板吗?不是原创  集成和整合的方式大总结 1.1. 乔布斯的名言:创新即整合(Creativity is just connecting things).1 1.2. 腾讯的微创新1 2. 那么软件系统集成和整合的方式常见的有哪些呢? 1 2.1. 一.软件系统功能完全融合在一个系统中2 2.2. 软件系统间以接口方式相互调用2 2.3. 直接访问数据库不是最好的解决方案2 2.4. Gui2 2.5. cli2 2.6. Sso单点登录2 企业在信息化的过程中会