Jak dát název sloupce, který je vyhrazené klíčové slovo v Kotlin třídy dat (Pokojová jednotka)?

0

Otázka

Mám dat Entity třídy s název proměnné 'abstraktní' . Tak je to rezervované slovo jeho ukazující chyba při ukládání do databáze. Jak mohu uložit jako názvy sloupců, které jsou vyhrazená klíčová slova?

Níže je uveden třídy entity

package com.nyt.model

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable

@Entity
data class Article (
    val `abstract`: String?="",
    val adx_keywords: String?="",
    val asset_id: Long?=0,
    val byline: String?="",
    val column: String?="",
    val des_facet: List<String>?= emptyList(),
    val eta_id: Int?=0,
    val geo_facet: List<String>?= emptyList(),
    @PrimaryKey
    val id: Long?=0,
    val media: List<Media>?= emptyList(),
    val nytdsection: String?="",
    val org_facet: List<String>?= emptyList(),
    val per_facet: List<String>?= emptyList(),
    val published_date: String?="",
    val section: String?="",
    val source: String?="",
    val subsection: String?="",
    val title: String?="",
    val type: String?="",
    val updated: String?="",
    val uri: String?="",
    val url: String?=""
):Serializable
android-room data-class entity kotlin
2021-11-14 10:42:32
1
1

Můžete použít zadní klíšťata, aby se vyhnuli zvláštní význam různých symbolů.

Například, můžete vytvořit všechny tyto fantazie jména:

val `while` = 5

class `class name with spaces` {

}

fun `do fun while in class`() {

}

Ve vašem případě, můžete to udělat to takhle:

data class MyEntity(
    val `abstract`: ItsDataType
)
2021-11-14 12:06:10

Už jsem se snažil to tak. Ale to je stále dává chybu.
DroidBee

Co je to chyba?
Arpit Shukla

"chyba: Nelze najít seřizovač pro pole. soukromé final java.lang.Řetězec adx_keywords = null;" . Tato chyba je zobrazena s ostatními proměnnými v datech třídy . Ale když jsem přejmenovat "abstrakt" na něco jiného, chyba je pryč.
DroidBee
1

I když můžete umístit zpět klíšťata kolem abstrakt tato pak představí problémů. To je silně navrhl, že budete používat alternativní např. abstrct nebo synonymum.

Můžete mít vždy sloupci název sám o sobě jako abstraktní pomocí @ColumnInfo anotace např. :-

@ColumnInfo(name = "abstract")
val abstrct: String?="",
  • Z malého testování, pokud abstraktní (uzavřený v zadní klíšťata) je použit sloupec sama o sobě není získat generované v hlubších vygenerovaný kód a alespoň část důvod, proč používat na zadní klíšťata, není řešení.

  • Trvalý problém je možná, že pokoj zábaly názvy sloupců v zadní klíšťata, takže zpět klíšťata objeví dvakrát, a proto jsou ignorovány a pak abstraktní klíčové slovo přichází do hry, a tak je pak ignorován jako sloupec. Podpis Čl. třídy pak není co Místnosti očekává, takže se očekává, getry a setry.

    • Pokoj zábaly názvy sloupců v zadní klíšťata, tak, že názvy sloupců nejsou v rozporu s SQLite klíčová slova.
  • s abstrct uzavřený v zadní klíšťata, pak Pokoji vytvoří následující SQL (pouze část QL obrázku) vytvořit Článek tabulka CREATE TABLE IF NOT EXISTS IF NOT EXISTS Článek (abstrctTEXT,adx_keywordsTEXT,asset_id INTEGER.

  • Nicméně s abstraktní uzavřený v zadní klíšťata, pak SQL je CREATE TABLE IF NOT EXISTS IF NOT EXISTS Článek (adx_keywordsTEXT,asset_id INTEGER, (tj. abstraktní sloupec byl vynechán).

Změna k použití abstrct pak upozorňuje i na další problémy, všechny v podstatě stejné. To znamená, že nemůže mít sloupce (vals/vars v Subjektu), které jsou přímo Seznam/Pole atd.

Jako takový, budete mít problémy s des_facet, geo_facet, org_facet, per_facet a media vals.

Pokud chcete uložit Seznam/Pole atd pak můžete využít třídu, která obsahuje Seznam/Pole atd.

Takže pokud jste měli například:-

data class ListStringHolder (
    val listString: List<String> = emptyList()
)

pak byste mohl mít :-

val des_facet: ListStringHolder = ListStringHolder()

Nicméně, pak je třeba TypeConverters převést Seznam/Pole na hodnotu, která může být uloženy v databázi

  • omezena na SQLite úrovni na celé ČÍSLO (např. Dlouhý,Int,Byte,Short a Boolean), SKUTEČNÝ (např. Float/Double), TEXT (String) nebo BLOB (ByteArray)

    • SQlite má ČÍSELNÉ catch-all typu, ale Pokoj nepodporuje použití.

proto je třeba:-

  1. a ListStringHolder do typu, které mohou být uloženy v Místnosti,

  2. z uložené hodnoty do ListStringHolder objekt

Pro objekty, typicky Řetězec, který by mohl být JSON reprezentace ListStringHolder objektu.

například byste mohli mít třídu s názvem Konvertory :-

@TypeConverter
fun fromListStringHolder(lsh: ListStringHolder): String {
    return Gson().toJson(lsh)
}

@TypeConverter
fun toListStringHolder(lsh: String): ListStringHolder {
    return Gson().fromJson(lsh,ListStringHolder::class.java)
}

Musíte definovat TypeConverters do Místnosti pomocí @TypeConverters (poznámka: množné číslo) anotace. Můžete použít @TypeConverters anotace na různých úrovních (tím se nastaví rozsah měniče). Nejvhodnější úroveň je na @Databáze úroveň (rozsah je celá databáze), takže by si něco v duchu:-

@Database(entities = [Article::class], version = DB_Constants.DB_VERSION)
@TypeConverters(Converters::class)
....

Takže použití :-

@Entity
data class Article (
    val abstrct: String?="",
    val adx_keywords: String?="",
    val asset_id: Long?=0,
    val byline: String?="",
    val column: String?="",
    //val des_facet: List<String>?= emptyList(),
    val des_facet: ListStringHolder = ListStringHolder(), //<<<<<
    val eta_id: Int?=0,
    //val geo_facet: List<String>?= emptyList(),
    val geo_facet: ListStringHolder = ListStringHolder(), //<<<<<
    @PrimaryKey
    val id: Long?=0,
    //val media: List<Media>?= emptyList(),
    val media: ListMediaHolder = ListMediaHolder(), //<<<<<
    val nytdsection: String?="",
    //val org_facet: List<String>?= emptyList(),
    val org_facet: ListStringHolder = ListStringHolder(), //<<<<<
    //val per_facet: List<String>?= emptyList(),
    val per_facet: ListStringHolder = ListStringHolder(), //<<<<<
    val published_date: String?="",
    val section: String?="",
    val source: String?="",
    val subsection: String?="",
    val title: String?="",
    val type: String?="",
    val updated: String?="",
    val uri: String?="",
    val url: String?=""
):Serializable
  • ListMediaHolder zacházeno podobným způsobem, s TypeConverters

Pracovní Příklad

Pak se s výše a ArticleDao jako :-

@Dao
interface ArticleDao {

    @Insert
    fun insert(article: Article): Long
    @Query("SELECT * FROM article")
    fun getAllArticles(): List<Article>
}

A následující činnosti (zmínku, že pro pohodlí a stručnost .allowMainThreadQueries byl použit) :-

    articleDao = db.getArticleDao()

    var lsh1 = ListStringHolder(listOf<String>("A"))
    val lsh2 = ListStringHolder(listOf("D","E","F"))

    articleDao.insert(
        Article(abstrct = "abs1",
            adx_keywords = "adxkey1",
            byline = "byline1",
            column = "column1",
            des_facet = lsh1,
            geo_facet = lsh1,id = null, media = ListMediaHolder(emptyList()), org_facet = lsh1,per_facet = lsh1))
    articleDao.insert(
        Article(abstrct = "abs2",
            adx_keywords = "adxkey2",
            byline = "byline2",
            column = "column2",
            des_facet = lsh2,
            geo_facet = lsh1,id = null, media = ListMediaHolder(emptyList()), org_facet = lsh2,per_facet = lsh1))

    for(a: Article in articleDao.getAllArticles()) {
        Log.d("ARTICLEINFO","Article abstract = ${a.abstrct} number of des_facets = ${a.des_facet.listString.size} they are:-")
        for(s: String in a.des_facet.listString) {
            Log.d("ARTICLEINFO","\t$s")
        }

Při spuštění záznamu obsahuje :-

D/ARTICLEINFO: Article abstract = abs1 number of des_facets = 1 they are:-
D/ARTICLEINFO:  A
D/ARTICLEINFO: Article abstract = abs2 number of des_facets = 3 they are:-
D/ARTICLEINFO:  D
D/ARTICLEINFO:  E
D/ARTICLEINFO:  F

Samotná databáze obsahuje následující údaje (získané pomocí AppInspection aka Inspektor Databáze):-

enter image description here

2021-11-14 11:17:53

Děkuji moc za podrobné vysvětlení s příklady. Nicméně , problém tato data třídy je model třídy pro json vrátil od třetí strany API . Takže když změním název sloupce , json není stále mapovány s daty třídy. Jak to mohu vyřešit ?
DroidBee

@DroidBee Možností by mohlo být) proces json soubor/stream nahrazuje abstraktní, b) použít json converter pro přemapování jméno c) další POJO třídy s identickými obory bar abstrct, pojmenování abstraktní místo, poskytovat funkce pro sestavení Článek od něj, vyložit, aby POJO běh přes POJO je vytvoření Článku.
MikeT

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................