我试图插入值到房间数据库,但它不工作,我检查了数据库,表没有创建。我已经创建了数据库,DAO和Java存储库,并在MainActivity Kotlin类的协程内调用插入dao。
DAO
@Insert
public void addExpense(List<Expenses> exp);
储存库
public class Repository {
private ExpensesDao expensesDao;
private SubscriptionsDao subscriptionsDao;
private static AppDatabase db;
public Repository(Context context) {
initDb(context);
expensesDao = db.expensesDao();
subscriptionsDao = db.subscriptionsDao();
}
private static void initDb(Context context) {
if (db == null) {
db = Room.databaseBuilder(
context,
AppDatabase.class, "local_db"
)
.addMigrations(AppDatabase.DbMigration)
.build();
}
}
public void addExpense(List<Expenses> exp) {
expensesDao.addExpense(exp);
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var firstRun = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db = Repository(applicationContext)
var spacesList: List<String> = listOf("No Spaces Found")
var expList: List<Expenses> = listOf(
Expenses("dummy", LocalDate.now().toString(), 12.22, "dummy1"),
Expenses("dummy", LocalDate.now().toString(), 12.22, "dummy2"),
Expenses("dummy", LocalDate.now().toString(), 13.22, "dummy3"),
Expenses("dummy", LocalDate.now().toString(), 14.22, "dummy4"),
Expenses("dummy", LocalDate.now().toString(), 15.22, "dummy5"),
Expenses("dummy", LocalDate.now().toString(), 16.22, "dummy6")
)
CoroutineScope(Dispatchers.IO).launch {
// the insert call
val x = db.addExpense(expList)
println("-->> "+x.toString())
}
val tempSpacesList = db.getAllSpaces().value
if (tempSpacesList?.isEmpty() == true) {
spacesList = tempSpacesList
}
}
}
- 编辑**
@Entity
public class Expenses {
public Expenses(String space, String date, double amount, String description) {
this.uid = uid;
this.space = space;
this.date = date;
this.amount = amount;
this.description = description;
}
@PrimaryKey(autoGenerate = true)
int uid;
@ColumnInfo(name = "space")
String space;
@ColumnInfo(name = "date")
String date;
@ColumnInfo(name = "amount")
double amount;
@ColumnInfo(name = "description")
String description;
}
logcat(这里不多..)
15:11:55.340 E Could not remove dir '/data/data/org.android.app/code_cache/.ll/': No such file or directory
- 这是不是插刀的正确使用方法?
- 我可以在此实现上做哪些改进?
1条答案
按热度按时间ni65a41a1#
您的代码(较少使用Subscirptions和getAllApaces),即MainActivity为:-
与AppInspection配合使用,显示:-
已做出以下假设:
:-
:-
:-
这是不是插刀的正确使用方法?
是的
我可以在此实现上做哪些改进?
您可以消除
autoGenerate=true
的低效使用,它实际上不会导致自动生成,而是添加了**AUTOINCREMENT
**关键字,但接受0作为非0,而是将0的值解释为无值,从而生成值。这就是你可以使用:-
autoGenerate=true
引入了一个约束条件(规则),它强制生成的值大于任何曾经使用过的值,并且基于每个表。如果没有AUTOINCRMENT,生成的值将比当前最大值大1,因此允许重用已删除的行的值。低效之处在于,SQLite创建了一个名为sqlite_sequence的表,用于存储分配的最高值,以了解已存在的行的值。每当生成值时,都需要读取并更新此附加表,因此documentation表示
AUTOINCREMENT关键字会增加额外的CPU、内存、磁盘空间和磁盘I/O开销,如果不是非常需要,应该避免使用。通常不需要使用该关键字。
以下是使用
autoGenerate=true
时的所有表格(再次使用App Inspection)根据建议删除
autoGenerate=true
,则此外,实际生成的值非常有用,因为它唯一标识行(特别是在使用表之间的关系时)。您可以在插入一行或多行时获取此值,但它将作为long类型而不是int类型返回。您还可以在插入多行时检索值数组,再次使用long类型而不是int类型。因此,您可以使用:-
@Insert(onConflict = OnConflictStrategy.IGNORE)
,则如果行由于可忽略的冲突(例如重复)而被IGNOREd,则该插入的值将为-1。根据建议的更改,App Inspection将显示:-
即无明显差异,已添加数据(卸载应用程序,删除整个数据库)