如何从给定参数中检索查询?
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<Weather, String>
的泛型是您的实体类和主键的类型(这是您的城市,所以它是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 好的,很高兴听到这个消息!我只是有点担心,因为您说我实际上是为您完成了这项工作,当然有些事情必须改变。不过当时好像没必要担心。以上是关于如何从给定参数中检索查询?的主要内容,如果未能解决你的问题,请参考以下文章