工作单元模式
工作单元的定义是:维护一个受业务事务影响的对象列表,并协调写入更改内容和并发问题的解决方案。
一个业务事务中,可能需要多次修改对象模型,对象模型的修改需要记录到数据库中,当然可以每次对象模型有修改时就将变化记录到数据库中,但是这会产生很多对数据库的调用。而使用工作单元来记录业务事务中对数据库有影响的所有变化,就可以减少对数据库的大量小规模调用。
很显然对象模型的变化,工作单元都必须知道并且记录。所以一旦有变化产生都必须通知工作单元,有三种方式来实现:
1. 调用者注册:
一旦调用者修改了某个对象,就必须向工作单元注册这个修改。
先写一个工作单元接口
package test.hella.unitwork; public interface IUnitOfWork{ void registerAdded(Object entity); void registerChanged(Object entity); void registerRemoved(Object entity); void commit(); }
然后是接口实现:
package test.hella.unitwork; import java.util.ArrayList; import java.util.List; public class UnitOfWork implements IUnitOfWork { private List<Object> newObjects = new ArrayList<Object>(); private List<Object> dirtyObjects = new ArrayList<Object>(); private List<Object> removedObjects = new ArrayList<Object>(); public void registerAdded(Object entity) { newObjects.add(entity); } public void registerChanged(Object entity) { dirtyObjects.add(entity); } public void registerRemoved(Object entity) { removedObjects.add(entity); } public void commit() { insertNew(); updateDirty(); deleteRemoved(); } private void insertNew() { for (Object newObj : newObjects) { //DO insert } } private void updateDirty() { for (Object dirtyObj : dirtyObjects) { //DO update } } private void deleteRemoved() { for (Object removedObj : removedObjects) { //DO delete } } }
调用着的调用方式:
package test.hella.unitwork; public class UnitOfWorkTest { private static final UserRepository userRepository = new UserRepository(); public static void main(String[] args) { User user1 = new User(1,"user1"); IUnitOfWork unitOfWork = new UnitOfWork(); unitOfWork.registerRemoved(user1); User user2 = userRepository.getUser(2); user2.changeName("user2Changed"); unitOfWork.registerChanged(user2); User user3 = userRepository.getUser(3); unitOfWork.registerRemoved(user3); unitOfWork.commit(); } }
2. 对象注册:
对象注册的方式,调用者无需负责注册,注册方法被置于对象方法中。
还以上面的代码距离,此时User对象需要负责注册:
package test.hella.unitwork; public class User { private final long id; private String name; public long getId() { return id; } public User(long id, String name) { this.id = id; this.name = name; } public void changeName(String name, IUnitOfWork unitOfWork) { this.name = name; unitOfWork.registerChanged(this); } }
调用者无需再向工作单元进行注册。很明显看到上例中需要将工作单元传递给User对象,这种传递显得不够简洁,更好的方式是将工作单元放到一个众所周知的地方来解决这个问题,比如java的ThreadLocal。
package test.hella.unitwork; import java.util.ArrayList; import java.util.List; public class UnitOfWork implements IUnitOfWork { private List<Object> newObjects = new ArrayList<Object>(); private List<Object> dirtyObjects = new ArrayList<Object>(); private List<Object> removedObjects = new ArrayList<Object>(); private static ThreadLocal current = new ThreadLocal<UnitOfWork>(); public static void newCurrent() { setCurrent(new UnitOfWork()); } public static void setCurrent(UnitOfWork now) { current.set(now); } public static UnitOfWork getCurrent() { return (UnitOfWork) current.get(); } public void registerAdded(Object entity) { newObjects.add(entity); } public void registerChanged(Object entity) { dirtyObjects.add(entity); } public void registerRemoved(Object entity) { removedObjects.add(entity); } public void commit() { insertNew(); updateDirty(); deleteRemoved(); } private void insertNew() { for (Object newObj : newObjects) { //DO insert } } private void updateDirty() { for (Object dirtyObj : dirtyObjects) { //DO update } } private void deleteRemoved() { for (Object removedObj : removedObjects) { //DO delete } } }
3. 工作单元控制器:
这种方式调用者和DomainObject都无需小心翼翼的记得向工作单元注册变化。工作单元控制所有的数据读取,读取数据之后会产生一个拷贝,提交时按照对象的唯一标识和拷贝的对象进行对比,如果有变化则更新数据库中的数据。
相关推荐
源码zanqunet 2020-10-28
theowl 2020-08-18
qiximiao 2020-08-03
风萧萧梦潇 2020-07-28
Andrewjdw 2020-07-26
huakai 2020-07-26
XCMercy 2020-07-19
georgeandgeorge 2020-07-19
Jonderwu 2020-07-19
源码物语 2020-07-18
XGQ 2020-06-21
aNian 2020-06-16
郴州小程序 2020-06-13
园搬家测试账号 2020-06-12
Wonder的学习 2020-06-08
小方哥哥 2020-06-07
LULUBAO 2020-06-05
学习备忘录 2020-06-03
RocNg 2020-06-01