天天看點

NC6 根據視圖主鍵查詢視圖VO的工具類和更新視圖VO中的某些屬性值到資料庫中的工具類

1、根據視圖主鍵查詢視圖VO的工具類

package nc.impl.pubapp.pattern.data.view;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import nc.impl.pubapp.pattern.data.vo.VOQuery;
import nc.vo.pub.IAttributeMeta;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.IVOMeta;
import nc.vo.pubapp.pattern.model.entity.view.IDataView;
import nc.vo.pubapp.pattern.model.meta.entity.view.IDataViewMeta;
import nc.vo.pubapp.pattern.pub.Constructor;
import nc.vo.pubapp.pattern.pub.MapList;

/**
 * 根據視圖主鍵查詢視圖VO的工具類。
 * <ol>
 * <li>不需要拼寫要查詢的資料庫字段和資料庫表以及表之間的連接配接條件,因為這些資訊在視圖中繼資料中已經定義
 * <li>查詢視圖VO中繼資料定義的全部屬性
 * <li>當視圖主鍵個數超過系統規定的門檻值時,會使用臨時表來構造查詢sql。是以,此種查詢必須置于有事務的調用中
 * <li>由于視圖VO可以由多個實體VO組成。它先查詢主實體VO,再根據視圖中繼資料的定義,查詢其他關聯的實體VO。這樣,
 * 一個由多個實體VO組成的視圖VO的裝載可能包含多條sql語句。
 * <li>由于被關聯的實體VO可能具有共享性。是以,通過設定共享實體VO可以隻加載一次相同的實體VO。這樣可以節省記憶體。
 * 但是這種方式隻能用于視圖VO隻讀的場景下。否則會産生資料錯誤。<br>
 * <b>使用場景舉例:</b>在查詢主子表組成的視圖VO時,可以設定表頭實體VO共享,則表頭的實體VO隻會在記憶體中存儲一份
 * </ol>
 * 
 * @param <E> 視圖類型
 * @since 6.0
 * @see EfficientViewQuery
 * @see IDataView
 */
public class ViewQuery<E extends IDataView> {

	/**
	 * 表頭VO的執行個體是否共享
	 */
	private boolean sharedHead = true;

	/**
	 * 視圖類型Class
	 */
	private Class<E> viewClazz;

	/**
	 * 視圖中繼資料
	 */
	private IDataViewMeta viewMeta;

	/**
	 * 視圖查詢構造方法
	 * 
	 * @param clazz 視圖類型Class
	 */
	public ViewQuery(Class<E> clazz) {
		this.viewClazz = clazz;
		IDataView instance = Constructor.construct(clazz);
		this.viewMeta = instance.getMetaData();
	}

	/**
	 * 視圖主實體之外的其他連接配接實體是否在記憶體總共享同一對象
	 * 
	 * @return 連接配接實體共享同一對象時傳回真
	 */
	public boolean isSharedHead() {
		return this.sharedHead;
	}

	/**
	 * 根據主鍵查詢視圖
	 * 
	 * @param ids 視圖主鍵
	 * @return 查詢出來的視圖
	 */
	public E[] query(String[] ids) {
		int length = ids.length;
		if (length == 0) {
			return this.construct(0);
		}
		E[] views = this.queryMainVO(ids, this.viewMeta);
		IVOMeta left = this.viewMeta.getMainVOMeta();
		this.setRelationVO(views, this.viewMeta, left);
		return views;
	}

	/**
	 * 根據主鍵查詢視圖--主表左連接配接擴充表查詢
	 * 
	 * @param ids 視圖主鍵
	 * @return 查詢出來的視圖
	 */
	public E[] queryByLeftJoin(String[] ids) {
		int length = ids.length;
		if (length == 0) {
			return this.construct(0);
		}
		E[] views = this.queryMainVO(ids, this.viewMeta);
		IVOMeta left = this.viewMeta.getMainVOMeta();
		this.setRelationVOByLeftJoin(views, this.viewMeta, left);
		return views;
	}

	/**
	 * 設定視圖主實體之外的其他連接配接實體是否在記憶體總是否共享同一對象
	 * 
	 * @param sharedHead 是否共享同一實體對象
	 */
	public void setSharedHead(boolean sharedHead) {
		this.sharedHead = sharedHead;
	}

	private E[] construct(int size) {
		E[] views = Constructor.construct(this.viewClazz, size);
		return views;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private ISuperVO[] query(String[] ids, IDataViewMeta meta, IVOMeta voMeta) {
		Class<? extends ISuperVO> clazz = meta.getVOClass(voMeta);
		Set<String> set = meta.getAttributeNames(voMeta);
		List<String> list = new ArrayList<String>();
		for (String name : set) {
			IAttributeMeta attribute = voMeta.getAttribute(name);
			if (attribute.isPersistence()) {
				list.add(attribute.getName());
			}
		}
		int size = list.size();
		String[] names = new String[size];
		names = list.toArray(names);

		VOQuery query = new VOQuery(clazz, names);
		ISuperVO[] vos = query.query(ids);
		return vos;
	}

	private ISuperVO[] queryByLeftJoin(String[] ids, IDataViewMeta meta, IVOMeta voMeta) {
		Class<? extends ISuperVO> clazz = meta.getVOClass(voMeta);
		Set<String> set = meta.getAttributeNames(voMeta);
		List<String> list = new ArrayList<String>();
		for (String name : set) {
			IAttributeMeta attribute = voMeta.getAttribute(name);
			if (attribute.isPersistence()) {
				list.add(attribute.getName());
			}
		}
		int size = list.size();
		String[] names = new String[size];
		names = list.toArray(names);

		VOQuery query = new VOQuery(clazz, names);
		ISuperVO[] vos = query.queryByLeftJoin(ids);
		return vos;
	}

	private E[] queryMainVO(String[] ids, IDataViewMeta meta) {
		IVOMeta left = meta.getMainVOMeta();
		ISuperVO[] vos = this.query(ids, meta, left);

		int size = vos.length;
		E[] views = this.construct(size);

		for (int i = 0; i < size; i++) {
			views[i].setVO(vos[i]);
		}
		return views;
	}

	private void setRelationVO(E[] views, IDataViewMeta meta, IVOMeta left) {
		IVOMeta[] rights = this.viewMeta.getRelationVOMetas(left);
		if ((rights == null) || (rights.length == 0)) {
			return;
		}
		for (IVOMeta right : rights) {
			this.setRelationVO(views, this.viewMeta, left, right);
			this.setRelationVO(views, meta, right);
		}
	}

	private void setRelationVO(E[] views, IDataViewMeta meta, IVOMeta left, IVOMeta right) {
		IAttributeMeta leftAttribute = meta.getRelationStartAttribute(left, right);
		IAttributeMeta rightAttribute = meta.getRelationEndAttribute(left, right);

		MapList<String, E> index = new MapList<String, E>();
		Set<String> set = new HashSet<String>();
		for (E view : views) {
			String id = (String) view.getAttributeValue(leftAttribute.getName());
			set.add(id);
			index.put(id, view);
		}
		int size = set.size();
		if (size == 0) {
			return;
		}
		String[] ids = new String[size];
		ids = set.toArray(ids);
		ISuperVO[] vos = this.query(ids, meta, right);
		for (ISuperVO vo : vos) {
			String id = (String) vo.getAttributeValue(rightAttribute.getName());
			List<E> list = index.get(id);
			for (E view : list) {
				if (!this.sharedHead) {
					view.setVO((ISuperVO) vo.clone());
				} else {
					view.setVO(vo);
				}
			}
		}
	}

	private void setRelationVOByLeftJoin(E[] views, IDataViewMeta meta, IVOMeta left) {
		IVOMeta[] rights = this.viewMeta.getRelationVOMetas(left);
		if ((rights == null) || (rights.length == 0)) {
			return;
		}
		for (IVOMeta right : rights) {
			this.setRelationVOByLeftJoin(views, this.viewMeta, left, right);
			this.setRelationVOByLeftJoin(views, meta, right);
		}
	}

	private void setRelationVOByLeftJoin(E[] views, IDataViewMeta meta, IVOMeta left, IVOMeta right) {
		IAttributeMeta leftAttribute = meta.getRelationStartAttribute(left, right);
		IAttributeMeta rightAttribute = meta.getRelationEndAttribute(left, right);

		MapList<String, E> index = new MapList<String, E>();
		Set<String> set = new HashSet<String>();
		for (E view : views) {
			String id = (String) view.getAttributeValue(leftAttribute.getName());
			set.add(id);
			index.put(id, view);
		}
		int size = set.size();
		if (size == 0) {
			return;
		}
		String[] ids = new String[size];
		ids = set.toArray(ids);
		ISuperVO[] vos = this.queryByLeftJoin(ids, meta, right);
		for (ISuperVO vo : vos) {
			String id = (String) vo.getAttributeValue(rightAttribute.getName());
			List<E> list = index.get(id);
			for (E view : list) {
				if (!this.sharedHead) {
					view.setVO((ISuperVO) vo.clone());
				} else {
					view.setVO(vo);
				}
			}
		}
	}
}

           

使用:nc.bs.sc.m61.referred.SCOrdReffredUtil 類的 querySCOrdVO(String sql) 方法

public static SCOrderVO[] querySCOrdVO(String sql) {

DataAccessUtils dau = new DataAccessUtils();

IRowSet rs = dau.query(sql);

if (rs.size() == 0) {

return null;

}

String[] bids = rs.toOneDimensionStringArray();

ViewQuery vq = new ViewQuery(SCOrderViewVO.class);

SCOrderViewVO[] views = vq.query(bids);

CombineViewToAggUtil combUtil = new CombineViewToAggUtil(SCOrderVO.class,

SCOrderHeaderVO.class, SCOrderItemVO.class);

SCOrderVO[] vos = combUtil.combineViewToAgg(views, SCOrderHeaderVO.PK_ORDER);

return vos;

}

2、更新視圖VO中的某些屬性值到資料庫中的工具類

package nc.impl.pubapp.pattern.data.view;

import java.util.ArrayList;
import java.util.List;

import nc.impl.pubapp.pattern.data.vo.VOUpdate;
import nc.vo.pub.ISuperVO;
import nc.vo.pubapp.pattern.model.entity.view.IDataView;
import nc.vo.pubapp.pattern.pub.ListToArrayTool;

/**
 * 更新視圖VO中的某些屬性值到資料庫中
 * 
 * @param <E> 視圖類型
 * @since 6.0
 */
public class ViewUpdate<E extends IDataView> {

	/**
	 * 對視圖中指定的實體類型更新指定的實體屬性到資料庫中
	 * 
	 * @param views 要更新的視圖
	 * @param clazz 要更新的實體類型Class
	 * @param names 要更新的實體的屬性名稱
	 * @return 更新後的視圖
	 */
	public E[] update(E[] views, Class<? extends ISuperVO> clazz, String[] names) {
		List<ISuperVO> list = new ArrayList<ISuperVO>();
		for (E view : views) {
			list.add(view.getVO(clazz));
		}
		int size = list.size();
		if (size == 0) {
			return views;
		}
		ListToArrayTool<ISuperVO> tool = new ListToArrayTool<ISuperVO>();
		ISuperVO[] vos = tool.convertToArray(list);
		VOUpdate<ISuperVO> bo = new VOUpdate<ISuperVO>();
		bo.update(vos, names);

		return views;
	}
}

           

例如:

public SCOrderVO[] open(SCOrderVO[] vos) throws BusinessException {

CompareAroundProcesser processer = new CompareAroundProcesser(SCOrderPluginPoint.OPEN_ACT);

// 查詢聯副參數

List bids = new ArrayList();

for (SCOrderVO scOrderVO : vos) {

SCOrderItemVO[] items = scOrderVO.getChildrenVO();

for (SCOrderItemVO scOrderItemVO : items) {

scOrderItemVO.setClosetime(null);

scOrderItemVO.setCloser(null);

scOrderItemVO.setBclose(UFBoolean.FALSE);

scOrderItemVO.setClosereason(null);

scOrderItemVO.setDr(Integer.valueOf(0));

bids.add(scOrderItemVO.getPk_order_b());

}

}

// 關聯打開聯副産品

SCOrderVO[] newOrderVos = this.getVOWithGrand(vos, bids.toArray(new String[bids.size()]));

ViewUpdate< SCOrderCloseVO> bo = new ViewUpdate< SCOrderCloseVO>();

BillToViewConvertor<SCOrderVO, SCOrderCloseVO> btv = new BillToViewConvertor<SCOrderVO, SCOrderCloseVO>(SCOrderCloseVO.class);

String[] names = new String[] { SCOrderItemVO.BCLOSE, SCOrderItemVO.CLOSER, SCOrderItemVO.CLOSEREASON, SCOrderItemVO.CLOSETIME };

this.addBeforeRule(processer);

this.addAfterRule(processer);

SCOrderCloseVO[] scCloseVO = btv.convert(vos);

SCOrderCloseVO[] newSCCloseVO = btv.convert(newOrderVos);

processer.before(newOrderVos, newOrderVos);

bo.update(newSCCloseVO, SCOrderItemVO.class, names);

processer.after(newOrderVos, newOrderVos);

return SCOrderCloseVO.getSCOrderVO(scCloseVO);

}

nc

繼續閱讀