Каков наилучший способ создания подключения к базе данных greenDAO только один раз для одного запуска приложения?
В настоящее время я создаю соединение с базой данных 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;
}
2 ответа
Ваш подход приводит к тому, что база данных загружается очень часто, что не является необходимым и может значительно замедлить работу вашего приложения.
Откройте базу данных один раз, сохраните ее где-нибудь и запросите ее оттуда, если необходимо.
Лично я пользуюсь глобальным DaoSession
и местный DaoSession
s. Местный DaoSession
s используются там, где ничего не должно оставаться в кэше сеанса (т. е. при сохранении нового объекта в базе данных, который, вероятно, будет использоваться только очень редко, или при выполнении некоторых запросов, которые будут загружать множество объектов, которые вряд ли будут снова использованы повторно).
Имейте в виду, что обновление сущностей в локальном DaoSession
плохая идея, если вы используете сущность и в глобальном сеансе. Если вы сделаете это, кэшированная сущность в вашем глобальном сеансе не будет обновлена, и вы получите неверные результаты, если не очистите кэш глобального сеанса!
Таким образом, самый безопасный способ это либо просто использовать один DaoSession
или новый DaoSession
s все время и не использовать глобальные и локальные сеансы!!!
Пользовательский класс приложения - это хорошее место, но любой другой класс тоже подойдет.
Вот как я это делаю:
Класс 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 вместо самой БД. Это уменьшит некоторые небольшие накладные расходы.
Я использую синглтоноподобный класс Application и статические методы, чтобы избежать приведения приложения (((MyApplication)getApplication())
) каждый раз, когда я использую некоторые распространенные методы (например, доступ к БД).
Я бы порекомендовал создать вашу базу данных в вашем классе приложений. Затем вы можете создать метод для возврата DaoSession, чтобы получить доступ к базе данных в других действиях.