我正在使用Hibernate。问题出在底部。
很简单。
首先,我有一个基本的Dao<T>
。
public class Dao<T> {
private Class<T> persistentClass;
private Session session;
public Dao(Class<T> persistentClass) {
this.persistenClass = persistentClass;
this.session = HibernateUtil.getCurrentSession();
}
它作为基类很好用,它将最常用的方法传递到Session
。
public T get(Serializable id) {
@SuppressWarnings("unchecked")
T t = (T) this.session.get(this.persistentClass, id);
return t;
}
protected Criteria getCriteria() {
return this.session.createCriteria(this.persistentClass);
}
当需要在模型上使用查询时,它会进入该模型的特定DAO,该模型继承自Dao<T>
。
public class DaoTask extends Dao<Task> {
public DaoTask() {
super(Task.class);
}
public List<Task> searchActiveTasks() {
@SuppressWarnings("unchecked")
List<Task> list = (List<Task>) this.getCriteria()
.add(Restrictions.eq("active", true))
.list();
return list;
}
}
这种方法一直运作良好。
然而,今天我发现很多时候实例需要重新附加到Session
,并且会出现类似于以下内容的行:
new Dao<Book>(Book.class).update(book);
......我觉得这很糟糕,因为
Book.class
DaoBook
,此构造将变得过时。所以我将Dao<T>
变成了一个抽象类,然后继续重构旧代码。
为了从代码库中删除Dao<T>
引用,我想到了两种方法:
DaoBook
和排序。Dao<Object>
的类,并仅公开附件方法(例如save()
,update()
等)。我倾向于选择#2,但我认为这种“AttacherDao
”模式可能不好,所以我希望你的意见。
#2的任何缺点?另外,你觉得“当前战略”有什么问题吗?
答案 0 :(得分:1)
我们的方法是为每个持久化类提供DAO对象(从commonDao派生)。实际上,我们为这个DAO类定义接口,每个DAO决定打开哪些接口。
使用以下代码,用户无法删除PersistentClass
。
interface PersistentClassDao {
void save(PersistentClass persistentObject);
}
Class PersistentClassDaoImpl extends CommonDao implements PersistentClassDao {
void save(persistentObject) {
persist(persistentObject);
}
即使它有一些额外的开销,这种方法有助于在暴露接口之前对适当的代码进行单元测试。
答案 1 :(得分:0)
几个问题
否则,我有点担心保持会话对象而不是获取当前会话的任何内容 - 对于长期存在的会话对象,它不被认为是“坏”吗?我不是DAO的主人,所以也许我在这里错过了一些东西。
答案 2 :(得分:0)
我们选择了类似于lud0h的方法,但有以下几点:
abstract class<T extends IModelObject> JdbcCrudDao<T>{
void create(T dbo){}
T findByFoo(String foo){}
void update(T dbo){}
void delete(T dbo){}
}
class BarDao extends JdbcCrudDao<Bar>{
}
但是,扭曲的是我们选择性地通过立面暴露Dao上的方法,只转发我们绝对必须的那些。
class BarController implements IController{
private static final BarDao dao;
// ...
void update( IBar bar ){
dao.update(bar);
}
}
所有这一切中唯一的缺点是,如果你想在接口类型(我们这样做)之后隐藏你的数据库密钥,它需要一些演员,但这是一个非常小的不便与替代(数据库代码之外) DAOS)。