如何将自定义查询添加到我的 Spring 启动应用程序并在控制器中访问它?
我有两个表,分别叫CarBrand
和YearMade
。CarBrand
有ID
、code
和Brand
作为列。YearMade
也有ID
、code
和year
作为列。
我已经为每个实体编写了带有 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 根据方法命名约定派生查询。 因此,要通过code
YearMade
表中获取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 来编写此内容。可能存在编译器错误。希望这能让您了解这一切。