| 業(yè)務(wù)層設計之六(CompositeEntity) |
| Composite Entity(復合實(shí)體) 問(wèn)題 需用EntityBean實(shí)現業(yè)務(wù)領(lǐng)域概念模型.使用EntityBean實(shí)現業(yè)務(wù)對象會(huì )產(chǎn)生一些問(wèn)題。 1. 需要決定用遠程EntityBean還是本地lEntityBean(EJB1.1不可用)。遠程EntityBean 會(huì )增加網(wǎng)絡(luò )負載。在EJB 2.x 容器中,本地EntityBean與它的客戶(hù)端處于同一JVM中, 這就能進(jìn)一步控制系統性能和網(wǎng)絡(luò )負載.但是與POJO業(yè)務(wù)對象相比,本地EntityBean 還不夠高效,EJB容器還要透明地提供很多優(yōu)化和很多服務(wù),比如安全,事務(wù)等等。 2. 如何實(shí)現EntityBean業(yè)務(wù)對象的持久化存儲??梢杂肅MP, 但是如果有一個(gè)以前遺留 的持久化實(shí)現或者需要實(shí)現某些獨特的需求,就要用BMP了。 3. 業(yè)務(wù)對象的關(guān)系實(shí)現??梢允褂?容器-管理關(guān)系"和"bean-管理關(guān)系"實(shí)現.只有使用了 CMP才能用上CMR, 但CMR還要求所有相互關(guān)聯(lián)的EntityBean都得是本地EntityBean。 動(dòng)機 1. 需要避免遠程entity bean的缺點(diǎn)(比如網(wǎng)絡(luò )負載和遠程的entity bean關(guān)系)。 2. 需要用定制的或者是以前遺留的持久化實(shí)現,完成bean-管理持久化(BMP)。 3. 在使用entity bean實(shí)現業(yè)務(wù)對象時(shí),需要高效地實(shí)現對象之間的父-子關(guān)系。 4. 需要用entity bean封裝并聚合現存的POJO業(yè)務(wù)對象。 5. 需要充分利用EJB容器的事務(wù)管理和安全功能。 6. 需要把數據庫的物理設計對客戶(hù)端封裝起來(lái)。 結構 使用復合實(shí)體,結合本地entity bean和POJO,實(shí)現業(yè)務(wù)對象的持久化。 client ----> CompositeEntity(LocalEntityEJB) ---->DependentBO(entity, POJO) 客戶(hù)端: SessionFacade, AppService etc. 復合實(shí)體: 一般以L(fǎng)ocalEntityBean實(shí)現父業(yè)務(wù)對象,其中還包含從屬對象。 從屬服務(wù)對象: DependentBO依靠父對象管理LifeCycle。從屬對象還可以包含其他從屬 對象。這樣一來(lái),整個(gè)復合實(shí)體中就可能包含一棵對象樹(shù)。從屬對象可以實(shí)現為本地 EntityBean,也可以實(shí)現為POJO(如果使用CMR,從屬對象就只能是本地EntityBean)。 EJB容器: 參見(jiàn)EJB容器如何通過(guò)load,store,activae,passivate方法和EntityBean交互。 示例 Resouce業(yè)務(wù)對象是通過(guò)復合實(shí)體模式實(shí)現的,它與從屬關(guān)系的"一對多"關(guān)系是用集合實(shí)現。 public class ResourceEntityBean implement EntityBean { public String employeeId; public String lastName; public String firstName; public String departmentId; // BlockOutTime(缺勤時(shí)間集)從屬對象的集合。 public Collection blockOutTimes; // SkillSet(技能集)從屬對象的集合 public Collection skillSets; private EntityContext context; public String ejbCreate(ResourceTO resource) throws CreatException { try { this.employeeId = resource.employId; setResourceData(resource); getResourceDAO().create(resource); } catch (Exception e) { throw new EJBException("Reason:"+.......); } return this.employeeId; } public String ejbFindByPrimaryKey(String primaryKey) throws FinderException { // return getResourceDAO().findResource(primaryKey); } public void ejbRemove() { // 刪除從屬對象 // getSkillSetDAO().deleteAll(employId); // skillSets = null; // getBlockOutTimeDAO().deleteAll(employId); // blockOutTimes = null; // 從持久化存儲中刪除資源 //resourceDAO.delete(employeeId); } public void setEntityContext(EntityContext context) { this.context = context; } public void unsetEntityContext() { context = null; } public void ejbActivate() { employeeId = (String)context.getPrimaryKey(); } public void ejbPassivate() { employeeId = null; } public void ejbLoad() { // 裝載資源 ResourceDAO resourceDAO = getResourceDAO(); setResourceData((ResourceTO)resourceDAO.findResource(employeeId)); // 如果必要,裝載其他從屬對象 } public void ejbStore() { // 存儲資源信息 getResourceDAO().update(getResourceData()); // 如果必要,保存其他從屬對象 } public void ejbPostCreate(ResourceTO resource) {} public ResourceTO getResourceTO() { ResourceTO resourceTO = new ResourceTO(employeeId); resourceTO.lastName = lastName; resourceTO.firstName = firstName; resourceTO.departmentId = departmentId; .......... return resourceTO; } public void setResourceData(ResourceTO resourceTO) { employeeId = resourceTO.employeeId; lastName = resourceTO.lastName; ........... } public Collection getBlockOutTimesData() { return blockOutTimes; } public Collection getSkillSetsData() { return skillSets; } public void addBlockOutTimes(Collection moreBOTs) { // 注意: moreBOTs是BlockOutTimeTO對象的 // moreBOTs.iterator(); blockOutTimes.add((BlockOutTimeTO)iter.next()); } public void addSkillSet(Collection moreSkills) { //同上 } public void updateBlockOutTime(Collection updBOTs) { Iterator botIter = blockOutTimes.iterator(); Iterator updIter = updBOTs.iterator(); while (updIter.hasNext()) { BlockOutTimeTO botTO = (BlockOutTimeTO) updIter.next(); while (botIter.hasNext()) { BlockOutTimeTO existBOT = (BlockOutTimeTO) botIter.next(); if (existBOT.equals(botTO)) { botTO.setDirty(); // 修改過(guò)的舊從屬對象 botTO.resetNew(); // 不是一個(gè)新的從屬對象了 existBOT = botTO; } } } } pubic void updateSkillSet(Collection updSkills) { // 同上 } } |
聯(lián)系客服