我完全能够使用提供的示例使用Sugar ORM。
在我的用例中,我从服务器下载一个SQLite数据库(ETL加载它的数百万条记录,因此必须在服务器端完成)。下载保存到内部存储上的自定义路径。
在我的情况下,我不需要基于POCO创建动态数据库。
是否可以将Sugar ORM与预先存在的SQLite DB一起使用,指向自定义路径,前提是所有POCO类字段是否与表结构匹配?
答案 0 :(得分:4)
首先,我对Sugar的想法感到不舒服 app类。如果我还有其他任务需要执行怎么办? 在app开始之前?!所以让我们用自己的方式扩展SugarApp 然后,AppClass在清单中注册appClass名称。此外,这是我第一次相信init db的正确位置。
public class MyAppStartClass extends SugarApp {
@Override
public final void onCreate() {
init();
super.onCreate();
}
private void init() {
initDB();
}
private void initDB() {
try {
if (!doesDatabaseExist(this, consts.dbPath)) {
Context context = getApplicationContext();
SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName, context.MODE_PRIVATE, null);
db.close();
InputStream dbInput = getApplicationContext().getAssets().open(consts.dbName);
String outFileName = consts.dbPath;
OutputStream dbOutput = new FileOutputStream(outFileName);
try {
byte[] buffer = new byte[1024];
int length;
while ((length = dbInput.read(buffer)) > 0) {
dbOutput.write(buffer, 0, length);
}
} finally {
dbOutput.flush();
dbOutput.close();
dbInput.close();
}
}
} catch (Exception e) {
e.toString();
}
}
private boolean doesDatabaseExist(ContextWrapper context, String dbName) {
File dbFile = context.getDatabasePath(dbName);
return dbFile.exists();
}
}
Manifest:android:name =“com.myPackageName.MyAppStartClass”
确保首先创建一个空数据库,否则你将从FileOutputStream()和dbPath = /data/data/com.myPackageName/databases/myDb.db(/p)收到错误>
SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName,context.MODE_PRIVATE,null);
db.close();
确保您的现有数据库架构具有主键列ID。哦耶! Sugar只将ID视为检索数据的主键。
如果你想使用现有的表,在扩展SugarRecord时不要指定T,你必须添加Sugar作为模块,你的项目依赖于它!
public class Book extends SugarRecord {
String title;
String edition;
public Book(){
}
public Book(String title, String edition){
this.title = title;
this.edition = edition;
}
}
6.如果您想使用现有表格。请注意,Sugar会查找大写列名称,因此如果现有的表列名称为小写,则永远不会从中获取任何现有数据!
7.这让我得出了一个不情愿的结论:如果你从头开始db并使用它来为你生成db和table,那么Sugar就很棒。但是当你已经有一个包含数据的现有数据库时,情况并非如此。
答案 1 :(得分:3)
我找到的解决方案是将您的db文件放在assets文件夹中。而不是读取.csv文件来创建.db文件(当你开始正确的活动时)首先尝试检查.db文件是否在/data/data/file.db中,如果它不是,复制它从您的资源文件夹到该路径。使用下一个代码,您将能够完成所有操作:
protected void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = getApplicationContext().getAssets().open("file.db");
// Path to the just created empty db
String outFileName = "/data/data/com.yourpackagename/databases/" + "file.db";
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
protected boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = "/data/data/com.yourpackage/databases/" + "file.db";
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
答案 2 :(得分:1)
我还没有尝试过。但是,如果您可以将数据库文件复制到/data/data//db_name.db位置并使用相同的db_name&清单中的糖配置中的db版本,它应该只是拿起它。