如何为具有多种语言(例如 google 翻译一种)的词汇表应用程序制作数据库?
How to make database for Vocabulary list app with multiple languages like google translate one?
我正在开发一个词汇表应用程序,假设我的应用程序有 2 个多语言单词输入。
例如,用户的母语是韩语,想学英语,所以he/she会在应用设置中选择(Korean/English),学习一个新单词,然后在第一个输入中输入韩语和英语含义在第二个输入中并保存以稍后查看 his/her 单词列表。
我为此制作了一个简单的数据库和模型
@Entity(tableName = "words")
data class Word(
val first_word: String,
val second_word: String,
val bookmarked: Boolean,
@PrimaryKey(autoGenerate = true)
val id: Int
)
但我的问题是如何更改它以支持多种语言但不在一个列表中显示。
Korean/English 个单词将显示在他们的列表中。
Korean/Japanese 单词将显示在他们的列表中并且...
有点像 google 翻译。您选择韩语,然后选择英语,它只会以韩语和英语显示单词。
我不知道如何制作这个数据库,我必须为每两种语言制作多个表格吗?
我希望你明白我想做什么 :)
如果您需要更多信息,请告诉我。
此外,我正在使用 android/kotlin、SQLite 数据库和 Room 库。
在开始编写代码之前,您确实需要考虑设计。
我建议多个 table 没有必要,而且可能会成为障碍。单个 table,至少对于单词,而不是每个语言组合的多个 table。通过指示源语言和目标语言(语言由 table 为语言指定)。
例如,考虑以下 SQLite 代码:-
CREATE TABLE IF NOT EXISTS language (id INTEGER PRIMARY KEY, language TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS wordv1 (id INTEGER PRIMARY KEY, fromLanguage INTEGER REFERENCES language(id), toLanguage INTEGER REFERENCES language(id), fromword TEXT, toword TEXT);
INSERT OR IGNORE INTO language (language)
VALUES('English'),('French'),('German')
;
INSERT OR IGNORE INTO wordv1 (fromlanguage,tolanguage,fromword,toword)
VALUES
(1,2,'Bread','Pain'),
(1,3,'Bread','Brot'),
(1,3,'Milk','Milch'),
(1,2,'Milk','Lait'),
(1,2,'Water','Eau'),
(1,3,'Water','Wasser'),
(3,1,'Haus','House'),
(2,1,'Maison','House')
;
SELECT fromword, toword FROM wordv1 WHERE (tolanguage = 1 OR fromlanguage = 1) AND (tolanguage = 3 OR fromlanguage = 3);
- SELECT 说 select 个包含英语和德语成分的单词 结果是 :-
但是,以上内容并未标准化,例如每次排列都重复牛奶。
要规范化并让一个词只有一个条目,需要多对多的关系,这通常是通过映射实现的 table (许多其他名称,例如交叉参考 table)
要移动到这样的模式,单词 table 本身更简单,只是单词和它的语言。映射 table 将 map/associate/cross 引用一个词和另一种语言中的另一个词。
语言 table 仍将按原样使用。
单词 (wordv2) table 可以简化为:-
CREATE TABLE IF NOT EXISTS wordv2 (id INTEGER PRIMARY KEY, word TEXT, language INTEGER REFERENCES language(id));
在这个阶段可以将单词加载到 table 中以便复制上面的内容(3 种语言的 4 个单词)然后:-
INSERT INTO wordv2 (word,language)
VALUES
('Bread',1),('Milk',1),('Water',1),('House',1),
('Pain',2),('Lait',2),('Eau',2),('Maison',2),
('Brot',3),('Milch',3),('Wasser',3),('Haus',3)
;
映射 table 有两列,每列引用其中一个单词,主键(表示唯一值)将由这两列组合而成。所以这可能是:-
CREATE TABLE IF NOT EXISTS wordtranslatemap (fromword INTEGER REFERENCES wordv2(id),toword INTEGER REFERENCES wordv2(id), CHECK (fromword <> toword), PRIMARY KEY(toword,fromword));
将数据加载到映射 table,(包括双向转换(可能有用也可能没用)例如 Milk->Milch 以及 Milch->Milk)可能是:-
INSERT INTO wordtranslatemap VALUES
(1,5),(5,1),(1,9),(9,1),(5,9),(9,5),
(2,6),(6,2),(2,10),(10,2),(6,10),(10,6),
(3,7),(7,3),(3,11),(11,3),(7,11),(11,7),
(4,8),(8,4),(4,12),(12,4),(8,12),(12,8)
;
注意上面的数字是id列,ASSUMING它们是连续的,从1开始,每插入一次加1。 你 WOULD/SHOULD 不要为应用程序做出这样的假设,通常你会通过提供的用户友好数据(例如单词或语言)获得 ID。
因为 Bread 是插入的第一行,它的 id 很可能是 1, Milk 2 .... ,因此 (1 (Bread), 5 (Pain)) 是英语到法语面包 5,1 是法语到英语(可能是可选的,但它可能会让生活更轻松)。
检索数据有点复杂,例如您可以使用类似的东西:-
SELECT f.word, fl.language, t.word AS , tl.language /* The columns that we want NOTE use of aliases for tables */
FROM wordtranslatemap /* the main table being looked at */
JOIN wordv2 AS f ON wordtranslatemap.toword = f.id /* get the referenced fromWord. give table an alias of f */
JOIN wordv2 AS t ON wordtranslatemap.fromword = t.id /* get the referenced toWord. give table an alias of f */
JOIN language AS fl ON f.language = fl.id /* get the language of the fromWord. alias with fl */
JOIN language AS tl ON t.language = tl.id /* get the language of the toWord. alias with tl */
/*
Alias's required otherwise column references are ambiguous.
See how in the output (as output columns not aliased, they could be) you have word and word(1)
i.e. both output columns are named word the utility has detected them and added a distinction
*/
/* So we want the translation from English to German of all from words that start with Br */
WHERE fl.language = 'English' AND tl.language = 'German' AND f.word Like('Br%')
ORDER BY fl.id,tl.id,f.word,t.word
;
结果是:-
当您设计了架构(tables 和其中的列)后,您可以继续将架构实施到房间中。
我建议始终使用唯一的列名称
将以上内容放入房间(第二次规范化)。
Step1 - 创建 Entities(table 对象,因此 tables)
语言table:-
@Entity
data class Language(
@PrimaryKey
@ColumnInfo(name = "language_id")
var id: Long?=null,
var language: String = ""
)
字table:-
@Entity(
foreignKeys = [
ForeignKey(
entity = Language::class,
parentColumns = ["language_id"],
childColumns = ["language_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
],
indices = [
Index("language_map")
]
)
data class Word(
@PrimaryKey
@ColumnInfo(name = "word_id")
var id: Long?=null,
var word: String="",
@ColumnInfo(name = "language_map")
var language: Long
)
wordtranslatemaptable:-
@Entity(
primaryKeys = ["from_word_map","to_word_map"],
foreignKeys = [
ForeignKey(
entity = Word::class,
parentColumns = ["word_id"],
childColumns = ["from_word_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
ForeignKey(
entity = Word::class,
parentColumns = ["word_id"],
childColumns = ["to_word_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
],
indices = [
Index("to_word_map")
]
)
data class WordTranslateMap(
@ColumnInfo(name = "from_word_map")
val fromWord: Long,
@ColumnInfo(name = "to_word_map")
val toWord: Long
)
接下来是一种提取数据的方法,它结合了来自多个 table 的数据。这些是 POJO classes 即它们没有 @Entity 因为它们不是 tables.
虽然示例中未使用,但通过@Embedded 和@Relation 使用其语言的单词 WordWithLanguage :-
data class WordWithLanguage (
@Embedded
val word: Word,
@Relation(entity = Language::class,parentColumn = "word_id",entityColumn = "language_id")
val language: Language
)
- 在这种情况下,@Relation 注释执行底层 JOIN(实际上它没有,但它通过底层查询模拟 JOIN)
为了反映上面的查询然后另一个 POJO 用于 TranslatedWord :-
data class TransaltedWord(
val from_word: String,
val from_word_id: Long,
val from_language: String,
val from_language_id: Long,
val to_word: String,
val to_word_id: Long,
val to_language: String,
val to_language_id: Long
)
- 请注意,table 中的实际列名并未使用,因此我们要处理不明确的列名。
- 列名将分别分配在各自的@Query
现在我们需要告诉 Room 关于 methods/functions 将与数据库中的 table 进行交互。这些在接口或抽象 classes 中定义,并用 @Dao 注释。对于此示例,单个 class WordConvertDao 是:-
@Dao
abstract class WordConvertDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(language: Language): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(word: Word): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(wordTranslateMap: WordTranslateMap): Long
@Query("SELECT * FROM word")
abstract fun getAllWords(): List<Word>
@Query("SELECT * FROM language")
abstract fun getAllLanguages(): List<Language>
@Transaction
@Query("SELECT * FROM wordtranslatemap")
abstract fun getAllWordTranslateMaps(): List<WordTranslateMap>
@Query("SELECT * FROM word")
abstract fun getAllWordsWithLanguage(): List<WordWithLanguage>
@Query("SELECT " +
"f.word AS from_word, " +
"f.word_id as from_word_id, " +
"fl.language AS from_language, " +
"fl.language_id AS from_language_id, " +
"t.word AS to_word, " +
"t.word_id AS to_word_id, " +
"tl.language AS to_language, " +
"tl.language_id AS to_language_id " +
"FROM wordtranslatemap " +
"JOIN word AS f ON from_word_map = f.word_id " +
"JOIN word AS t ON to_word_map = t.word_id " +
"JOIN language AS fl ON f.language_map = fl.language_id " +
"JOIN language AS tl ON t.language_map = tl.language_id ")
abstract fun getAllTranslatedWords(): List<TransaltedWord>
}
- 尽你所能 see/guess @Insert 用于插入数据,@Query 用于提取数据。最后一个 @Query 等同于上面的 SQLite 查询,注意使用 AS 为列名设置别名以适应 TranslatedWord POJO 的 fields/member/variables.
所有东西都必须通过一个用@Database 注释的抽象 class 放在一起,在这种情况下 TheDatabase :-
@Database(entities = [Language::class,Word::class,WordTranslateMap::class],version = 1)
abstract class TheDatabase: RoomDatabase() {
abstract fun getWordConvertDao(): WordConvertDao
@TypeConverters(Converters::class)
companion object {
@Volatile
private var instance: TheDatabase? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"wordconvert.db")
.allowMainThreadQueries()
.build()
}
return instance as TheDatabase
}
}
}
- 注意 .allowMainThreadQueries 用于brevity/convenience,建议您考虑使用主线程以外的其他线程。
最后,实际做点什么,加载一些数据,然后在 Activity MainActivity 中提取数据:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: WordConvertDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getWordConvertDao()
val english = dao.insert(Language(language = "English"))
val german = dao.insert(Language(language = "German"))
val french = dao.insert(Language(language = "French"))
val bread = dao.insert(Word(word = "Bread",language = english))
val milk = dao.insert(Word(word = "Milk", language = english))
val water = dao.insert(Word(word = "Water", language = english))
val house = dao.insert(Word(word = "House", language = english))
val brot = dao.insert(Word(word = "Brot",language = german))
val milch = dao.insert(Word(word = "Milch", language = german))
val wasser = dao.insert(Word(word = "Wasser",language = german))
val haus = dao.insert(Word(word = "Hause", language = german))
val pain = dao.insert(Word(word = "Pain", language = french))
val lait = dao.insert(Word(word = "Lait", language = french))
val eau = dao.insert(Word(word = "Eau", language = french))
val maison = dao.insert(Word(word = "Maison", language = french))
dao.insert(WordTranslateMap(bread,brot))
dao.insert(WordTranslateMap(brot,bread))
dao.insert(WordTranslateMap(bread,pain))
dao.insert(WordTranslateMap(pain,bread))
dao.insert(WordTranslateMap(pain,brot))
dao.insert(WordTranslateMap(brot,pain))
dao.insert(WordTranslateMap(milk,milch))
dao.insert(WordTranslateMap(milk,lait))
dao.insert(WordTranslateMap(milch,lait))
dao.insert(WordTranslateMap(milch,milk))
dao.insert(WordTranslateMap(lait,milk))
dao.insert(WordTranslateMap(lait,milch))
// etc
// Extract everthing as TranslatedWord's and write the extracted data to the log.
for(t: TransaltedWord in dao.getAllTranslatedWords()) {
Log.d("CONVERTINFO","From=${t.from_word} (${t.from_language}) is ${t.to_word} (${t.to_language})")
}
}
}
结果 :-
D/CONVERTINFO: From=Bread (English) is Brot (German)
D/CONVERTINFO: From=Brot (German) is Bread (English)
D/CONVERTINFO: From=Bread (English) is Pain (French)
D/CONVERTINFO: From=Pain (French) is Bread (English)
D/CONVERTINFO: From=Pain (French) is Brot (German)
D/CONVERTINFO: From=Brot (German) is Pain (French)
D/CONVERTINFO: From=Milk (English) is Milch (German)
D/CONVERTINFO: From=Milk (English) is Lait (French)
D/CONVERTINFO: From=Milch (German) is Lait (French)
D/CONVERTINFO: From=Milch (German) is Milk (English)
D/CONVERTINFO: From=Lait (French) is Milk (English)
D/CONVERTINFO: From=Lait (French) is Milch (German)
我正在开发一个词汇表应用程序,假设我的应用程序有 2 个多语言单词输入。 例如,用户的母语是韩语,想学英语,所以he/she会在应用设置中选择(Korean/English),学习一个新单词,然后在第一个输入中输入韩语和英语含义在第二个输入中并保存以稍后查看 his/her 单词列表。 我为此制作了一个简单的数据库和模型
@Entity(tableName = "words")
data class Word(
val first_word: String,
val second_word: String,
val bookmarked: Boolean,
@PrimaryKey(autoGenerate = true)
val id: Int
)
但我的问题是如何更改它以支持多种语言但不在一个列表中显示。 Korean/English 个单词将显示在他们的列表中。 Korean/Japanese 单词将显示在他们的列表中并且... 有点像 google 翻译。您选择韩语,然后选择英语,它只会以韩语和英语显示单词。 我不知道如何制作这个数据库,我必须为每两种语言制作多个表格吗? 我希望你明白我想做什么 :) 如果您需要更多信息,请告诉我。
此外,我正在使用 android/kotlin、SQLite 数据库和 Room 库。
在开始编写代码之前,您确实需要考虑设计。
我建议多个 table 没有必要,而且可能会成为障碍。单个 table,至少对于单词,而不是每个语言组合的多个 table。通过指示源语言和目标语言(语言由 table 为语言指定)。
例如,考虑以下 SQLite 代码:-
CREATE TABLE IF NOT EXISTS language (id INTEGER PRIMARY KEY, language TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS wordv1 (id INTEGER PRIMARY KEY, fromLanguage INTEGER REFERENCES language(id), toLanguage INTEGER REFERENCES language(id), fromword TEXT, toword TEXT);
INSERT OR IGNORE INTO language (language)
VALUES('English'),('French'),('German')
;
INSERT OR IGNORE INTO wordv1 (fromlanguage,tolanguage,fromword,toword)
VALUES
(1,2,'Bread','Pain'),
(1,3,'Bread','Brot'),
(1,3,'Milk','Milch'),
(1,2,'Milk','Lait'),
(1,2,'Water','Eau'),
(1,3,'Water','Wasser'),
(3,1,'Haus','House'),
(2,1,'Maison','House')
;
SELECT fromword, toword FROM wordv1 WHERE (tolanguage = 1 OR fromlanguage = 1) AND (tolanguage = 3 OR fromlanguage = 3);
- SELECT 说 select 个包含英语和德语成分的单词 结果是 :-
但是,以上内容并未标准化,例如每次排列都重复牛奶。
要规范化并让一个词只有一个条目,需要多对多的关系,这通常是通过映射实现的 table (许多其他名称,例如交叉参考 table)
要移动到这样的模式,单词 table 本身更简单,只是单词和它的语言。映射 table 将 map/associate/cross 引用一个词和另一种语言中的另一个词。
语言 table 仍将按原样使用。
单词 (wordv2) table 可以简化为:-
CREATE TABLE IF NOT EXISTS wordv2 (id INTEGER PRIMARY KEY, word TEXT, language INTEGER REFERENCES language(id));
在这个阶段可以将单词加载到 table 中以便复制上面的内容(3 种语言的 4 个单词)然后:-
INSERT INTO wordv2 (word,language)
VALUES
('Bread',1),('Milk',1),('Water',1),('House',1),
('Pain',2),('Lait',2),('Eau',2),('Maison',2),
('Brot',3),('Milch',3),('Wasser',3),('Haus',3)
;
映射 table 有两列,每列引用其中一个单词,主键(表示唯一值)将由这两列组合而成。所以这可能是:-
CREATE TABLE IF NOT EXISTS wordtranslatemap (fromword INTEGER REFERENCES wordv2(id),toword INTEGER REFERENCES wordv2(id), CHECK (fromword <> toword), PRIMARY KEY(toword,fromword));
将数据加载到映射 table,(包括双向转换(可能有用也可能没用)例如 Milk->Milch 以及 Milch->Milk)可能是:-
INSERT INTO wordtranslatemap VALUES
(1,5),(5,1),(1,9),(9,1),(5,9),(9,5),
(2,6),(6,2),(2,10),(10,2),(6,10),(10,6),
(3,7),(7,3),(3,11),(11,3),(7,11),(11,7),
(4,8),(8,4),(4,12),(12,4),(8,12),(12,8)
;
注意上面的数字是id列,ASSUMING它们是连续的,从1开始,每插入一次加1。 你 WOULD/SHOULD 不要为应用程序做出这样的假设,通常你会通过提供的用户友好数据(例如单词或语言)获得 ID。
因为 Bread 是插入的第一行,它的 id 很可能是 1, Milk 2 .... ,因此 (1 (Bread), 5 (Pain)) 是英语到法语面包 5,1 是法语到英语(可能是可选的,但它可能会让生活更轻松)。
检索数据有点复杂,例如您可以使用类似的东西:-
SELECT f.word, fl.language, t.word AS , tl.language /* The columns that we want NOTE use of aliases for tables */
FROM wordtranslatemap /* the main table being looked at */
JOIN wordv2 AS f ON wordtranslatemap.toword = f.id /* get the referenced fromWord. give table an alias of f */
JOIN wordv2 AS t ON wordtranslatemap.fromword = t.id /* get the referenced toWord. give table an alias of f */
JOIN language AS fl ON f.language = fl.id /* get the language of the fromWord. alias with fl */
JOIN language AS tl ON t.language = tl.id /* get the language of the toWord. alias with tl */
/*
Alias's required otherwise column references are ambiguous.
See how in the output (as output columns not aliased, they could be) you have word and word(1)
i.e. both output columns are named word the utility has detected them and added a distinction
*/
/* So we want the translation from English to German of all from words that start with Br */
WHERE fl.language = 'English' AND tl.language = 'German' AND f.word Like('Br%')
ORDER BY fl.id,tl.id,f.word,t.word
;
结果是:-
当您设计了架构(tables 和其中的列)后,您可以继续将架构实施到房间中。
我建议始终使用唯一的列名称
将以上内容放入房间(第二次规范化)。
Step1 - 创建 Entities(table 对象,因此 tables)
语言table:-
@Entity
data class Language(
@PrimaryKey
@ColumnInfo(name = "language_id")
var id: Long?=null,
var language: String = ""
)
字table:-
@Entity(
foreignKeys = [
ForeignKey(
entity = Language::class,
parentColumns = ["language_id"],
childColumns = ["language_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
],
indices = [
Index("language_map")
]
)
data class Word(
@PrimaryKey
@ColumnInfo(name = "word_id")
var id: Long?=null,
var word: String="",
@ColumnInfo(name = "language_map")
var language: Long
)
wordtranslatemaptable:-
@Entity(
primaryKeys = ["from_word_map","to_word_map"],
foreignKeys = [
ForeignKey(
entity = Word::class,
parentColumns = ["word_id"],
childColumns = ["from_word_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
ForeignKey(
entity = Word::class,
parentColumns = ["word_id"],
childColumns = ["to_word_map"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
],
indices = [
Index("to_word_map")
]
)
data class WordTranslateMap(
@ColumnInfo(name = "from_word_map")
val fromWord: Long,
@ColumnInfo(name = "to_word_map")
val toWord: Long
)
接下来是一种提取数据的方法,它结合了来自多个 table 的数据。这些是 POJO classes 即它们没有 @Entity 因为它们不是 tables.
虽然示例中未使用,但通过@Embedded 和@Relation 使用其语言的单词 WordWithLanguage :-
data class WordWithLanguage (
@Embedded
val word: Word,
@Relation(entity = Language::class,parentColumn = "word_id",entityColumn = "language_id")
val language: Language
)
- 在这种情况下,@Relation 注释执行底层 JOIN(实际上它没有,但它通过底层查询模拟 JOIN)
为了反映上面的查询然后另一个 POJO 用于 TranslatedWord :-
data class TransaltedWord(
val from_word: String,
val from_word_id: Long,
val from_language: String,
val from_language_id: Long,
val to_word: String,
val to_word_id: Long,
val to_language: String,
val to_language_id: Long
)
- 请注意,table 中的实际列名并未使用,因此我们要处理不明确的列名。
- 列名将分别分配在各自的@Query
现在我们需要告诉 Room 关于 methods/functions 将与数据库中的 table 进行交互。这些在接口或抽象 classes 中定义,并用 @Dao 注释。对于此示例,单个 class WordConvertDao 是:-
@Dao
abstract class WordConvertDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(language: Language): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(word: Word): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(wordTranslateMap: WordTranslateMap): Long
@Query("SELECT * FROM word")
abstract fun getAllWords(): List<Word>
@Query("SELECT * FROM language")
abstract fun getAllLanguages(): List<Language>
@Transaction
@Query("SELECT * FROM wordtranslatemap")
abstract fun getAllWordTranslateMaps(): List<WordTranslateMap>
@Query("SELECT * FROM word")
abstract fun getAllWordsWithLanguage(): List<WordWithLanguage>
@Query("SELECT " +
"f.word AS from_word, " +
"f.word_id as from_word_id, " +
"fl.language AS from_language, " +
"fl.language_id AS from_language_id, " +
"t.word AS to_word, " +
"t.word_id AS to_word_id, " +
"tl.language AS to_language, " +
"tl.language_id AS to_language_id " +
"FROM wordtranslatemap " +
"JOIN word AS f ON from_word_map = f.word_id " +
"JOIN word AS t ON to_word_map = t.word_id " +
"JOIN language AS fl ON f.language_map = fl.language_id " +
"JOIN language AS tl ON t.language_map = tl.language_id ")
abstract fun getAllTranslatedWords(): List<TransaltedWord>
}
- 尽你所能 see/guess @Insert 用于插入数据,@Query 用于提取数据。最后一个 @Query 等同于上面的 SQLite 查询,注意使用 AS 为列名设置别名以适应 TranslatedWord POJO 的 fields/member/variables.
所有东西都必须通过一个用@Database 注释的抽象 class 放在一起,在这种情况下 TheDatabase :-
@Database(entities = [Language::class,Word::class,WordTranslateMap::class],version = 1)
abstract class TheDatabase: RoomDatabase() {
abstract fun getWordConvertDao(): WordConvertDao
@TypeConverters(Converters::class)
companion object {
@Volatile
private var instance: TheDatabase? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"wordconvert.db")
.allowMainThreadQueries()
.build()
}
return instance as TheDatabase
}
}
}
- 注意 .allowMainThreadQueries 用于brevity/convenience,建议您考虑使用主线程以外的其他线程。
最后,实际做点什么,加载一些数据,然后在 Activity MainActivity 中提取数据:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: WordConvertDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getWordConvertDao()
val english = dao.insert(Language(language = "English"))
val german = dao.insert(Language(language = "German"))
val french = dao.insert(Language(language = "French"))
val bread = dao.insert(Word(word = "Bread",language = english))
val milk = dao.insert(Word(word = "Milk", language = english))
val water = dao.insert(Word(word = "Water", language = english))
val house = dao.insert(Word(word = "House", language = english))
val brot = dao.insert(Word(word = "Brot",language = german))
val milch = dao.insert(Word(word = "Milch", language = german))
val wasser = dao.insert(Word(word = "Wasser",language = german))
val haus = dao.insert(Word(word = "Hause", language = german))
val pain = dao.insert(Word(word = "Pain", language = french))
val lait = dao.insert(Word(word = "Lait", language = french))
val eau = dao.insert(Word(word = "Eau", language = french))
val maison = dao.insert(Word(word = "Maison", language = french))
dao.insert(WordTranslateMap(bread,brot))
dao.insert(WordTranslateMap(brot,bread))
dao.insert(WordTranslateMap(bread,pain))
dao.insert(WordTranslateMap(pain,bread))
dao.insert(WordTranslateMap(pain,brot))
dao.insert(WordTranslateMap(brot,pain))
dao.insert(WordTranslateMap(milk,milch))
dao.insert(WordTranslateMap(milk,lait))
dao.insert(WordTranslateMap(milch,lait))
dao.insert(WordTranslateMap(milch,milk))
dao.insert(WordTranslateMap(lait,milk))
dao.insert(WordTranslateMap(lait,milch))
// etc
// Extract everthing as TranslatedWord's and write the extracted data to the log.
for(t: TransaltedWord in dao.getAllTranslatedWords()) {
Log.d("CONVERTINFO","From=${t.from_word} (${t.from_language}) is ${t.to_word} (${t.to_language})")
}
}
}
结果 :-
D/CONVERTINFO: From=Bread (English) is Brot (German)
D/CONVERTINFO: From=Brot (German) is Bread (English)
D/CONVERTINFO: From=Bread (English) is Pain (French)
D/CONVERTINFO: From=Pain (French) is Bread (English)
D/CONVERTINFO: From=Pain (French) is Brot (German)
D/CONVERTINFO: From=Brot (German) is Pain (French)
D/CONVERTINFO: From=Milk (English) is Milch (German)
D/CONVERTINFO: From=Milk (English) is Lait (French)
D/CONVERTINFO: From=Milch (German) is Lait (French)
D/CONVERTINFO: From=Milch (German) is Milk (English)
D/CONVERTINFO: From=Lait (French) is Milk (English)
D/CONVERTINFO: From=Lait (French) is Milch (German)