目前我正在一个类中创建greenDAO数据库连接(在每个静态方法中打开连接)并在我需要的地方使用它。但我不确定这是否是最佳方式。 任何人都可以建议一个更好的方法吗?
我的代码:
import com.knowlarity.sr.db.dao.DaoMaster;
import com.knowlarity.sr.db.dao.DaoMaster.DevOpenHelper;
import com.knowlarity.sr.db.dao.DaoSession;
import com.knowlarity.sr.db.dao.IEntity;
public class DbUtils {
private static Object lockCallRecord =new Object();
private DbUtils(){};
public static boolean saveEntity(Context context , IEntity entity){
boolean t=false;
DevOpenHelper helper=null;
SQLiteDatabase db=null;
DaoMaster daoMaster=null;
DaoSession daoSession =null;
try{
helper = new DaoMaster.DevOpenHelper(context, IConstant.DB_STRING, null);
db = helper.getReadableDatabase();
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
//Some business logic here for fetching and inserting the data.
}catch (Exception e){
Log.e("saveEntity", e.getStackTrace().toString());
}finally{
if(daoSession!=null)daoSession.clear();
daoMaster=null;
if(db.isOpen())db.close();
helper.close();
}
return t;
}
答案 0 :(得分:10)
您的方法导致数据库经常被加载,这是不必要的,并且可能会显着减慢您的应用程序。
打开数据库一次并将其存储在某处,并在需要时从那里请求。
我个人使用全球DaoSession
和本地DaoSession
。本地DaoSession
被用于会话缓存中不应该保留任何内容(即将新对象持久存储到数据库中,这可能只是很少使用或执行某些查询会加载很多实体不太可能再次重复使用)。
请注意,如果您在全局会话中使用该实体,则更新本地DaoSession
中的实体也是一个坏主意。如果这样做,全局会话中的缓存实体将不会更新,除非您清除全局会话的缓存,否则您将得到错误的结果!
因此,最安全的方法是始终只使用一个DaoSession
或新DaoSession
,并且不使用全局和本地会话!!!
自定义应用程序类是个好地方,但任何其他类也都可以。
我就是这样做的:
类DBHelper:
private SQLiteDatabase _db = null;
private DaoSession _session = null;
private DaoMaster getMaster() {
if (_db == null) {
_db = getDatabase(DB_NAME, false);
}
return new DaoMaster(_db);
}
public DaoSession getSession(boolean newSession) {
if (newSession) {
return getMaster().newSession();
}
if (_session == null) {
_session = getMaster().newSession();
}
return _session;
}
private synchronized SQLiteDatabase getDatabase(String name, boolean readOnly) {
String s = "getDB(" + name + ",readonly=" + (readOnly ? "true" : "false") + ")";
try {
readOnly = false;
Log.i(TAG, s);
SQLiteOpenHelper helper = new MyOpenHelper(context, name, null);
if (readOnly) {
return helper.getReadableDatabase();
} else {
return helper.getWritableDatabase();
}
} catch (Exception ex) {
Log.e(TAG, s, ex);
return null;
} catch (Error err) {
Log.e(TAG, s, err);
return null;
}
}
private class MyOpenHelper extends DaoMaster.OpenHelper {
public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "Create DB-Schema (version "+Integer.toString(DaoMaster.SCHEMA_VERSION)+")");
super.onCreate(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Update DB-Schema to version: "+Integer.toString(oldVersion)+"->"+Integer.toString(newVersion));
switch (oldVersion) {
case 1:
db.execSQL(SQL_UPGRADE_1To2);
case 2:
db.execSQL(SQL_UPGRADE_2To3);
break;
default:
break;
}
}
}
在应用程序类中:
private static MyApplication _INSTANCE = null;
public static MyApplication getInstance() {
return _INSTANCE;
}
@Override
public void onCreate() {
_INSTANCE = this;
// ...
}
private DBHelper _dbHelper = new DBHelper();
public static DaoSession getNewSession() {
return getInstance()._dbHelper.getSession(true);
}
public static DaoSession getSession() {
return getInstance()._dbHelper.getSession(false);
}
当然你也可以存储DaoMaster而不是DB本身。这将减少一些小的开销。
每次使用一些常用方法(比如访问数据库)时,我都在使用类似Singleton的Application类和静态方法来避免转换应用程序(((MyApplication)getApplication())
)。
答案 1 :(得分:0)
我建议您在Application类中创建数据库。然后,您可以创建一个方法来返回DaoSession以访问其他活动中的数据库。