반응형

출처: https://cocomo.tistory.com/409

 

안드로이드(Android) - SQLite

안드로이드(Android) - SQLite SQLite란? SQLite는 MySQL나 PostgreSQL와 같은 데이터베이스 관리 시스템이지만, 서버가 아니라 응용 프로그램에 넣어 사용하는 비교적 가벼운 데이터베이스입니다. 일반적인 RDBMS..

cocomo.tistory.com

https://soulduse.tistory.com/21

 

[안드로이드] SQLite 사용하기

출처 : http://here4you.tistory.com/49 안드로이드 개인 앱개발을 진행하면서, 파싱한 데이터를 SQLite에 저장할 필요가 생기게 되었는데 해당 내용을 참조하여 데이터가 잘 들어간 것을 확인하였다. 생각보다 쉽..

soulduse.tistory.com

 

위의 링크들을 보면서 내 프로젝트에서도 SQLite 데이터베이스 사용을 해보았다.

 

1. 데이터베이스 관리 객체

public class LogDB extends SQLiteOpenHelper {

    // 싱글톤 구현
    private static LogDB db = null;

    private LogDB(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public static LogDB getDB(Context context) {
        if (db == null)
            db = new LogDB(context, "TRAVELLOG", null, 1);

        return db;
    }

    // 데이터베이스 생성
    @Override
    public void onCreate(SQLiteDatabase db) {
        StringBuffer sb = new StringBuffer();

        sb.append("create table if not exists ROUTE (");
        sb.append("ID integer primary key autoincrement, ");
        sb.append("ITINERARY text not null, ");
        sb.append("LATITUDE real not null, ");
        sb.append("LONGITUDE real not null, ");
        sb.append("MEMO text, ");
        sb.append("IMAGE BLOB)");

        db.execSQL(sb.toString());

        Log.e("DB: ", "Success");

    }

    // 데이터베이스 버전 업그레이드
    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    // 레코드 추가
    public void insert(PlaceInfo placeInfo) {
        SQLiteDatabase db = getWritableDatabase();
        StringBuffer sb = new StringBuffer();

        sb.append("insert into ROUTE (");
        sb.append("ITINERARY, LATITUDE, LONGITUDE, MEMO, IMAGE )");
        sb.append("values (?, ?, ?, ?, ?)");

        db.execSQL(sb.toString(), new Object[]{
                placeInfo.getItinerary(),
                placeInfo.getLatitude(),
                placeInfo.getLongitude(),
                placeInfo.getMemo(),
                placeInfo.getImage()
        });

        Log.e("Insert: ", "Success");
    }

    // 레코드 수정
    public void update(PlaceInfo placeInfo) {
        SQLiteDatabase db = getWritableDatabase();
        StringBuffer sb = new StringBuffer();

        sb.append("update ROUTE set ");
        sb.append("ITINERARY = ?, ");
        sb.append("LATITUDE = ?, ");
        sb.append("LONGITUDE = ?, ");
        sb.append("MEMO = ?, ");
        sb.append("IMAGE = ? ");
        sb.append("where ID = ?");

        db.execSQL(sb.toString(), new Object[]{
                placeInfo.getItinerary(),
                placeInfo.getLatitude(),
                placeInfo.getLongitude(),
                placeInfo.getMemo(),
                placeInfo.getImage(),
                placeInfo.getId()
        });

        Log.e("Update: ", "Success");
    }

    // 레코드 삭제
    public void delete(PlaceInfo placeInfo) {
        SQLiteDatabase db = getWritableDatabase();
        StringBuffer sb = new StringBuffer();

        sb.append("delete from ROUTE ");
        sb.append("where id = ?");

        db.execSQL(sb.toString(), new Object[]{
                placeInfo.getId()
        });

        Log.e("Delete: ", "Success");
    }

    // 여정표 레코드들 조회
    public ArrayList getRouteList(String itinerary) {
        SQLiteDatabase db = getReadableDatabase();
        StringBuffer sb = new StringBuffer();
        ArrayList placeInfoList = new ArrayList();

        sb.append("select ID, ITINERARY, LATITUDE, LONGITUDE, MEMO, IMAGE ");
        sb.append("from ROUTE ");
        sb.append("where ITINERARY like ? ");
        sb.append("order by ID");

        Cursor cursor = db.rawQuery(sb.toString(), new String[]{
                itinerary
        });

        while (cursor.moveToNext()) {
            PlaceInfo placeInfo = new PlaceInfo();

            placeInfo.setId(cursor.getInt(0));
            placeInfo.setItinerary(cursor.getString(1));
            placeInfo.setLatitude(cursor.getDouble(2));
            placeInfo.setLongitude(cursor.getDouble(3));
            placeInfo.setMemo(cursor.getString(4));
            placeInfo.setImage(cursor.getBlob(5));

            placeInfoList.add(placeInfo);
        }

        Log.e("SelectAll: ", "Success");

        return placeInfoList;

    }

    // 여정표 이름 조회
    public ArrayList getRouteListName() {
        SQLiteDatabase db = getReadableDatabase();
        StringBuffer sb = new StringBuffer();
        ArrayList itineraryList = new ArrayList();

        sb.append("select ITINERARY ");
        sb.append("from ROUTE ");
        sb.append("group by ITINERARY ");
        sb.append("order by ID desc");

        Cursor cursor = db.rawQuery(sb.toString(), null);

        while (cursor.moveToNext()) {
            itineraryList.add(cursor.getString(0));
        }

        Log.e("SelectName: ", "Success");

        return itineraryList;

    }
}

 

2. 데이터베이스 레코드 객체

public class PlaceInfo {
    private int id;
    private String itinerary;
    private double latitude;
    private double longitude;
    private String memo;
    private byte[] image;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getItinerary() {
        return itinerary;
    }

    public void setItinerary(String itinerary) {
        this.itinerary = itinerary;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public byte[] getImage() {
        return image;
    }

    public void setImage(byte[] image) {
        this.image = image;
    }
}

1. 데이터베이스 관리 객체 싱글톤 구현

 - DB 관리 객체를 하나만 만들어서 그것만 계속 쓰게 한다.

   뭐 조금 생각해보면 이런 녀석이 많이 있다는 게 더 이상하긴 하다.

   저기서 context 변수는 이 인스턴스를 쓰려는 Activity이다.

출처: https://jeong-pro.tistory.com/86

 

싱글톤 패턴(Singleton pattern)을 쓰는 이유와 문제점

싱글톤 패턴(Singleton Pattern) 싱글톤 패턴 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴. 생성자가 여러 차례 호출되더..

jeong-pro.tistory.com

 

2. onCreate()

 - 데이터베이스에 테이블이 없는 경우 한 번만 호출되어 테이블을 생성한다.

   StringBuffer를 사용했는데, 그 이유는 String보다 빠르게 처리하는데 좋다고 한다.

   그리고 execSQL()을 이용하여 SQL 명령어를 실행한다.

 

3. onUpgrade()

 - 데이터베이스 버전이 올라갈 때 호출

   따로 구현은 하지 않았다.

 

3. Insert, Update, Delete

 - 우선 데이터베이스를 쓰기(Write) 위한 상태로 만든다.

   이것은 getWritableDatabase() 메소드로 한다.

   그리고 StringBuffer와 execSQL() 설명은 위와 동일하다.

   다만 조건을 위해 추가되는 특정 필드값은 SQL 명령어에서는 ?로 한 다음,

   execSQL() 메서드에 Object 배열을 매개변수에 추가했다.

 

4. Select

 - 데이터베이스를 읽기 위한 상태로 만든다.

   이는 getReadableDatabase() 메소드로 한다.

   그리고 cursor란 것을 받아오는데, 워드에서 쓰던 그 커서랑 같은 녀석이다.

   cursor를 받기 위해 rawQuery() 메소드를 사용했는데,

   특정 필드값을 ? 처리 후 Object 배열 매개변수를 추가한다는 점에서

   execSQL()과 비슷하다.

   이 cursor는 레코드 단위로 움직이면서 읽을 레코드가 있을 때까지(moveToNext() 메소드)

   레코드 내 필드값들을 getXXX() 메소드로 가져온다.

   그리고 읽어온 레코드들을 List에 저장 후 return 값으로 보냈다.

 

5. 데이터베이스 레코드 객체

 - 캡슐화를 위해 변수는 private 선언 후

   getter와 setter로 접근 및 설정을 하도록 했다.

 

앞으로도 이런 거 계속 쓸 건데 잊지 않도록 해야겠다.

 

 

반응형
Posted by 애콜라이트
l

free counters