在spring Boot rest中使用抽象/泛型类- crud API

f1tvaqid  于 2023-02-12  发布在  Spring
关注(0)|答案(1)|浏览(176)

我现在真的很纠结于我的问题。我一直在努力解决这个问题,也许我能在这里得到帮助。
我有一个简单的Spring Boot CRUD项目连接到我的MySQL数据库(localhost:3306),一切都很好。当我把我的类修改成一个更常见的oop结构时,我得到了几个错误,什么都不能用了。
我的结构简图:

  • 雇员(抽象)类
  • 职员(实体)类
  • 管理员(实体)类

employee类只包含一个字段(employee id "emp_id"),我不想重复输入finall等jpaRepo函数。
下面是我的抽象类:

package dev.cherry.emp.Employee.Util;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public abstract class Employee {

    @Id
    @Column(name = "emp_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long empId;
}

这是我的抽象类仓库:

package dev.cherry.emp.Repository;

import dev.cherry.emp.Employee.Util.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

@NoRepositoryBean
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

这是我的抽象类的服务类。泛型被包含以重用Clerk和admin类:

package dev.cherry.emp.Service;

import dev.cherry.emp.Repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeService<T> {

    private final EmployeeRepository employeeRepo;

    @Autowired
    public EmployeeService(EmployeeRepository employeeRepo) {
        this.employeeRepo = employeeRepo;
    }

    public List<T> allEmps() {
        return (List<T>) employeeRepo.findAll();
    }
}

这是抽象类Employee的Controller类:

package dev.cherry.emp.Controller;

import dev.cherry.emp.Service.EmployeeService;
import org.apache.coyote.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class EmployeeController<T> {

    private final EmployeeService employeeService;

    @Autowired
    public EmployeeController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    public ResponseEntity<List<T>> allEmps() {
        List<T> allEmps = employeeService.allEmps();
        return new ResponseEntity<>(allEmps, HttpStatus.OK);
    }
}

很抱歉我的代码看起来像样板文件,最后但并非最不重要的是我的文件夹结构,根目录是src/main/java/dev.cherry. emp/

.
├── Controller
│   ├── AdminController.java
│   ├── ClerkController.java
│   └── EmployeeController.java
├── EmpApplication.java
├── Employee
│   └── Util
│       ├── Employee.java
│       └── Gender.java
├── Model
│   ├── Admin.java
│   └── Clerk.java
├── Repository
│   ├── AdminRepository.java
│   ├── ClerkRepository.java
│   └── EmployeeRepository.java
└── Service
    ├── AdminService.java
    ├── ClerkService.java
    └── EmployeeService.java

这是控制台上的Spring启动错误:
应用程序无法启动
描述:
dev. cherry. emp. Service. EmployeeService中构造函数的参数0需要单个bean,但找到了2个:- 管理存储库:在dev. cherry. emp. Repository中定义。AdminRepository在@EnableJpa Repositories中定义,在Jpa Repositories注册器上声明。EnableJpa Repositories配置-clerkRepository:在dev. cherry. emp. Repository. Clerk中定义在@EnableJpa中定义在Jpa存储库注册器上声明的存储库。EnableJpa存储库配置
行动:
考虑将其中一个Bean标记为@Primary,更新使用者以接受多个Bean,或者使用@Qualifier标识应使用的Bean

m2xkgtsf

m2xkgtsf1#

不知何故,我可以想出如何解决我的问题。长话短说,我会显示我所有的类。简短的免责声明。ChatGPT帮助我解决了这个问题。
我的班级/项目结构:
路径:源代码/main/java/dev/cherry/emp
文件夹"emp"中的树:

.
├── EmpApplication.java
└── Employee
    ├── Controller
    │   └── EmployeeController.java
    ├── Model
    │   ├── Admin.java
    │   └── Clerk.java
    ├── Repository
    │   ├── AdminRepository.java
    │   ├── ClerkRepository.java
    │   └── EmployeeRepository.java
    ├── Service
    │   └── EmployeeService.java
    └── Util
        ├── Employee.java (abstract)
        └── Gender.java (Enum)

以下是一个接一个的课程。抱歉,文字墙:

    • 抽象类员工**
package dev.cherry.emp.Employee.Util;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public abstract class Employee {

    @Id
    @Column(name = "emp_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long empId;
}
    • 班级管理员及文员(分班/儿童班)**

一个二个一个一个

    • 我的存储库类**
package dev.cherry.emp.Employee.Repository;

import dev.cherry.emp.Employee.Util.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

@NoRepositoryBean
public interface EmployeeRepository<T extends Employee> extends JpaRepository<T, Long> {
}
package dev.cherry.emp.Employee.Repository;

import dev.cherry.emp.Employee.Model.Clerk;
import org.springframework.stereotype.Repository;

@Repository
public interface ClerkRepository extends EmployeeRepository<Clerk>{
}
package dev.cherry.emp.Employee.Repository;

import dev.cherry.emp.Employee.Model.Admin;
import org.springframework.stereotype.Repository;

@Repository
public interface AdminRepository extends EmployeeRepository<Admin> {
}
    • 我的服务类**
package dev.cherry.emp.Employee.Service;

import dev.cherry.emp.Employee.Util.Employee;
import dev.cherry.emp.Employee.Model.Admin;
import dev.cherry.emp.Employee.Model.Clerk;
import dev.cherry.emp.Employee.Repository.AdminRepository;
import dev.cherry.emp.Employee.Repository.ClerkRepository;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EmployeeService {
    private final AdminRepository adminRepo;
    private final ClerkRepository clerkRepo;

    public List<? extends Employee> getAllEmps(@NotNull String type) {
        if (type.equals("Clerk")) {
            return (List<Clerk>) clerkRepo.findAll();
        } else if (type.equals("Admin")) {
            return (List<Admin>) adminRepo.findAll();
        } else throw new IllegalArgumentException("Class: " + type + " not found in project");
    }

    public Employee createEmployee(Employee employee) {
        if (employee instanceof Clerk) {
            return clerkRepo.save((Clerk) employee);
        } else if (employee instanceof Admin) {
            return adminRepo.save((Admin) employee);
        } else {
            throw new IllegalArgumentException("Illegal Employee subclass: " + employee.getClass().getSimpleName());
        }
    }

}
    • 我的控制器类**
package dev.cherry.emp.Employee.Controller;

import dev.cherry.emp.Employee.Util.Employee;
import dev.cherry.emp.Employee.Service.EmployeeService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/employees")
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class EmployeeController {

    private final EmployeeService employeeService;

    @GetMapping(value = "type/{type}")
    public ResponseEntity<List<? extends Employee>> getAllEmps(@PathVariable String type) {
        List<? extends Employee> employees = employeeService.getAllEmps(type);
        return new ResponseEntity<>(employees, HttpStatus.OK);
    }

    @PostMapping("/new")
    public ResponseEntity<Employee> createEmployee(@RequestBody Employee employee) {
        Employee savedEmployee = employeeService.createEmployee(employee);
        return new ResponseEntity<>(savedEmployee, HttpStatus.CREATED);
    }
}

我的代码工程实际上和 Postman 我可以测试我的要求。请随时告诉我一个更好的方式,如果你认为它可以做得更聪明或更少的代码行。
非常感谢您的支持。

相关问题