Java 使用Hibernate和Spring的通用DAO,他们的方法比这更好吗? 公共类GenericDao{ 私有最终类类型; @资源(name=“sessionFactory”) 私人会话工厂会话工厂; 公共泛型DAO(最终类类型){ this.type=type; } 公共PK保存(最终TO){ 返回(PK)sessionFactory.getCurrentSession().save(o); } //…获取、删除等

Java 使用Hibernate和Spring的通用DAO,他们的方法比这更好吗? 公共类GenericDao{ 私有最终类类型; @资源(name=“sessionFactory”) 私人会话工厂会话工厂; 公共泛型DAO(最终类类型){ this.type=type; } 公共PK保存(最终TO){ 返回(PK)sessionFactory.getCurrentSession().save(o); } //…获取、删除等,java,hibernate,spring,dependency-injection,dao,Java,Hibernate,Spring,Dependency Injection,Dao,应用程序上下文bean: public class GenericDao <T, PK extends Serializable> { private final Class<T> type; @Resource(name = "sessionFactory") private SessionFactory sessionFactory; public GenericDao(final Class<T> type) {

应用程序上下文bean:

public class GenericDao <T, PK extends Serializable> {

    private final Class<T> type;

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    public GenericDao(final Class<T> type) {
    this.type = type;
    }

    public PK save(final T o) {
    return (PK) sessionFactory.getCurrentSession().save(o);
    }
// ... get,delete, etc

com.mycompany.Foo
在服务层中,按如下方式调用:

<bean id="fooDao" class="com.mycompany.dao.GenericDao">
        <constructor-arg>
            <value>com.mycompany.Foo</value>
        </constructor-arg>
    </bean>
@Autowired
私家菜刀;
...
公共文件包括存档(Foo-Foo)
fooDao.save(foo);

这种设计的缺点是——您会如何执行一些非琐碎的操作?对许多对象的操作又如何?当请求中使用的对象数量达到一定数量(比如1000个)时,由于多个db请求,您将面临巨大的减速


根据我的经验,这是一个很好的方法,它可以创建一些类,比如现在的GenericDao,然后从中派生出特定的DAO。它允许在GenericDao中放入一些有用的通用方法,并在特定的派生中实现特定的方法。

我认为您的解决方案很好,但您不需要class参数
T
。它只是限制了您和不允许对整数和字符串重复使用同一DAO(例如)

Save方法根本不需要这种类型

get()
find()
这样的方法本身应该接收泛型类型:

public T findById(类clazz,可序列化id);


公共列表列表所有(类clazz);

比自己编写更好

  • (它是Spring Data Jpa的前身)
在这两个方面,它看起来非常相似:只有接口,没有实现:

@Autowired
private GenericDao<Foo, Integer> fooDao;
...
public doStuffIncludingSave(Foo foo)
fooDao.save(foo);
公共接口UserDao扩展了GenericDao{
用户findByLogin(字符串登录);
}

如果您感兴趣,请查看文档。

看起来您正在将类型传递给dao,这样您就可以为dao中的泛型获取正确的类型。而不是这样做,您可以使用这样一种方法,它允许您拥有如下方法:

public interface UserDao extends GenericDao<User, Long> {
     User findByLogin(String login);         
}
@Bean(name=“myAsdfDao”)
公共GenericDao getMyAsdDao(){
返回新的GenericDao();
}

这将允许您保留特定于实体的DAO,而无需通过xml配置将类型传递给构造函数。这将位于@Configuration注释类中,该类为spring提供基于java的配置。

一个好的起点是从2006年开始,但其中包含一些好的信息。要更新spring的通用DAO,请这就是我所做的。这也是非常有用的

所有标识符都是一个通用的intferface,以确保类具有
I getId()
setId(I id)

创建通用DAO接口

@Bean(name="myAsdfDao")
public GenericDao<MyAsdf, MyAsdfId> getMyAsdfDao() {
    return new GenericDao<MyAsdf, MyAsdfId>();
}

@soulcheck在任何意义上都更好。例如,是否有我缺少的最佳实践标准实践。我是否必须通过xml传递构造函数参数,泛型是否合适,它们内置的spring机制是否适用于此。然后我可以删除构造函数参数并使用相同的实现来查找/删除任何类型?我将如何调用依赖注入?它们中的任何一个看起来是什么样的?如果对它的作用有简短的解释就好了?啊哈,所以对于每个实体类型(foo、bar等),我会在类上有不同的方法。您的标识符是哪个类?例如,org.springframework.expression.spel.ast.Identifier或org.hibernate.metamodel.relational.Identifier。无论哪种方式,我都会得到一个编译错误,它说:“标识符不带参数”,我自己也用过:
公共接口标识符{I getId();void setId(I Identifier);}
vary help answer@sebastienth此实现没有服务接口和实现。若要使其工作而不出现同步错误,请确保将配置类中的
@EnableTransactionManagement
更改为
@EnableTransactionManagement(proxyTargetClass=true)
。然后将
@Transactional
注释移动到服务实现类,而不是已经用
@Repository
注释的DaoImpl类
public interface GenericDao<T extends Identifier<I>, I extends Serializable> {
    public T find(I id);
    public void delete(T obj);
    public void saveOrUpdate(T obj);
}
public abstract class GenericDaoImpl<T extends Identifier<I>, I extends Serializable> implements GenericDao<T, I>{

    private Class<T> type;

    @Autowired
    private SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    protected SessionFactory getSessionFactory() {
        if (sessionFactory == null)
            throw new IllegalStateException("SessionFactory has not been set on DAO before usage");
        return sessionFactory;
    }

    public Class<T> getType() {
        return type;
    }

    public GenericDaoImpl() {
        this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @Transactional(readOnly = true)
    @Override
    public T find(I id) {
        return (T) getSessionFactory().getCurrentSession().get(getType(), id);
    }

    @Transactional
    @Override
    public void delete(T obj) {
        getSessionFactory().getCurrentSession().delete(obj);
    }

    @Transactional
    @Override
    public void saveOrUpdate(T obj) {
        getSessionFactory().getCurrentSession().saveOrUpdate(obj);
    }
}
public interface SomeObjectDao extends GenericDao<SomeObject, Long>{
}
@Repository
public class SomeObjectDaoImpl extends GenericDaoImpl<SomeObject, Long> implements SomeObjectDao {

}
@Autowired
private SomeObjectDao someObjectDao;