【问题标题】:CRUD with generic classes (dao,service)具有泛型类的 CRUD (dao,service)
【发布时间】:2013-07-28 13:09:45
【问题描述】:

我从 spring、hibernate、maven、jpa、springMVC 开始我的大型应用程序。 目前我有 30 节课。 (每个类都有接口,我们有 60 个类) 我有两个包裹。 (道与服务) 对于 dao,我使用 genericDao 类。 我对 All Dao 的课程摘要是:

>
package org.me.dao.jpageneric;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
 
import org.apache.log4j.Logger;
 
public abstract class GenericDAO<T, K> {
 
        @PersistenceContext(unitName="database")
        protected EntityManager em;
 
        protected Logger logger=Logger.getLogger(getClass());
 
        public abstract Query getByIdQuery(K id);
        public abstract Query getAllQuery();
 
        public T save(T saved) {
                if (saved == null) {
                  throw new IllegalArgumentException("L'argument de save() ne doit pas être nul.");
                }

                return (T) em.merge(saved);
        } // save()
 
        public void delete(T deleted) {
                if (deleted == null) {
                     throw new IllegalArgumentException("L'argument de delete() ne doit pas être nul.");
                }
                em.remove(deleted);
        } // delete().
 
        @SuppressWarnings("unchecked")
        public T get(K id) {
                if (id == null) {
                   throw new IllegalArgumentException("L'argument de get() ne doit pas être nul.");
                }
                Query query = getByIdQuery(id);
                return (T) query.getSingleResult();
        } 
        @SuppressWarnings("unchecked")
        public List<T> getAll() {
                logger.debug("Récupération de tous les objets");
                Query query = getAllQuery();
                return (List<T>) query.getResultList();
        } 

每个 Dao 都必须扩展这个类并实现他的接口(我必须为其他 30 个类做这个)。我希望这是一个好的做法。

之后,我有了另一个用于服务类的抽象泛型类。

package org.me.service.generic;
 
import java.util.List;
 
public abstract class GenericService<T,K> {
 
        public abstract T create(T saved);
        public abstract void remove(T deleted);
        public abstract T findById(K id) ;
        public abstract List<T> findAll();
 
}

她同样的事情,所有的服务类都必须扩展这个通用的服务类并实现每个类的接口。 又是好习惯吗?

当然,我为每个类(包 dao 和服务)都有一个接口。

另一个问题:我必须创建控制器,我该怎么做?为每个类创建一个控制器(也就是说 30 个控制器?) 以及如何处理页面 html 和 jsp? 谢谢你。 对不起,我的英语不好。:-)

【问题讨论】:

  • 服务和控制器应该实现应用程序的用例。它们不应包含任意创建、删除和查找方法。假设您正在实现一个银行应用程序。您真的不想列出所有帐户(可能是数百万)或所有客户,对吗?此外,JPA 有 EntityManager.find() 通过 ID 获取实体。使用它而不是查询。
  • 感谢您提供这些信息。我改变了你说的!更简单,非常有用。我的申请是大使馆、旅行社和外交部。

标签: spring hibernate model-view-controller jpa controller


【解决方案1】:

Spring-data-jpa 替换了您的 GenericDAO。

您可以查看 spring-data-rest 以获得您的 crud 服务。

另外,我建议查看 spring-roo,它为 Web UI 搭建了基础以进行 crud 操作。

【讨论】:

  • 谢谢。是的,spring-data-jpa 有很多我不明白的地方!最后它非常易于使用。另一个问题?可以将 spring-data-rest 添加到 spring-data-jpa 吗?我看到 spring-roo 这很有趣,但我对所有框架都感到害怕。可以使用 spring-data-jpa,spring-data-休息吗?
  • spring-data-rest 建立在 spring-data-jpa 之上,所以一旦你有了 spring-data-jpa,你就可以在 spring-data-rest 上工作。我认为 spring-data-rest 和 spring-roo 不能很好地协同工作。
  • 仅供参考。如果我将 spring-data-rest 与 spring-data-rest 集成在一起,控制器呢?它是嵌入的还是我必须创建它?
  • 看起来 spring-data-rest 提供了一个直接映射到 jpa repo 的控制器,因此您根本不需要编写控制器或服务层。
【解决方案2】:

软件编程中一些广为人知的良好做法是:

  • 干燥(不要重复自己)。如果您发现自己多次复制相同的代码,那只是等待发生的错误 - 尤其是在重构(更改)重复代码的时候。
  • 不要重新发明轮子。看看 Spring Data JPA 项目,已经有a generic DAO feature可以使用了

对于 Spring MVC 控制器,我不明白为什么需要对所有控制器进行超类化。您只需要使用@Controller 注释每个控制器类。将控制器执行的业务功能封装在 Service 类中是个好主意,这样您就可以在其他地方重用它

【讨论】:

  • 如您所知:我的应用程序有 30 个实体。我已经尝试过 Spring Data JPA,但我必须编写为所有 DAO(30 个类)实现的每个方法。使用我的解决方案,我不必这样做。仅举个例子: public class AddressDAO extend GenericDao
    implements IAddress{ 而且我不必在 AddressDAO 中编写任何方法。但是使用 JpaRepository 我必须为所有类编写所有方法。我希望这是正确的我的概念。如果你看到错误不要犹豫。感谢控制器:我应该创建 30 个控制器类?还是所有类只有一个控制器?谢谢
  • 我会试试 spring-data-jpa
  • 顺便提一下:您还可以在控制器级别使用泛型。一个简单的控制器用于主数据的 CRUD 操作,它从路径变量或请求参数中获取类名和 id。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
  • 2020-08-26
  • 1970-01-01
  • 2015-07-09
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多