控制器中的 Spring 启动自定义查询



如何将自定义查询添加到我的 Spring 启动应用程序并在控制器中访问它?

我有两个表,分别叫CarBrandYearMadeCarBrandIDcodeBrand作为列。YearMade也有IDcodeyear作为列。

我已经为每个实体编写了带有 setter 和 getter 方法的模型类。 我添加了我的存储库接口和服务类。

public interface YearRepository extends JpaRepository<Year, Long> {
}

我的品牌存储库

public interface BrandRepository extends JpaRepository<Brand, Long> {
@Query("select b from brand b where brand.brand = ?1")
List<Brand> findVehicleBrand(String brand);
}

这是我的服务类

public class YearService {
@Autowired
private YearRepository yearRepository;
public List<Year> listAll(){
return yearRepository.findAll();
}
public void save(Year engineSize){
yearRepository.save(engineSize);
}
public Year get (long id){
return yearRepository.findById(id).get();
}
public void delete (Long id){
yearRepository.deleteById(id);
}
}

我的品牌服务

public interface BService {
List<Brand> findVehicleBrand(String name);
}

还有这个。

@Service
@Transactional
public class BrandService implements BService{
@Autowired
private BrandRepository brandRepository;
public List<Brand> listAll(){
return brandRepository.findAll();
}
public void save(Brand brand){
brandRepository.save(brand);
}
public Brand get (long id){
return brandRepository.findById(id).get();
}
public void delete (Long id){
brandRepository.deleteById(id);
}
@Override
public List<Brand> findVehicleBrand(String name) {
var brand = (List<Brand>) brandRepository.findVehicleBrand(name);
return brand;
}
}

在我的控制器中,我得到一个带有字符串的路径变量,我使用substring将字符串分成两部分。两个子字符串具有品牌和年份的代码。前两个代表年份,另外三个代表品牌。如何将代码与数据库中的代码进行比较以获取实际年份和品牌。

http://localhost:8081/vincode/wwQPT

ww是1990年的代码,QPT是数据库中本田汽车公司的代码。

我想要这样的 JSON 响应

{
Year Made : 1990,
Brand Name : Honda Motor Company
}

这是我到目前为止拥有的控制器类。

@RequestMapping("/{vincode}")
public @ResponseBody String getAttr(@PathVariable(value="vincode") String vincode) {
String yr = vincode.substring(0,1);
String brand = vincode.substring(2,4);
System.out.println(yr);
return yr;
}

在哪里添加查询以及如何在控制器中使用它?

谢谢。

如果您没有请求 mappong wlth 值在类的顶部,则 http://localhost:8081/vincode/ww/QPT

RequestMapping("/vincode/{code}/{company}"( 可能更有用

无需使用子字符串,代码或公司密钥大小可能会更改。

此外,可以随时注入和使用服务层。

首先在BrandRepository 界面中添加此语句:

public interface BrandRepository extends JpaRepository<Brand, Long> {
@Query("select b from brand b where brand.brand = ?1")
List<Brand> findVehicleBrand(String brand);
public Brand findByCode(String code);
}

在 年份存储库 界面 :

public interface YearRepository extends JpaRepository<Year, Long> {
public Year findByCode(String code);
}

然后在品牌服务类中添加此方法:

public String findByCode (String code){
return brandRepository.findByCode(code).getBrand();
}

然后在 YearService Class 中添加此方法:

public String findByCode (String code){
return yearRepository.findByCode(code).getYear;
}

创建域类:

public class YearBrand
{
private String YearMade;
private String BrandName;
public YearBrand(String year, String brand)
{
this.YearMade=year;
this.BrandName=brand;
}
}

然后在控制器类中:

@RequestMapping("/{vincode}")
public YearBrand getAttr(@PathVariable(value="vincode") String vincode) {
String yr = vincode.substring(0,1);
String brand = vincode.substring(2,4);
return new YearBrand(yearService.findByCode(yr),brandService.findByCode(brand));
}

笔记: 确保控制器类已用@RestController

Spring Data JPA 根据方法命名约定派生查询。 因此,要通过codeYearMade表中获取year,您需要像这样修改YearReporsitory接口(添加一个抽象方法(:

public interface YearRepository extends JpaRepository<Year, Long> {
// set return type as required
//find - Do What, ByCode - Criteria.
public Integer findByCode(String code);
}

而且,在YearService中使用此方法,就像使用其他方法一样。 但是,您不能使用相同的方法来按代码要求获取品牌。你必须为它编写一个存储库类,如下所示:

public interface BrandRepository extends JpaRepository<CarBrand, Long> {
public Integer findByCode(String code);
}

可以为Entity类的所有成员编写这些方法。你必须遵循命名约定才能让 Spring 识别它。

编辑(显示如何在控制器和服务类中使用它(:
YearRepository接口:

public interface YearRepository extends JpaRepository<Year, Long> {
// set return type as required
//find - Do What, ByCode - Criteria.
public Integer findByCode(String code);
}

BrandRepository

public interface BrandRepository extends JpaRepository<Brand, Long> {
/*The below two methods are abstract methods.*/
// it must follow the findby<MemberName> convention
//return CarBrand
CarBrand findByBrand(String brand);

/*return a CarBrand Entity*/
public CarBrand findByCode(String code);

YearService

public class YearService {
@Autowired
private YearRepository yearRepository;
public List<Year> listAll() {
return yearRepository.findAll();
}
public void save(Year engineSize) {
yearRepository.save(engineSize);
}
public Year get(long id) {
return yearRepository.findById(id).get();
}
public void delete(Long id) {
yearRepository.deleteById(id);
}
public int getYearByCode(String code) {
//here, we're using this method just as you've used the methods above.
//Spring constructs the query at runtime
return yearRepository.findByCode(code); //<-- usage of the custom method
}
}

BService

public interface BService {
CarBrand findVehicleBrand(String name);
}

BrandService

@Service
@Transactional
public class BrandService implements BService{
@Autowired
private BrandRepository brandRepository;
public List<Brand> listAll(){
return brandRepository.findAll();
}
public void save(Brand brand){
brandRepository.save(brand);
}
public Brand get (long id){
return brandRepository.findById(id).get();
}
public void delete (Long id){
brandRepository.deleteById(id);
}
@Override
public CarBrand findVehicleBrand(String name) {
//var brand = (List<Brand>) brandRepository.findVehicleBrand(name);  
var brand = brandRepository.findByBrand(name); //<-- using the custom method in brandRepository
return brand;
}
}

您的RepsonseDto

class RepsonseDto {

private String yearMade;
private brandName;

//getters and setters
/*Use  @JsonProperty("Year Made") and  @JsonProperty("Brand Name") on your getters. Otherwise, you will get json reposnse as: "yearMade" and "brandName"*/
}

控制器:

有更好的方法来编写控制器和注入依赖项。让我们暂时保持简单。

@RequestController
class YourController {

//inject dependencies

@Autowired
YearService yearService;

@Autowired
BrandService brandService;

@RequestMapping("/{vincode}")
// the definition for ResponseEntity is above
public ResponseEntity<RepsonseDto> getAttr(@PathVariable(value="vincode") String vincode) {
// create a ReponseEntity object
RepsonseDto retEntity = new RepsonseDto();


// do a check for null and expected length of vincode
if(vincode != null && vincode.length() == 5) {
String yr = vincode.substring(0,1);
String brand = vincode.substring(2,4);
retEntity.setYearMade(yearService.getYearByCode(yr));
retEntity.setBrandName(brandService.findVehicleBrand(brand));

System.out.println(yr);

}
return new ResponseEntity<>(retEntity, HttpStatus.OK)

}

注意:我没有使用 IDE 来编写此内容。可能存在编译器错误。希望这能让您了解这一切。

最新更新