如何在Spring Boot中为许多数据库编写Controller类?

时间:2018-01-05 21:03:36

标签: java spring hibernate spring-mvc spring-boot

我有多个数据库(MySQL和4个NoSQL数据库)。服务类都为CRUD操作实现CustomerServiceClass。 这就是我的Controller类的外观:

@RestController
@RequestMapping("/customer")
public class CustomerController {

@Autowired
CustomerService customerService;

public CustomerController(CustomerService customerService) { this.customerService = customerService;}

@RequestMapping(value = "/{Id}", method = RequestMethod.POST)
public ResponseEntity<Customer> create(@RequestBody CustomerData customerData) {
    customerService.create(customerData);
    return new ResponseEntity<Customer>(customerData, HttpStatus.CREATED);
}

@RequestMapping(value = "/{Id}", method = RequestMethod.GET)
public ResponseEntity<Customer> read(@PathVariable("Id") String Id){
    Customer customer = (Customer)customerService.read(Id);
    if (customer == null){
        return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<Customer>(customer, HttpStatus.OK);

}

@RequestMapping(method = RequestMethod.GET)
public List<Customer> retrieveCustomers(){
    return customerService.retrieveAllCustomers();
}

@RequestMapping(value = "/{Id}", method = RequestMethod.PUT)
public ResponseEntity<Customer> update(@PathVariable("Id") String Id,    @RequestBody CustomerData customerData) {

    Customer currentCustomer = (Customer)customerService.read(Id);
    if(currentCustomer == null){
        return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
    }
    currentCustomer.setName(customerData.getName());
    currentCustomer.setDistrict(customerData.getDistrict());
    currentCustomer.setDate(customerData.getDate());

    customerService.create(currentCustomer);
    return new ResponseEntity<Customer>(currentCustomer, HttpStatus.OK);

}

@RequestMapping(value = "/{Id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> delete(@PathVariable String Id){
    Customer customer = (Customer)customerService.read(Id);
    if (customer==null){
        return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
    }else {
        customerService.delete(Id);
        return new ResponseEntity<Void>(HttpStatus.GONE);
    }
  }}

这是CustomerService界面的外观:

@Component
public interface CustomerService<E>{

E create(Customer customer);

E read(String id);

List<E> retrieveAllCustomers();

E update(String Id, Customer customer);

//List<Order> retrieveAllOrders(String customerId);

void delete(String id);

void deleteAll();}

这是我的MySQL-CustomerService类:

@Service("myCustomerService")
@Qualifier("myCustomerService")
@Profile(Profiles.MYSQL)
public class MyCustomerService implements CustomerService{

@Autowired
private MyCustomerRepository customerRepository;

@Override
public Customer create(Customer customer) {
    MyCustomer myCustomer = new MyCustomer(customer);
    customerRepository.save(myCustomer);
    return myCustomer;
}

@Override
public Customer read(String id) { return customerRepository.findOne(id); }

@Override
public List<MyCustomer> retrieveAllCustomers() { return customerRepository.findAll(); }

@Override
public Customer update(String id, Customer customerData) {
    MyCustomer customer = customerRepository.findOne(id);
    customer.copy(customerData);
    customerRepository.save(customer);
    return customer;
}


@Override
public void delete(String id) { customerRepository.delete(id); }

@Override
public void deleteAll() { customerRepository.deleteAll(); }}

我对NoSQL类做了同样的事情。

这是我得到的错误消息,我已经尝试了一切来修复它(添加限定符等):

  

org.springframework.beans.factory.UnsatisfiedDependencyException:在文件[/demo/controller/CustomerController.class]中定义名称为'customerController'的bean时出错:通过构造函数参数0表示的不满意的依赖关系;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型'demo.service.CustomerService'的限定bean可用:预期至少有1个bean有资格作为autowire候选者。依赖注释:{}

更新: 这是我的属性的yml文件:

spring:
datasource:
url: jdbc:mysql://localhost/mydb
username: root
driver-class-name: com.mysql.jdbc.Driver
data:
mongodb:
  uri: mongodb://localhost:27017/MongoTest
cassandra:
  keyspace-name: db_keyspace
  contact-points: localhost
  port: 9042
  schema-action: create_if_not_exists
neo4j:
  uri: bolt://localhost:7474
  username: neo4j
  password: root

jpa:
  properties:
  hibernate.show_sql: true
  hibernate.use_sql_comments: true
  hibernate.format_sql: true
  hibernate.dialect: org.hibernate.dialect.MySQL5Dialect

mvc:
view:
  prefix: /WEB-INF/jsp
  suffix: .jsp

logging:
file: logback-spring.xml
level: DEBUG

将@Primary添加到其中一个Database-Service类可以解决问题。但我需要从不同数据库的所有类中检索数据而不特别选择。

提前感谢您的任何帮助!

2 个答案:

答案 0 :(得分:0)

在启动Spring应用程序时,您似乎没有激活要使用的数据库的配置文件。

如果您在CustomerServices上使用@Profile(Profiles.WHATEVER),则需要在运行应用程序时激活其中一个配置文件。

您可以使用.yml文件中的应用程序属性(设置spring.profiles.active = WHATEVER),Spring Tool Suite中的运行配置(它有一个单独的字段来输入配置文件)或命令来实现。行参数

-Dspring.profiles.active="WHATEVER"

命令行参数也可以添加到Java应用程序的Eclipse运行配置中的VM参数中(如果您不使用Spring Tool Suite)

要进行测试,请查看@ActiveProfiles注释(或在特殊属性文件中定义活动配置文件以进行测试)。

@Primary还会激活一个配置文件:它会告诉Spring当您没有通过其他方式选择配置文件时,或者当您激活了包含CustomerServices的多个配置文件时(如果其中一个配有@Primary),将使用哪个CustomerService注释,它将被选中;否则你会得到一个异常,告诉你Spring找到了太多的CustomerServices)。

答案 1 :(得分:0)

我认为您应该从CustomerController构造函数中删除CustomService customerService。 您不需要在构造函数中设置CustomerService,因为它将通过@Autowired Annotation自动注入CustomerServiceField。

@Autowired
CustomerService customerService;

public CustomerController() 
{
}

如果你想使用构造函数注入(Good for tests),你可以像这样使用它:

CustomerService customerService;

@Autowired
public CustomerController(CustomerService customerService) 
{
    this.customerService = customerService;
}