【问题标题】:Implementing a Search feature using multiple Search parameters使用多个搜索参数实现搜索功能
【发布时间】:2022-01-25 05:13:36
【问题描述】:

我是学习 Spring Boot 的新手,我正在尝试这个辅助项目,您可以在其中使用 2 个参数 access_pin 和 org_name 搜索员工。

假设我想在数据库中搜索的员工具有以下凭据:

  • access_pin:1234
  • 组织名称:巴黎圣日耳曼

我的 API 应该检索具有上述匹配项的员工记录。

我的 REST API URL 如下所示:

http://localhost:8080/employeeSearch/version1/1234/PSG

当我在 PostMan 上发送 GET 请求时,我收到 500 错误。

PostMan Screenshot

这是数据库表:

Database table Screenshot

能否知道spring是如何处理多个搜索参数并从数据库中返回准确结果的?

我的后端代码如下所示:

模型: (Employee.java)

package com.example.demo.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employeedatabase")
public class Employee {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long employeeId; 
    
    @Column(name = "employee_name")
    private String employeeName;
    
    @Column(name = "access_pin")
    private long accessPin; 
    
    @Column(name = "org_name")
    private String orgName;
    
    public Employee() {
        
    }

    public Employee(String employeeName, String orgName) {
        super();
        this.employeeName = employeeName;
        this.orgName = orgName;
    }

    public long getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(long employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public long getAccessPin() {
        return accessPin;
    }

    public void setAccessPin(long accessPin) {
        this.accessPin = accessPin;
    }

    public String getOrgName() {
        return orgName;
    }

    public void setOrgName(String orgName) {
        this.orgName = orgName;
    } 
    
    
    
    
    
    
}



控制器: (EmployeeController.java)

package com.example.demo.Controller;

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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.model.Employee;
import com.example.demo.service.EmployeeService;



@RestController
@RequestMapping("/employeeSearch/version1")
public class EmployeeController {
    
    @Autowired
    private EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        super();
        this.employeeService = employeeService;
    }
    
    @GetMapping("{accessPin}/{orgName}")
    public ResponseEntity<Employee> getEmployeeNAme(@PathVariable("accessPin") long accessPin, @PathVariable("orgName") String orgName) {
        Employee result = employeeService.getEmployeeName(accessPin, orgName);
        
        return ResponseEntity.status(HttpStatus.OK).body(result);
    }
    
    
}

服务: (EmployeeService.java)

package com.example.demo.service;

import com.example.demo.model.Employee;

public interface EmployeeService {
    
    Employee getEmployeeName(long accessPin, String orgName) ; 
}

ServiceImpl: (EmployeeServiceImpl.java)

package com.example.demo.serviceImpl;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.exception.ResourceNotFoundException;
import com.example.demo.model.Employee;
import com.example.demo.repository.EmployeeRepository;
import com.example.demo.service.EmployeeService;

@Service
public class EmployeeServiceImpl implements EmployeeService{
    
    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public Employee getEmployeeName(long accessPin, String orgName) {
        // TODO Auto-generated method stub
//      return null;
        
        Optional<Employee> employeeName = employeeRepository.findById(accessPin);
        
        
        if(employeeName.get().getAccessPin() == accessPin) {
            return employeeName.get(); 
        }
        else {
            throw new ResourceNotFoundException("The employee does not exist. "); 
        }
    }

}

存储库: (EmployeeRepository.java)

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Employee;

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

}

【问题讨论】:

  • 500 类型错误表示您正在抛出异常。
  • 检查您的 Spring Boot 应用程序日志。可能有 n 个错误导致内部服务器错误。
  • 你有错误的堆栈跟踪吗?
  • @Kevin Wallis,不,我的应用程序运行但我得到了资源未找到异常。

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


【解决方案1】:

根据您的实体,字段employee_id 是您的ID。使用 findbyId 时,您正在使用实体的 id 进行搜索。因此,当您使用 '1234' 调用该函数时,您将得到一个空的可选项,并在调用 Optional::get 时遇到空指针异常,从而导致 500 错误。对于您的用例,您可以向 EmployeeRepository 添加自定义函数,如下所示

Optional<Employee> findByAccessPinAndOrgName(long accessPin, String orgName);

此外,当使用可选值时,请在访问之前检查该值是否存在。

请参阅以下文章以获取有关这两个主题的更多帮助:

https://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/#jpa.query-methods.query-creation

https://www.baeldung.com/java-optional

【讨论】:

  • 感谢您提供信息,我在代码中实施了您建议的更改,但我不确定如何进行 REST API 调用,以便在前端获得预期结果
  • 理想情况下,它应该与您的服务和存储库层中存在的更改完全相同的格式。也许您可以编辑您的问题或添加指向存储库的链接,其中更改将可见并且您可以获得进一步的帮助。
【解决方案2】:

我在您的代码中发现了三个问题。

在您的服务中,您正在调用 findById,但您传递的是 accessPin,而不是员工 ID - employeeRepository.findById(accessPin)。您应该将findByAccessPin 函数定义添加到您的存储库接口。

在您的服务类中处理Optional 存储库结果时,您应该在尝试使用.get() 访问结果之前调用isPresent()。对空的 Optional 调用 get 将导致抛出异常。

最后,您的 EmployeeController 构造函数正在调用 super() 但该类没有超类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    相关资源
    最近更新 更多