Java中的通用存储库
假设我有一门课:Java中的通用存储库,java,android,generics,dry,Java,Android,Generics,Dry,假设我有一门课: public class PhotoRepository { private PhotoDao db; PhotoRepository(PhotoDao dao) { db = dao; } public void save(List<Photo> photos) { db.insertOrReplaceInTx(photos); } public List<Photo> all() { r
public class PhotoRepository {
private PhotoDao db;
PhotoRepository(PhotoDao dao) {
db = dao;
}
public void save(List<Photo> photos) { db.insertOrReplaceInTx(photos); }
public List<Photo> all() { return db.loadAll(); }
public Photo get(Long id) { return db.load(id); }
}
公共级光电沉积{
私有数据库;
光电沉积{
db=dao;
}
public void save(列出照片){db.insertoreplaceintx(照片);}
public List all(){return db.loadAll();}
公共照片获取(长id){return db.load(id);}
}
因为我有更多种类的实体,而不仅仅是照片,所以我希望有一个通用的存储库,在那里我可以传递任何种类的Dao
我曾尝试使用Class>
作为构造函数的参数,但编译器说de-dao方法无法解析。大致如下:
public class Repository<T> {
private Class<? extends AbstractDao<T, ?>> db;
Repository(Class<? extends AbstractDao<T, ?>> dao) {
db = dao;
}
public void save(List<T> items) { db.insertOrReplaceInTx(items); }
public List<T> all() { return db.loadAll(); }
public T get(Long id) { return db.load(id); }
}
公共类存储库{
私有类>数据库;
存储库(类>dao){
db=dao;
}
public void save(列表项){db.insertoreplaceintx(项);}
public List all(){return db.loadAll();}
公共T get(长id){return db.load(id);}
}
我试过使用类型参数,也试过不使用类型参数,还有其他几种排列,但运气不佳。
有没有一种在Java中实现这一点的方法
谢谢。您必须为
存储库
类引入第二个类型参数,它将表示dao,因为类>
不正确
让我们调用第二个类型参数D
。它必须始终是AbstractDao
的子类,由您要使用的对象类型(即T
类型)参数化
注意,我假设PhotoDao
定义为:
class PhotoDao extends AbstractDao<Photo> { .. }
class PhotoDao扩展了AbstractDao{..}
但这不是decorator模式AbstractDao
的第二个类型参数是什么?@kocko它通常很长,尽管我见过在GreenDao源代码中使用“?”。@bigdestroyer为什么?当前的方法只是现有方法的较短名称,但没有什么能阻止我调用多个方法或在其中执行额外的操作。@haraldK即使这是一个存储库,一般来说,它不是一个装饰器吗?太好了!这实际上允许我实例化存储库,忽略类型参数:repo=newrepository(daoSession.getPhotoDao())代码>如何在此处访问D的内部类属性?在我的原始代码中,我有这样一个:publicquerybuilder QueryBuilder(){returndb.QueryBuilder().orderDesc(VideoDao.Properties.Created_at).limit(10);}
虽然这是有效的,但不要这样做,因为这样可以将repo
的类型变成原始类型,这降低了泛型的优点,应该避免D
的内部类属性,您需要执行强制转换,或者在AbstractDao
类中引入一些新方法,以获得所需的属性
Repository<Photo, PhotoDao> repo = new Repository<>(new PhotoDao());
class PhotoDao extends AbstractDao<Photo> { .. }