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:-
a ListStringHolder do typu, které mohou být uloženy v Místnosti,
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):-