事务管理。
事务有四个特性:ACID
原子性Atomicity,一致性Consistency,隔离性Isolation,持续性Durability。
MyBatis的事务设计的重点是Transaction接口,包含四个方法,获取连接,提交,回滚,关闭连接。
事务管理分别2种形式:使用JDBC的事务管理机制:即利用java.sql.Connection完成对事物的操作;使用MANAGED的事务管理机制,MyBatis自身不会去实现事务管理,而是让容器如WebLogic,JBOSS等来实现事务管理。
但是网上,似乎都是搭配着Spring的事务管理使用。
缓存机制
一级缓存,是SqlSession范围的,默认开启,无需任何配置。如果SqlSession执行了DML操作(增删改),并提交到了数据库,MyBatis会清空SqlSession中的一些缓存,避免脏读。
不同SqlSession之间的缓存数据区域是互不影响的,这个缓存数据由一个HashMap实现,key为对象的id,value为对象。实验如下:
OrderMapper orderMapper = session.getMapper(OrderMapper.class);
HashMap hashMap = new HashMap();
hashMap.put("arg0", 1);
hashMap.put("arg1", "xboxone");
System.out.println(orderMapper.selectOrderByIdLike(hashMap));
session.commit();
System.out.println(orderMapper.selectOrderByIdLike(hashMap));
System.out.println(orderMapper.selectOrderByIdLike(hashMap));
session.commit();
session.close();
查询3同一条数据3次,第一次之后commit了,看看输出情况:
==> Preparing: SELECT * FROM tb_order WHERE id = ?
==> Parameters: 1(Integer)
<== Columns: id, code, total, user_id
<== Row: 1, xboxone, 59.99, 1
<== Total: 1
[Order{id=1, code='xboxone', total=59.99, user3=null, articles=null}]
==> Preparing: SELECT * FROM tb_order WHERE id = ?
==> Parameters: 1(Integer)
<== Columns: id, code, total, user_id
<== Row: 1, xboxone, 59.99, 1
<== Total: 1
[Order{id=1, code='xboxone', total=59.99, user3=null, articles=null}]
[Order{id=1, code='xboxone', total=59.99, user3=null, articles=null}]
可以说是非常能说明问题了。
二级缓存是mapper级别的缓存,范围更大,作用域是mapper的同一个namespace,不同的SqlSession两次执行相同namespace下单sql语句,而且相sql中传递的参数也相同,则会使用缓存。依然以HashMap实现。
需要在总的配置文件中开启
然后在mapper的配置文件中:
size="512" readOnly="true"/>
cache元素用来开启当前mapper的namespace下的二级缓存。有四个属性:
flushInterval:刷新间隔,默认是不设置的,缓存仅在调用语句时刷新
size:缓存数目,默认是1024
readOnly:只读属性,会给所有的调用者返回缓存对象的相同实例,因此这些对象不能被修改,这样性能好。如果是false,可读写的缓存会返回缓存对象的拷贝(通过序列化),慢,却安全,默认是false。
eviction,收回策略,默认是LRU,还有FIFO,SOFT,WEAK等等。
使用二级缓存时,与查询结果映射的Java对象必须实现Serializable接口,如果存在父类,其成员都要实现序列化接口。这是因为二级缓存数据存储介质多种多样,不一定在内存,有可能是硬盘或者远程服务器。
MyBatis的部分,大概就到这里了。第三部分的下,应该会在一个项目实战后给出