- 通过在Map中保存每个已加载过的对象,确保每个对象只加载一次.
- 当要访问对象时,首先检查标识映射,看需要的对象是否已经存在其中.
- 使用Identify来确保不重复加载相同的数据,不仅有助于保证正确性(不会将同一数据加载到两个不同的对象上),还能提升性能.
- 运行机制
- 基本思想:使用一系列映射.这些映射包含了从DB读出的对象.
- 键选择
- 当DB的键只有一列,且不可改变时,最自然的就是DB的主键.
- 通常,一个以简单数据类型的代理主键,可以作为映射的键.
- 显示还是通用.
- 显式的.为每一种需要的对象提供不同的方法.findPerson(1).
- 推荐.
- 强类型有利于编译时检查.
- 显示的接口.
- 但是每增加一个映射就要加入一个方法.
- 通用的.为所有的对象提供统一的方法.find("person",1).
- 易于构造可重复使用的注册表.
- 新增映射时不需要修改它.
- 键的类型也会影响它.如果对象的键类型相同,那么通用型很合适.
- 数量
- 范围:从一个类对应一个映射,到整个会话对应一个映射.
- 对于多映射,一般是每个类或者每个表对应一个映射.
- 当DB方案和对象模型同构时,没有问题.
- 当不同时,基于对象比较容易.因为对象不知道映射的复杂关系.
- 对于继承.多个映射分离使得引入多态变得困难.最好一个继承树一个映射.
- 单映射的优点是新增DB表时,不必增加新的映射.
- 放在那里
- 要确保每个会话都有自己的实例,并独立于其他会话的实例.
- 当正在使用工作单元时,最好放在工作单元上.
- 如果没有,捆绑到会话的注册表中.
- 事务相关
- 通常一个会话子还有一个单一标识映射.否则,就要为映射提供事务保护.
- 两个例外
- 用对象数据库作为事务高速缓存.
- 在所有条件下都是只读的对象.不必担心这些对象在会话期间的共享问题.
- 把只读标识映射放在进程上下文中,把可更新的标识映射放在会话上下文中.
- 使用时机
- 用一个标识映射来管理所有修改了的数据库读出对象.
- 主要是不希望出现两个内存对象对应同一条数据库记录的情形.
- 可作为数据库读取操作的高速缓存.
- 由于不必担心对不变对象的修改异常,所以其用不着标识映射.
- 标识印刷有助于避免同一会话中的更新冲突.但它对超出会话的冲突根本无用.