如何从给定参数中检索查询?

Posted

技术标签:

【中文标题】如何从给定参数中检索查询?【英文标题】:How to retrieve query from a given parameter? 【发布时间】:2018-12-23 18:23:17 【问题描述】:

我最近开始在工作中学习 Spring boot 和 Spring RESTful。我可以在 spring REST 项目中打印“Hello world”。我还使用了集合,并且能够显示城市的名称。现在,我需要让用户能够请求一个城市,应用程序将只检索该特定城市的数据。

我知道我必须使用 RequestMapping,但我似乎无法理解很多技术术语。这不是要求你做我的工作,我要求的只是帮助。我本来可以更好地学习一切,但我的公司给了我不到一周的时间来展示它作为演示,而且我刚刚学习了 Spring 的基础知识,所以我必须在旅途中学习。

感谢任何帮助。

我将它们全部放在主文件夹中,而不是单独的包。

此类为请求提供数据。

package com.weatherreport.demo;

import java.util.ArrayList;
import java.util.List;


import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController

public class WeatherResource

    @RequestMapping("weather")

    public List<Weather> getWeather()
    
        List<Weather> weather=new ArrayList<>();

        Weather a1=new Weather();
        Weather a2=new Weather();
        Weather a3=new Weather();
        Weather a4=new Weather();
        Weather a5=new Weather();
        Weather a6=new Weather();

        a1.setCity("Timbuktu");
        a1.setMaxTemp(38);
        a1.setMinTemp(15);
        a1.setRainfall(3.5);
        a1.setWindspeed((float) 11.5);
        a1.setHumidity(29);


        a2.setCity("London");
        a2.setMaxTemp(12);
        a2.setMinTemp(2);
        a2.setRainfall(12.5);
        a2.setWindspeed((float) 1.5);
        a2.setHumidity(12);




        a3.setCity("Delhi");
        a3.setMaxTemp(38);
        a3.setMinTemp(29);
        a3.setRainfall(0.2);
        a3.setWindspeed((float) 19.5);
        a3.setHumidity(9);


        a4.setCity("Mawsynram");
        a4.setMaxTemp(22);
        a4.setMinTemp(16);
        a4.setRainfall(358.5);
        a4.setWindspeed((float) 91.5);
        a4.setHumidity(96);


        a5.setCity("Wellington");
        a5.setMaxTemp(12);
        a5.setMinTemp(9);
        a5.setRainfall(31.5);
        a5.setWindspeed((float)44);
        a5.setHumidity(85);




        weather.add(a1);
        weather.add(a2);
        weather.add(a3);
        weather.add(a4);
        weather.add(a5);



        return weather;
    



这是一个定义变量及其 getter setter 的基本类。

package com.weatherreport.demo;

public class Weather

    private String city;
    private int maxTemp;
    private int minTemp;
    private float rainfall;
    private float windspeed;
    private int humidity;
    public String getCity() 
        return city;
    
    public void setCity(String city) 
        this.city = city;
    
    public int getMaxTemp() 
        return maxTemp;
    
    public void setMaxTemp(int maxTemp) 
        this.maxTemp = maxTemp;
    
    public int getMinTemp() 
        return minTemp;
    
    public void setMinTemp(int minTemp) 
        this.minTemp = minTemp;
    
    public float getRainfall() 
        return rainfall;
    
    public void setRainfall(double d) 
        this.rainfall = (float) d;
    
    public float getWindspeed() 
        return windspeed;
    
    public void setWindspeed(float windspeed) 
        this.windspeed = windspeed;
    
    public int getHumidity() 
        return humidity;
    
    public void setHumidity(int humidity) 
        this.humidity = humidity;
    




没有对 SpringBootApplication 类进行任何更改。

现在,当我通过 POSTman 发送 GET 请求时,我得到了集合中存在的所有数据。相反,我想要的是让用户能够输入城市,检查所需的城市是否在数据库中。如果是,它应该只显示该特定城市的数据。

我知道这类问题不受欢迎。但是我被困在一块石头和一个坚硬的地方之间,并且可以使用每一点帮助。谢谢。

编辑

我终于做到了。在路上搜索和学习一点。

这些是我的要求:我必须在集合中制作一些数据。然后我必须检索请求的城市数据。我使用了 Web 依赖项,仅此而已。

首先,创建一个模型类,在模型类中定义所有需要的参数。检查上面的类。

我选择以丑陋的方式来做,而不是将存储库和控制类分开。不管怎样,这里是控件/资源类的代码。

@RestController
public class WeatherResource


    @RequestMapping(value = "/weather", method = RequestMethod.GET) //This will get the entire data.
    public List getWeather()
    
        List<Weather> listOfCityWeather = new ArrayList();
        listOfCityWeather=createCityWeatherList();
        return listOfCityWeather;
    

    @RequestMapping(value = "/weather/city", method = RequestMethod.GET) // Gets the data for a specific city
    public Weather getWeatherByCity(@PathVariable String city)
    

        List<Weather> listOfCityWeather = new ArrayList();
        listOfCityWeather=createCityWeatherList();

        for (Weather weather: listOfCityWeather) 
            if(weather.getCity().equalsIgnoreCase(city))
            

                return weather;

            

        


        return null;
    



        public List createCityWeatherList()
        

            List<Weather> listOfCityWeather=new ArrayList<>();

            Weather a1=new Weather();



            a1.setCity("Timbuktu");
            a1.setMaxTemp(38);
            a1.setMinTemp(15);
            a1.setRainfall(3.5);
            a1.setWindspeed((float) 11.5);
            a1.setHumidity(29);


            //Initialise the List as required. I have provided an example.


            listOfCityWeather.add(a1);


            return listOfCityWeather;
        




感谢大家,尤其是 @g00glen00b 对我的帮助。

【问题讨论】:

所以您在 Spring REST 项目中打印“Hello world”,但您不知道@RequestMapping 是什么?这怎么可能? spring.io/guides 正如我所说,我几乎没有时间使用 REST 创建服务。我只是按照 YouTube 视频上的说明进行操作。我需要时间来学习,而我当然没有。所以我必须在工作中学习。 那么你需要告诉给你任务的人你没有足够的时间。对于 Stack Overflow,这并不是一个有效的问题。 @RequestMapping javadoc. 【参考方案1】:

首先,如果您想使用数据库,您需要对代码库进行一些更改。如果您要使用 SQL 数据库(1),您可以使用 Spring Data JPA 和内存数据库(如 HSQLDB 或 H2)用于开发/测试目的。要使用这些,您需要添加一些依赖项,例如使用 Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
</dependency>

(1) 即使您不打算使用 SQL 数据库,Spring Data 项目的目标是为所有数据源提供一致的 API,以便您可以更改轻松编写代码。

之后,您需要更改 Weather 类,使其成为有效的 JPA 实体(实体类是数据库中表的 Java 表示形式)。您必须在这里定义的一件事是您的主键,它应该是唯一的。例如,在这种情况下,它可能是城市:

@Entity // Add this to declare your Weather class as an entity
public class Weather 
    @Id // Add this to define your city as the primary key
    private String city;
    private int maxTemp;
    private int minTemp;
    private float rainfall;
    private float windspeed;
    private int humidity;

    // Getters + Setters

现在您已经有了一个实体,您可以创建一个 Spring 数据存储库,它提供了访问/修改数据库中数据的方法。 Spring Data 将为您完成大部分工作,您所要做的就是创建一个从JpaRepository 扩展的新接口:

public interface WeatherRepository extends JpaRepository<Weather, String> 


传递给JpaRepository&lt;Weather, String&gt; 的泛型是您的实体类和主键的类型(这是您的城市,所以它是String)。

之后,您可以移动用于创建所有天气记录的逻辑,以便在您启动应用程序时创建它们。为此,我们可以实现ApplicationRunner接口:

@Component
public class WeatherInitializer implements ApplicationRunner 
    private WeatherRepository repository;

    public WeatherInitializer(WeatherRepository repository) 
        this.repository = repository;
    

    @Override
    public void run(ApplicationArguments args) 
        Weather a1=new Weather();
        Weather a2=new Weather();
        // Initialize the weather objects like you did in your controller

        // Save all weather records on startup
        repository.saveAll(Arrays.asList(a1, a2, a3, a4, a5));
    

Spring会自动创建这个类的实例,在应用启动时注入WeatherRepository并调用run()方法。

现在您可以重构控制器以使用您的存储库:

@RestController
@RequestMapping("/weather") // All endpoints will have '/weather' in them, so you can put it here
public class WeatherResource 
    private WeatherRepository repository;

    public WeatherResource(WeatherRepository repository) 
        this.repository = repository;
    

    @GetMapping // You can use GetMapping to only allow GET calls
    public List<Weather> getWeather() 
        return repository.findAll(); // This should replace your original implementation
    

现在,对于参数化调用,您必须决定如何发送这些参数,例如:

您可以使用查询参数(如/weather?city=Timbuktu) 您可以使用路径参数(如/weather/Timbuktu) ...

如果你想使用路径参数,你可以使用@PathVariable注解。例如,您可以将此方法添加到您的WeatherResource

@GetMapping("/city")
public Weather getWeather(@PathVariable String city) 
    return repository.findById(city);

通过在我们的路径中使用city 占位符并使用@PathVariable 注释,Spring 将能够将城市名称传递给您的方法。之后,您可以使用repository.findById() 方法获取特定城市的天气。

如果您更愿意使用查询参数,则不需要city 占位符,您必须将@PathVariable 注释替换为@RequestParam 注释:

@GetMapping
public Weather getWeather(@RequestParam String city) 
    return repository.findById(city);

【讨论】:

非常感谢,伙计。你帮了大忙。你实际上已经为我完成了这项工作。我正在尝试尽可能快地学习。如果在 cmets 中有关于这个问题的问题,我可以发布查询吗?再次感谢 @Zer0 它取决于查询。如果这个答案有什么不清楚的地方,你可以在 cmets 中询问,以便我可以在必要时改进我的答案。但是,如果这是一个与使用查询参数无关的新问题,您可能应该提出一个新问题。 Stack Overflow 是关于提出小范围的问答,以便“孤立”地解决问题,也可以帮助未来的读者。如果解决方案隐藏在 cmets 中,那就更难了。 另外,请注意,此代码旨在作为一种学习方式。这当然不是生产就绪的复制粘贴代码。 我很清楚这一点。你的回答给了我一些建议。我能够制作一个基本的应用程序。谢谢! @Zer0 好的,很高兴听到这个消息!我只是有点担心,因为您说我实际上是为您完成了这项工作,当然有些事情必须改变。不过当时好像没必要担心。

以上是关于如何从给定参数中检索查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django 检索多个查询参数值?

如何在iphone中检索给定月份的最后一个日期作为参数

如何从这些给定的表格中检索帖子

角度参数映射与查询参数映射?

如何获取查询字符串的值?

从java中的mysql存储过程中获取参数