Android Studio 如何在房间数据库中存储 API 数据并按城市名称检索?

Android Studio how to store API data in room database and retrieve by city name?

Android Studio 如何在房间数据库中存储 API 数据并按城市名称检索? 我想将从 API 获得的数据保存到房间数据库中。那我怎样才能按城市名称提取数据呢? 我正在 android 中创建一个 SQLite 数据库,以将来自 JSON 的数据存储在数据库中,以便在应用程序离线时查看数据。

public interface WeatherAPI {
    @GET("forecast?")
    Single<WeatherModel> getData(@Query("q") String name, @Query("APPID") String app_id);
}

我的模型

@Entity(tableName = "Places")
public class WeatherModel  {
    @ColumnInfo(name = "cod")
    @SerializedName("cod")
    public String cod;
    @SerializedName("message")
    public int message;
    @SerializedName("cnt")
    public int cnt;
    @SerializedName("list")
    public List<list> list;
    @SerializedName("city")
    public City city;

    public class Main{
        @SerializedName("temp")
        public double temp;
        @SerializedName("feels_like")
        public double feels_like;
        @SerializedName("temp_min")
        public double temp_min;
        @SerializedName("temp_max")
        public double temp_max;
        @SerializedName("pressure")
        public int pressure;
        @SerializedName("sea_level")
        public int sea_level;
        @SerializedName("humidity")
        public int humidity;
        @SerializedName("temp_kf")
        public double temp_kf;
    }

    public City getCity(){
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    public class Weather{
        @SerializedName("id")
        public int id;
        @SerializedName("main")
        public String main;
        @SerializedName("description")
        public String description;
        @SerializedName("icon")
        public String icon;
    }

    public class Clouds{
        @SerializedName("all")
        public int all;
    }

    public class Wind{
        @SerializedName("speed")
        public double speed;
        @SerializedName("deg")
        public int deg;
        @SerializedName("gust")
        public double gust;
    }

    public class Sys{
        @SerializedName("pod")
        public String pod;
    }

    public class Rain{
        @SerializedName("3h")
        public double _3h;
    }

    public class list{
        @SerializedName("dt")
        public int dt;
        @SerializedName("main")
        public Main main;
        @SerializedName("weather")
        public List<Weather> weather;
        @SerializedName("clouds")
        public Clouds clouds;
        @SerializedName("wind")
        public Wind wind;
        @SerializedName("visibility")
        public int visibility;
        @SerializedName("pop")
        public double pop;
        @SerializedName("sys")
        public Sys sys;
        @SerializedName("dt_txt")
        public String dt_txt;
        @SerializedName("rain")
        public Rain rain;
    }

    public class Coord{
        @SerializedName("lon")
        public double lon;
        @SerializedName("lat")
        public double lat;
    }

    public class City{
        public int id;
        @SerializedName("name")
        public String name;
        public Coord coord;
        public String country;
        public int population;
        public int timezone;
        public int sunrise;
        public int sunset;
    }

    public WeatherModel(String cod, int message, int cnt, List<WeatherModel.list> list, City city) {
        this.cod = cod;
        this.message = message;
        this.cnt = cnt;
        this.list = list;
        this.city = city;
    }
}
@Dao
public interface PlacesDao {

    @Query("SELECT * FROM Places")
    Single<WeatherModel> getAll();

    @Insert
    io.reactivex.Completable insert(WeatherModel weatherModel);

    @Delete
    io.reactivex.Completable delete(WeatherModel weatherModel);

    @Update
    io.reactivex.Completable  upDate(WeatherModel weatherModel);
}

首先假设您想要按照您的模型存储数据,您将需要 Type converters 用于 WeatherModel class(又名地点 table)中的所有列不是字符串类型、整数类型(long、Long、int、Int 等)、小数类型(float、double Float、Double 等)或字节数组;将它们转换成这样的类型。

  • 即列表和城市。

通常这些转换器会将类型转换为字符串作为 JSON 字符串(可能会使用字节数组,不太可能(不可能?)将此类对象表示为整数或小数值) .

但是,生成的字符串并不能完全帮助按城市名称进行检索。那就是城市列中的数据类似于:-

这是您可能开始遇到困难的地方,假设您想在上述数据中搜索 *New York

然后简单地使用一个使用 .... WHERE instr(city,'New York') > 0 的查询,它本身超出了一些人可能熟悉的范围,例如在房间里可能是:-

@Query("SELECT * FROM places WHERE instr(city,:cityname) > 0")
List<WeatherModel> getByCityNameV1(String cityname);
  • WHERE city LIKE '%'||:cityname||'%'" 与 instr 函数类似,但不区分大小写。

这将只得到包含纽约的第 1 行(第一行)(根据上面的数据)。

但是 如果上述查询用于约克,那么它将 return 纽约(第一行)和约克,第二行。

要最终找到 York,您至少需要搜索 "York" 并希望没有其他可能冲突的值,更安全的选择是搜索 name":"York","。现在您已经介绍了双引号的复杂性,这可能会带来问题,因此对于这个简单的任务,您将以以下方式结束:-

@Query("SELECT * FROM places WHERE instr(city,'name'||char(34)||':'||char(34)||:cityname||char(34)) > 0")
List<WeatherModel> getByCityNameV2(String cityname);