태그 보관물: android

Android Studio Database Inspector 사용

개요

안드로이드 개발 시 DB(SQLite)를 이용하는 경우 테이블의 내용을 바로 확인하기가 매우 까다로웠습니다. Device File Explorer로 *.db파일을 로컬 PC로 복사해서 별도의 프로그램으로 열어서 확인해야 했습니다. 이런 불편은 이제 끝났습니다. 안드로이드 스튜디오 4.1로 업데이트 되면서 Database Inspector가 추가 되었기 때문입니다.

Database Inspector

안드로이드 4.1로 업데이트 되었다고 가정하겠습니다. 프로젝트를 불러와서 에뮬레이터로 실행한 후 View > Tool Windows > Database Inspector 를 선택하면 생성된 테이블의 목록이 나타납니다. 테이블명을 더블클릭하면 테이블의 내용을 확인할 수 있습니다.

Database Inspector 메뉴 선택
Database Inspector 메뉴 선택

에뮬레이터나 장비에 연결되어 있지 않거나 앱이 실행되지 않은 경우 ‘Deploy your app to a device running API level 26 or higher or select a debuggable process to inspect’ 메시지가 나타납니다. 메시지 내용으로 보면 API Level 이 26 이상이어야 한다는 것을 알 수 있습니다. 그 이하 API 레벨 앱의 경우 연결이 되어도 내용이 나타나지 않습니다.

Deploy your app to a device running API level 26 or higher or select a debuggable process to inspect 메시지
Deploy your app to a device running API level 26 or higher or select a debuggable process to inspect 메시지

연결되면 왼쪽에 생성된 DB 파일명과 테이블이 나타납니다. 테이블을 더블클릭하면 화면처럼 내용이 나타납니다. 다른 테이블을 선택하면 탭 형태로 추가되어 확인하기 편리합니다. Refresh table 버튼을 클릭하면 새로고침 됩니다. Live updates 를 체크하면 앱이 동작하면서 변경되는 테이블의 내용을 바로 확인할 수 있습니다.

테이블 목록 및 내용
테이블 목록 및 내용

테이블의 내용을 쿼리를 통해 확인할 수도 있습니다. 아래와 같이 Open New Query Tab 툴바버튼을 클릭하면 새로운 탭이 추가됩니다.

Open New Query Tab
Open New Query Tab

그러면 DB 파일을 선택할 수 있고 쿼리문을 작성 후 Run 버튼을 클릭해서 실행해 볼 수 있습니다. 테이블명에 대한 제안기능이 있어 더욱 편리하게 이용할 수 있습니다.

쿼리문 실행
쿼리문 실행

Database Inspector 기능의 추가로 DB를 이용한 앱 개발 시 자료 확인이 매우 편리하게 되었습니다. 불필요한 과정이 생략되어 시간도 많이 절약되게 되었습니다. 이상 Database Inspector 에 대해서 알아보았습니다.

Android ROOM 사용한 Master/Detail 관계 정의

개요

Android ROOM 은 Android Jetpack 에 포함된 컴포넌트 입니다. SQLite DB에 쉽게 접속하고 이용할 수 있게 해 주는 일종의 ORM(Object-relational mapping) 라이브러리 입니다. 이전에는 SQLite DB에 접속하려면 정형화된 별도의 클래스를 사용했습니다. 조금 지루한 작업이라고 할 수 있었습니다. 이것을 줄여주고 쉽게 SQLite DB 연동작업을 할 수 있도록 도와줍니다.

기초적인 연동방법은 좋은 글이 많으므로 그것을 참고하시면 됩니다. 이 글에서는 부모가 되는 테이블과 자식이 되는 테이블을 어떻게 정의하는지 살펴보도록 하겠습니다. 언어는 코틀린(Kotlin)을 기준으로 합니다.

Master/Detail 관계 정의

Master/Detail 관계는 기본적으로 1:N(일대다) 으로 이해하시면 됩니다. 하나의 부모에 자식이 여럿있는 개념입니다. 1:N(일대다) 관련 자료를 찾아보시면 더 자세한 내용을 보실 수 있습니다.

Android ROOM 에서는 클래스 파일에 테이블을 정의합니다. 코드는 다음과 같습니다.

@Entity(tableName = "test_parent")
class TestParent(@PrimaryKey @ColumnInfo(name = "parent_seq") var parentSeq: Int,
          @ColumnInfo(name = "parent_name") var parentName: String?,
.
.
.
)

@Entity(
    tableName = "test_detail",
    indices = [Index("parent_seq")],
    foreignKeys = [ForeignKey(entity = TestParent::class, parentColumns = ["parent_seq"], childColumns = ["parent_seq"], onDelete = ForeignKey.NO_ACTION)]
)

class TestDetail(@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "test_detail_seq") var testDetailSeq: Int,
                @ColumnInfo(name = "parent_seq") var parentSeq: Int,
.
.
.
)

12행이 핵심입니다. 부모 컬럼과 자식 컬럼이 지정된 것을 볼 수 있습니다. onDelete는 부모 테이블의 자료가 삭제되었을때의 동작입니다. 예제에서는 아무런 동작도 하지 않도록 했습니다. 각자의 상황에 맞는 값을 지정하면 됩니다. 사용할 수 있는 값과 의미는 다음의 주소에서 확인할 수 있습니다.

https://developer.android.com/reference/android/arch/persistence/room/ForeignKey.html#CASCADE

결과만 보면 간단한데 Master/Detail 관계를 정의한 예제를 거의 찾아볼 수 없었습니다. 코틀린(Kotlin)으로 된 예제는 없었습니다. 위 코드를 참조하셔서 필요한 부분에 적용하시면 됩니다.

필요한 필드만 업데이트

android ROOM을 이용해서 테이블을 갱신(update)해야 하는 경우가 있습니다. 기본적인 예제를 적용해보면 모든 필드가 갱신되는 것을 알 수 있습니다. 필요한 필드만 갱신하려면 Query 형태로 정의해야 합니다. Data Object Access(DAO) 클래스에 다음과 같이 정의합니다.


    @Query("update test_parent set parent_name = :parentName, photo = :parentPhoto, memo = :parentMemo where parent_seq = :parentSeq")
    fun updateParent(parentSeq:Int, parentName:String?, parentPhoto:String?, parentMemo:String?)

변수로 값을 전달해서 Query 내에 :변수명 형태로 대입해서 필요한 필드만 갱신 되도록 작업하시면 됩니다.

이상 Android ROOM 라이브러리를 사용한 Master/Detail 관계 정의에 대해서 알아보았습니다.