Eva
Java粉絲募集中
  • 簡介
  • 我們的優勢
  • 最新消息
  • 下載與使用
  • 範例與說明
    • Eva Objects >
      • Bean類別定義
      • Entity型別定義
      • Struct型別定義
      • 建立Entity空白物件
      • 建立Entity修改物件
      • 建立Entity條件物件
      • 建立Struct值物件
    • Eva_ORM >
      • ORM程式主體
      • 使用條件物件執行操作
      • 執行更複雜條件的操作.
      • 分頁取回資料
      • 操作JDBC的參數
      • Array Property的操作
      • Collection Property的操作
      • 更複雜的Collection Property
      • 指定表格名稱
      • 新增資料庫Dialect
    • Eva_IOC >
      • IOC程式主體
      • AOP應用
    • Eva_Struct >
      • Struct範例
      • Bit Strcut範例
      • 指標範例
      • 於Eva_ORM中使用
    • Eva_Sort >
      • 依指定Properties排序
      • 部份排序
      • 優先排序部份
    • Eva_Cache >
      • hashing-based cache
      • 非hashing-based cache
  • API列表
  • 技術支援
    • 協助開發
  • 相關書籍

自訂Colleciton型別.

在下面, 我們簡單地示範了, 如何在 Eva_ORM 中自行新增一個 Collection 類別. Eva_ORM 對於 Collection 使用的設計是, 使用者只是直覺地操作所熟悉的 Collection, 而操作的同時, 那些 Eva_ORM 所提供的 Collection 物件會去操作資料庫的資料, 當使用者新增或刪除 Collection 內的資料的同時, 該 Collection 物件也會去對資料庫下相同的指令. 因此, 使用者至少需準備下列類別. 
  1. 自訂的Collection類別.
  2. 儲存資料的 Entity 類別.
  3. 讓使用者做操作, 而同時操作資料庫資料的 Collection 類別.
  4. 註冊自訂 Collection 類別的 Converter 類別.

下面的範例中, 首先看到的是自訂的Collection型別MySet, 它是在Entity中可被使用的Property型別, 接著看到的是 MySetEntity, 它是用於儲存 MySet這個Collection 資料的 Entity 類別, 但與使用者直接使用的 Entity 類別不同的是, 在 Entity 的標記中的 collection, key, name 三個設定. key 與 name 是用於設定 Entity 所對映的資料表名稱. 因為 Collection 可以在其它 Entity 類別中被重覆使用, 所以其資料表的命名應隨著參考它的 Entity 類別所改變, 我們必需讓它以不同於 Entity 預設命名規則的方式被命名.

接著是被使用者操作的類別 MySetImp, 它繼承自 AbstractCollectionImp 類別, 同時在使用者操作自己時, 也同時去操作資料庫. 例如 Add 方法的例子, MySetImp 會先讀取本身的 cache, 若己有資料會回傳加入物件失敗, 若沒有資料則會將物件加入 cache, 並回傳新增資料庫成功與否. 這邊使用者可以看出 Eva_ORM 回傳值的策略, 若是回傳成功與否的 boolean 值, 則只有在本地與資料庫端都執行成功才會回傳成功, 反之回傳失敗.

最後是 SetAccessor 類別, 它繼承自 AbstractCollectionConverter, 並實作它所要求提供的一些方法. 之後使用者只需在建立 ORMappers 物件時也透過ConverterUtil這個類別的方法, 做了這個 SetAccessor 類別的註冊, 就能在 Entity 的定義中使用相關的 Collection 類別了.

但是 Eva_ORM 所預設所提供的 Collection 類別還有另外一個特性, 是在建立 Collection 時一律會先回傳一個 Proxy 物件, 而在 Proxy 物件被存取時才真正地向資料庫查詢資料. 但 Proxy 物件的設計超出本範例所應提供的內容, 使用者需另行思考這一部份.

package collection;

import java.util.Set;

import com.logntw.eva.anno.orm.UserDefinedCollection;

@UserDefinedCollection(entityClz=MySetEntity.class)
public interface MySet<T> extends Set<T>
{
  
}
package collection;

import com.logntw.eva.anno.orm.Column;
import com.logntw.eva.anno.orm.Entity;
import com.logntw.eva.anno.orm.Id;
import com.logntw.eva.orm.mapping.NamingSetting;
  
@Entity(collection=true, key=NamingSetting.DEFAULT_COLLECTION_KEY, name=NamingSetting.DEFAULT_COLLECTION_NAME)
public interface MySetEntity
{
  @Id    
  @Column(nullable=false)
  T getVal();
  void setVal(T value);  
}
package collection;

import com.logntw.eva.anno.orm.Column;
import com.logntw.eva.anno.orm.Entity;
import com.logntw.eva.anno.orm.Id;
import com.logntw.eva.orm.mapping.NamingSetting;
  
@Entity(collection=true, key=NamingSetting.DEFAULT_COLLECTION_KEY, name=NamingSetting.DEFAULT_COLLECTION_NAME)
public interface MySetEntity<T>
{
  @Id    
  @Column(nullable=false)
  T getVal();
  void setVal(T value);  
}
package collection;

import java.util.Collection;
import java.util.Iterator;

import com.logntw.eva.cdm.collection.AbstractCollectionImp;
import com.logntw.eva.cdm.element.EntityIterator;
import com.logntw.eva.orm.CollectionMapper;

public class MySetImp<E> extends AbstractCollectionImp<MySet<E>, MySetEntity<E>> implements MySet<E>
{
  private final MySet<E> set;
  private final CollectionMapper<MySetEntity<E>> mapper;
  public MySetImp(CollectionMapper<MySetEntity<E>> mapper, Object owner, MySet<E> set)
  {
    super(owner);
    if(mapper == null || set == null)
      throw new java.lang.IllegalArgumentException();
    this.mapper = mapper;
    this.set = set;
  }
  
  @Override
  public Object collection()
  {    
    return set;
  }

  @Override
  public CollectionMapper mapper()
  {    
    return mapper;
  }
  
  @Override
  public MySetEntity<E> entity(Object member)
  {
    MySetEntity<E> entity = mapper.newObject();      
    entity.setVal((E)member);
    return entity;
  }
  
  @Override
  public boolean add(E e)
  {
    boolean rtn = set.add(e);
    if(rtn)
    {
      MySetEntity<E> entity = mapper.newObject();      
      entity.setVal(e);
      return mapper.insert(this, entity);
    }
    return rtn;
  }

  private static final class MySetEntityIterator<E> extends EntityIterator<E, MySetEntity<E>>
  {    
    private final MySetEntity<E> entity;
    public MySetEntityIterator(Iterable<? extends E> iterable, MySetEntity<E> entity)
    {
      super(iterable);
      this.entity = entity;
    }

    @Override
    protected MySetEntity<E> toEntity(E e)
    {
      entity.setVal(e);
      return entity;
    }
  }

  @Override
  public boolean addAll(Collection<? extends E> c)
  {  
    boolean rtn = set.addAll(c);
    if(rtn)
    {
      Iterable<MySetEntity<E>> iterable = new MySetEntityIterator<E>(c, mapper.newObject());
      return allTrue(mapper.insert(this, iterable));
    }
    return rtn;
  }
  
  @Override
  public void clear()
  {
    set.clear();
    mapper.deleteAll(this);
  }

  @Override
  public boolean contains(Object o)
  {
    return set.contains(o);    
  }

  @Override
  public boolean containsAll(Collection<?> c)
  {
    return set.containsAll(c);
  }

  @Override
  public boolean isEmpty()
  {
    return set.isEmpty();
  }

  @Override
  public Iterator<E> iterator()
  {
    return set.iterator();
  }

  @Override
  public boolean remove(Object o)
  {
    boolean rtn = set.remove(o);
    if(rtn)
    {
      MySetEntity<E> entity = mapper.newObject();      
      entity.setVal((E)o);
      return mapper.delete(this, true, entity);
    }
    return rtn;
  }

  @Override
  public boolean removeAll(Collection<?> c)
  {
    boolean rtn = set.removeAll(c);
    if(rtn)
    {
      Iterable<MySetEntity<E>> iterable = new MySetEntityIterator<E>((Collection<E>)c, mapper.newObject());
      return allTrue(mapper.delete(this, true, iterable));
    }
    return rtn;
  }

  @Override
  public boolean retainAll(Collection<?> c)
  {
    throw new java.lang.UnsupportedOperationException();  
  }
  
  @Override
  public int size()
  {
    return set.size();
  }

  @Override
  public Object[] toArray()
  {
    return set.toArray();
  }

  @Override
  public <T> T[] toArray(T[] a)
  {
    return set.toArray(a);
  }
  
  @Override
  public void eagerToGetCollection()
  {
  // do nothing.  
  }
  
  @Override
  public boolean hasCollectionElement()
  {
  return false;
  }
  
  @Override
  public String toString()
  {
    return set.toString();
  }
}
package collection;

import java.util.HashSet;

import com.logntw.eva.bean.condition.ConditionObj;
import com.logntw.eva.cdm.AbstractCollectionConverter;
import com.logntw.eva.cdm.element.ElementIterator;
import com.logntw.eva.condition.OP;
import com.logntw.eva.orm.CollectionMapper;
import com.logntw.eva.orm.EagerToGet;
import com.logntw.eva.sql.SelectOption;

public class MySetAccessor extends AbstractCollectionConverter<MySet, MySetEntity>
{
  public final static MySetAccessor INSTANCE = new MySetAccessor();
  @Override
  public Class<MySetEntity> entityType()
  {
    return MySetEntity.class;
  }

  @Override
  public boolean insert(CollectionMapper<MySetEntity> mapper, Object owner, Object element)
  {      
    MySetEntity entity = mapper.newObject();    
    entity.setVal(element);
    return mapper.insert(owner, entity);
  }
  
  
  @Override
  public boolean delete(CollectionMapper<MySetEntity> mapper, Object owner, Object element)
  {
    MySetEntity entity = mapper.newObject();
    entity.setVal(element);
    return mapper.delete(owner, true, entity);  
  }
  
  private static class MyHashSet<T> extends HashSet<T> implements MySet<T>
  {
    
  }
  
  @Override
  public MySet createCollection(CollectionMapper<MySetEntity> mapper, Object owner)
  {
    MySet rtn = new MySetImp(mapper, owner, new MyHashSet());
    return rtn;
  }
  
  @Override
  public MySet select(CollectionMapper<MySetEntity> mapper, Object owner, final boolean byKey, final EagerToGet eager, final ConditionObj condition,
      final SelectOption option)
  {
    MySet set = new MyHashSet();
    MySetImp rtn = new MySetImp(mapper, owner, set);
    ConditionObj<MySetEntity> cobj = mapper.newCondition();
    cobj.If(OP.THAT).setVal(condition);      
    ElementIterator<MySetEntity> iterator = mapper.select(owner, byKey, eager, cobj, option);
    try
    {
      for(MySetEntity entity : iterator)              
        set.add(entity.getVal());
    }
    finally
    {
      iterator.dispose();
    }
    return rtn;
  }

  @Override
  public MySet selectAll(CollectionMapper<MySetEntity> mapper, Object owner, final EagerToGet eager, final SelectOption option)
  {    
    MySet set = new MyHashSet();
    MySetImp rtn = new MySetImp(mapper, owner, set);
    ElementIterator<MySetEntity> iterator = mapper.selectAll(owner, false, eager, option);
    try
    {
      for(MySetEntity entity : iterator)              
        set.add(entity.getVal());
    }
    finally
    {
      iterator.dispose();
    }
    return rtn;
  }

  @Override
  public int count(CollectionMapper<MySetEntity> mapper, Object owner, boolean byKey, ConditionObj condition)
  {
    ConditionObj<MySetEntity> cobj = mapper.newCondition();
    cobj.If(OP.THAT).setVal(condition);
    return mapper.count(owner, byKey, cobj);
  }
}
Powered by Create your own unique website with customizable templates.