package jef.database.meta; import javax.persistence.CascadeType; import javax.persistence.FetchType; import jef.database.annotation.Cascade; import jef.tools.ArrayUtils; import jef.tools.Assert; import jef.tools.reflect.Property; /** * 描述一个级联引用关系 * * @author jiyi * */ public abstract class AbstractRefField implements ISelectProvider { /** * 引用外部表的Field名称 */ protected Reference reference; /** * 是否延迟加载 */ protected FetchType fetch; // 延迟加载特性 /** * 数据类型 */ private Class<?> sourceFieldType; /** * 访问属性 */ private Property field; private Cascade cascadeInfo; /** * 优先级。默认大家都是0 */ private int priority; public AbstractRefField(Property fieldAccessor, Reference ref, CascadeConfig config) { Assert.notNull(fieldAccessor); this.field = fieldAccessor; this.reference = ref; this.sourceFieldType = fieldAccessor.getType(); this.cascadeInfo = config.getAsMap(); setCascade(config.getCascade()); this.fetch = config.getFetch(); } private boolean canInsert; private boolean canDelete; private boolean canUpdate; private boolean canSelect; // 设置时就将用途计算好,避免使用时去循环判断 private void setCascade(CascadeType[] cascades) { // 形成默认值 if (cascades.length == 0 || ArrayUtils.fastContains(cascades, CascadeType.ALL)) { canInsert = true; canDelete = true; canUpdate = true; canSelect = true; } else { canInsert = false; canDelete = false; canUpdate = false; canSelect = false; } //分别计算 for (CascadeType cascade : cascades) { switch (cascade) { case DETACH: canSelect = true; canUpdate = true; break; case PERSIST: canInsert = true; break; case MERGE: canInsert = true; canUpdate = true; break; case REFRESH: canSelect = true; case REMOVE: canDelete = true; case ALL: default: } } // 如果是单列引用,那么仅用于查询 if (this.isSingleColumn()) { canInsert = false; canDelete = false; canUpdate = false; } } public String getName() { return field.getName(); } public Reference getReference() { return reference; } public void setReference(Reference reference) { this.reference = reference; } public String toString() { return this.reference.getThisType().getName()+"."+field.getName(); } public FetchType getFetch() { return fetch; } public int getProjection() { return 0; } public abstract ISelectProvider toNestedDesc(String lastName); public abstract boolean isSingleColumn(); public boolean isToOne() { return reference.getType().isToOne(); } public boolean canSelect() { return canSelect; } public boolean canDelete() { return canDelete; } public boolean canUpdate() { return canUpdate; } public boolean canInsert() { return canInsert; } public Cascade getCascadeInfo() { return cascadeInfo; } public void setCascadeInfo(Cascade cascadeInfo) { this.cascadeInfo = cascadeInfo; } public Property getField() { return field; } /** * @return sourceFieldType * @see #sourceFieldType */ public Class<?> getSourceFieldType() { return sourceFieldType; } public void setSourceFieldType(Class<?> sourceFieldType) { this.sourceFieldType = sourceFieldType; } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } }