【问题标题】:Creating Spring @Repository and @Controller for every item I'm working with(from database)为我正在使用的每个项目(来自数据库)创建 Spring @Repository 和 @Controller
【发布时间】:2018-11-25 11:20:14
【问题描述】:

在处理涉及从数据库请求多种数据类型的项目时,我遇到了以下问题: 假设我有 2 个对应于数据库实体的 java 类:
Routes

  public class Route {
  public Route(int n, int region, Date fdate, boolean changed, int points, 
  int length) {
    super();
    this.n = n;
    this.region = region;
    this.fdate = fdate;
    this.changed = changed;
    this.points = points;
    this.length = length;
    }
   }

运营商

public class Carrier {
    public Carrier(...) {
    this.id = src.getId();
    this.name = src.getName();
    this.instId = src.getInstId();
    this.depotId = src.getDepotId();
}

如果是这样,创建 Dao 接口和类的正确方法是什么?我就是这么干的——

@Repository
public class CarrierDaoImpl implements CarrierDao{

@Autowired
DataSource dataSource;

public List<Carrier> getAllOrgs() { ... } 
}

@Repository
public class RoutesDaoImpl implements RoutesDao {

@Autowired
DataSource dataSource;

public ArrayList<AtmRouteItem> getRoutes(AtmRouteFilter filter) { ... }
}

我正在为每个 java 类 item\db 实体创建一个 @Repository DAO,然后为有关运营商和路线的请求创建 2 个单独的控制器。像这样:

@RestController
@RequestMapping(path = "/routes")
public class RoutesController {

@Autowired
RoutesDao routesDao;

@GetMapping(value = {"/getRoutes/", "/getRoutes"})
public ArrayList<Route> getRoutes() { ... } }

对于控制器运营商也是如此。它是否正确,如果不正确,正确的方法是什么?

对不起样式问题,这是我关于stackoverflow的第一个问题:)

【问题讨论】:

    标签: java spring spring-boot jdbc dao


    【解决方案1】:

    我建议创建标有@Service 注释的服务(即CarrierService 接口和CarrierServiceImpl 实现)。然后将它们注入控制器。在服务中使用存储库,因为某些数据库操作需要事务,而更好的管理事务的地方是服务。服务还可以做更专业的工作,这需要访问多个存储库,以便您可以注入它们。并且不要忘记使用 @Transactional 注释标记您的服务。

    【讨论】:

    • 据我所知,我的方法是正确的。你的答案呢 - 存储库不只是服务的别名,它表明它是一个持久层,所以这真的不重要吗?让我检查一下自己 - 根据您的建议,如果我在课堂上处理事务,我应该使用 @Repository,对于 DB @Service 的其他工作应该没问题,对吗?
    • @Marcin Bukowiecki 的意思是您应该使用服务类来处理来自数据库的数据。这只是良好的代码结构和良好的编程方式的问题。我可以问你:为什么你有一个控制器和一个存储库?你可以把他们放在同一个班级,不是吗?是的,你可以,但它会很丑。这是一个总结:@Controller:接听电话@Service:做逻辑工作@Repository:与DB交谈。也许,如果您只想在不进行处理的情况下进行 CRUD 操作,那么 @Service 可能是矫枉过正。我推荐你@RepositoryRestResource
    • 我会说得更清楚。让我们假设我们有 3 个实体:员工、产品和客户。我们将为每个实体创建一个存储库和一个控制器(简单的 CRUD)。在这一点上很好,但我们需要实现一些更复杂的业务逻辑,比如向我们的客户/员工发送通知,或者对我们的产品进行一些统计/开票。因此,放置此逻辑的最佳位置将是服务。只需将所需的存储库注入到ProductService,然后将其注入到ProductController。这只是将逻辑分离到适当的域。
    • 谢谢!现在我想我明白了!
    • 我还有一个问题——听从你的建议并使用@Service,而不是@Repository 注释(我觉得它是正确的,因为现在我的*Dao 类只是关于逻辑、sql 请求是在其他类中)我正在展示这些类是关于逻辑的,所以我真的不需要在这里使用 DAO 模式......这不是正确的吗?
    【解决方案2】:

    每个实体都有一个 DAO 是正确的。 使用 JPA 存储库时,您别无选择,只能提供实体。例如:

    public interface FooRepository extends JpaRepository<Foo,Long>{}
    

    对于 REST 控制器也是如此,您必须像您一样按对象将功能组合在一起。

    您可以改进映射,使其更加 RESTful。要检索所有路由,请不要指定路径:

    @GetMapping
    public ArrayList<RouteResource> getRoutes() { ... } 
    

    (我从未使用过@GetMapping,但它应该可以这样工作)

    如果你想要特定的路线:

    @GetMapping("/get/{id}")
    public RouteResource getRoute() {...}
    

    您应该向客户端返回资源而不是实体。

    【讨论】:

    • 现在我用的是JDBC,但我打算以后用JPA,谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2022-10-14
    相关资源
    最近更新 更多