Programing

SQLiteDatabase에 싱글 톤 디자인 패턴 사용

lottogame 2020. 10. 30. 07:37
반응형

SQLiteDatabase에 싱글 톤 디자인 패턴 사용


저는 안드로이드 초보자이고 기본적인 경험을 얻기 위해 간단한 애플리케이션을 개발하고 있습니다. 내 앱은 매우 간단하며 브로드 캐스트 수신기와 일부 활동으로 구성됩니다. 두 구성 요소 모두 단일 데이터베이스를 사용하므로 이론적으로는 둘 다 동시에 db에 액세스하려고 할 수 있습니다.

현재 저는 필요할 때마다 db 개체 (SQLite db 도우미 클래스)를 인스턴스화하고 쿼리, 삽입 등 필요한 작업을 수행하고 있습니다.

내가 여기서 읽은 내용과 다른 문서에서 db에 동시에 액세스하는 경우 "db locked"예외가 발생하는 문제가 있으므로 더 나은 접근 방식은이 db 개체의 단일 인스턴스를 갖는 것입니다. 구성 요소는 항상 동일한 db 연결을 사용합니다.

위의 추론이 맞습니까? 그렇다면 싱글 톤이 이것에 대한 충분한 해결책이 될까요? 나는 일부 순수 주의자들이 그것에 반대 할 수 있다는 것을 알고 있지만, 이것은 다른 경우에하지 않을 일을 할 여유가있을 수 있도록 다소 간단한 응용 프로그램이라는 점에 유의하십시오.

그렇지 않으면 더 나은 옵션은 무엇입니까? 콘텐츠 제공자 사용에 대해 읽었지만 다른 활동과 데이터를 공유하는 데 관심이 없다는 것 외에는 너무 많을 것입니다. 나는 실제로이 게시물을 읽고 도움이된다는 것을 알았습니다.


이 주제에 대한 내 블로그 게시물을 보려면 여기를 클릭하십시오.


다음은 세 가지 가능한 접근 방식을 보여주는 샘플 코드입니다. 이를 통해 애플리케이션 전체에서 데이터베이스에 액세스 할 수 있습니다.

접근 방식 # 1 :`SQLiteOpenHelper`를 정적 데이터 멤버로 지정

이것은 완전한 구현은 아니지만 DatabaseHelper클래스를 올바르게 디자인하는 방법에 대한 좋은 아이디어를 제공 합니다. 정적 팩토리 메소드는 항상 하나의 DatabaseHelper 인스턴스 만 존재하도록합니다.

/**
 * create custom DatabaseHelper class that extends SQLiteOpenHelper
 */
public class DatabaseHelper extends SQLiteOpenHelper { 
    private static DatabaseHelper mInstance = null;

    private static final String DATABASE_NAME = "databaseName";
    private static final String DATABASE_TABLE = "tableName";
    private static final int DATABASE_VERSION = 1;

    private Context mCxt;

    public static DatabaseHelper getInstance(Context ctx) {
        /** 
         * use the application context as suggested by CommonsWare.
         * this will ensure that you dont accidentally leak an Activitys
         * context (see this article for more information: 
         * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
         */
        if (mInstance == null) {
            mInstance = new DatabaseHelper(ctx.getApplicationContext());
        }
        return mInstance;
    }

    /**
     * constructor should be private to prevent direct instantiation.
     * make call to static factory method "getInstance()" instead.
     */
    private DatabaseHelper(Context ctx) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.mCtx = ctx;
    }
}

접근법 # 2 :`ContentProvider`로 SQLite 데이터베이스 추상화

이것이 제가 제안하는 접근 방식입니다. 하나의 경우 새 CursorLoader클래스에는 ContentProviders 가 필요 하므로 Activity 또는 Fragment를 LoaderManager.LoaderCallbacks<Cursor>a 로 구현하려면 CursorLoader(활용할 것을 제안합니다. 마법과 같습니다!) ContentProvider애플리케이션에 대해 를 구현 해야합니다. 또한 ContentProviders로 Singleton 데이터베이스 도우미를 만드는 것에 대해 걱정할 필요가 없습니다. getContentResolver()액티비티에서 호출하기 만하면 시스템이 모든 것을 처리합니다 (즉, 여러 인스턴스가 생성되는 것을 방지하기 위해 싱글 톤 패턴을 디자인 할 필요가 없습니다).

도움이 되었기를 바랍니다!


나는 안드로이드에서 db에 액세스하기 위해 싱글 톤을 사용하는 것에 대해 읽지 않았습니다. 그것에 대한 링크를 제공해 주시겠습니까?

In my apps, I use simple dbhelper objects, not singletons, I was thinking this is more the job of the sql engine to ensure db is not locked, not the job of your android classes, and it works pretty well for my biggest app that is medium sized.

Update #1: looking at the reference you gave, it looks like the problem is not at all about using different instances of a dbhelper. Even a single instance could encounter problems accessing the databases : the problem comes from a concurrent accesses. So the only way to ensure a proper access to the database by different threads is to use simple thread synchronization mechanisms (synchronized methods or blocks), and it almost nothing to do with using a singleton.

Update #2 : the second link you provide clearly shows that their is a need for singleton dbhelper objects in the case of multiple threads writing concurrently in a db. This can happen if you do you sql operations (inserts/updates/deletes) from AsyncTasks for instance. In that case a singleton object dbhelper would simply put all sql operations in some sort of pipeline and execute them in order.

This solution could be easier to implement than using proper thread synchronization using synchronized methods in java. Actually I think there should be more emphasize somewhere in android docs about this problem and the use of a singleton db helper could be encouraged.

Thanks for this nice question and the follow ups.

참고URL : https://stackoverflow.com/questions/6905524/using-singleton-design-pattern-for-sqlitedatabase

반응형