6월 3일의 ⁠#Android11: 베타 버전 출시 행사에 참여하세요.

Room 항목을 사용하여 데이터 정의

Room 지속성 라이브러리를 사용할 때 관련 필드 세트를 항목으로 정의합니다. 각 항목에서 연결된 Database 개체 내에 테이블이 생성되어 항목을 포함합니다. Database 클래스의 entities 배열을 통해 항목 클래스를 참조해야 합니다.

다음 코드 스니펫은 항목을 정의하는 방법을 보여줍니다.

Kotlin

    @Entity
    data class User(
        @PrimaryKey var id: Int,
        var firstName: String?,
        var lastName: String?
    )
    

자바

    @Entity
    public class User {
        @PrimaryKey
        public int id;

        public String firstName;
        public String lastName;
    }
    

필드를 유지하려면 Room에서 필드에 액세스할 수 있어야 합니다. 필드를 공개 상태로 설정하거나 필드에 getter 및 setter를 제공할 수 있습니다. getter 및 setter 메서드를 사용하는 경우 이러한 메서드는 Room의 JavaBeans 규칙을 기반으로 합니다.

기본 키 사용

각 항목은 하나 이상의 필드를 기본 키로 정의해야 합니다. 필드가 하나만 있는 경우에도 @PrimaryKey 주석을 사용하여 필드에 주석을 달아야 합니다. 또한 Room에서 항목에 자동 ID를 할당하려면 @PrimaryKeyautoGenerate 속성을 설정하면 됩니다. 항목에 복합 기본 키가 있으면 다음 코드 스니펫에서와 같이 @Entity 주석의 primaryKeys 속성을 사용할 수 있습니다.

Kotlin

    @Entity(primaryKeys = arrayOf("firstName", "lastName"))
    data class User(
        val firstName: String?,
        val lastName: String?
    )
    

자바

    @Entity(primaryKeys = {"firstName", "lastName"})
    public class User {
        public String firstName;
        public String lastName;
    }
    

기본적으로 Room은 클래스 이름을 데이터베이스 테이블 이름으로 사용합니다. 테이블의 이름을 다르게 지정하려면 다음 코드 스니펫에서와 같이 @Entity 주석의 tableName 속성을 설정하세요.

Kotlin

    @Entity(tableName = "users")
    data class User (
        // ...
    )
    

자바

    @Entity(tableName = "users")
    public class User {
        // ...
    }
    

주의: SQLite의 테이블 이름은 대소문자를 구분하지 않습니다.

tableName 속성과 마찬가지로 Room은 필드 이름을 데이터베이스의 열 이름으로 사용합니다. 열의 이름을 다르게 지정하려면 다음 코드 스니펫에서와 같이 필드에 @ColumnInfo 주석을 추가하세요.

Kotlin

    @Entity(tableName = "users")
    data class User (
        @PrimaryKey val id: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
    

자바

    @Entity(tableName = "users")
    public class User {
        @PrimaryKey
        public int id;

        @ColumnInfo(name = "first_name")
        public String firstName;

        @ColumnInfo(name = "last_name")
        public String lastName;
    }
    

필드 무시

기본적으로 Room은 항목에 정의된 각 필드의 열을 생성합니다. 항목에 유지하지 않으려는 필드가 있으면 다음 코드 스니펫에서와 같이 @Ignore를 사용하여 필드에 주석을 달 수 있습니다.

Kotlin

    @Entity
    data class User(
        @PrimaryKey val id: Int,
        val firstName: String?,
        val lastName: String?,
        @Ignore val picture: Bitmap?
    )
    

자바

    @Entity
    public class User {
        @PrimaryKey
        public int id;

        public String firstName;
        public String lastName;

        @Ignore
        Bitmap picture;
    }
    

항목이 상위 항목에서 필드를 상속하면 일반적으로 @Entity 속성의 ignoredColumns 속성을 사용하는 것이 더 쉽습니다.

Kotlin

    open class User {
        var picture: Bitmap? = null
    }

    @Entity(ignoredColumns = arrayOf("picture"))
    data class RemoteUser(
        @PrimaryKey val id: Int,
        val hasVpn: Boolean
    ) : User()
    

자바

    @Entity(ignoredColumns = "picture")
    public class RemoteUser extends User {
        @PrimaryKey
        public int id;

        public boolean hasVpn;
    }
    

Room은 데이터베이스 테이블에서 세부정보를 더 쉽게 검색할 수 있게 하는 여러 유형의 주석을 지원합니다. 앱의 minSdkVersion이 16보다 작지 않은 한 전체 텍스트 검색을 사용하세요.

전체 텍스트 검색 지원

앱에서 FTS(전체 텍스트 검색)를 통해 데이터베이스 정보에 매우 빠르게 액세스해야 한다면 FTS3 또는 FTS4 SQLite 확장 모듈을 사용하는 가상 테이블을 통해 항목을 지원하세요. Room 2.1.0 이상에서 제공되는 이 기능을 사용하려면 다음 코드 스니펫에서와 같이 지정된 항목에 @Fts3 또는 @Fts4 주석을 추가하세요.

Kotlin

    // Use `@Fts3` only if your app has strict disk space requirements or if you
    // require compatibility with an older SQLite version.
    @Fts4
    @Entity(tableName = "users")
    data class User(
        /* Specifying a primary key for an FTS-table-backed entity is optional, but
           if you include one, it must use this type and column name. */
        @PrimaryKey @ColumnInfo(name = "rowid") val id: Int,
        @ColumnInfo(name = "first_name") val firstName: String?
    )
    

자바

    // Use `@Fts3` only if your app has strict disk space requirements or if you
    // require compatibility with an older SQLite version.
    @Fts4
    @Entity(tableName = "users")
    public class User {
        // Specifying a primary key for an FTS-table-backed entity is optional, but
        // if you include one, it must use this type and column name.
        @PrimaryKey
        @ColumnInfo(name = "rowid")
        public int id;

        @ColumnInfo(name = "first_name")
        public String firstName;
    }
    

테이블이 여러 언어로 된 콘텐츠를 지원하면 다음과 같이 languageId 옵션을 사용하여 각 행의 언어 정보를 저장하는 열을 지정하세요.

Kotlin

    @Fts4(languageId = "lid")
    @Entity(tableName = "users")
    data class User(
        // ...
        @ColumnInfo(name = "lid") val languageId: Int
    )
    

자바

    @Fts4(languageId = "lid")
    @Entity(tableName = "users")
    public class User {
        // ...

        @ColumnInfo(name = "lid")
        int languageId;
    }
    

Room은 결과 정렬, tokenizer 유형 및 외부 콘텐츠로 관리되는 테이블을 비롯하여 FTS 지원 항목을 정의하기 위한 몇 가지 기타 옵션을 제공합니다. 이러한 옵션에 관한 자세한 내용은 FtsOptions 참조에서 확인하세요.

특정 열 색인 생성

앱에서 FTS3 또는 FTS4 테이블 지원 항목을 사용할 수 없는 SDK 버전을 지원해야 할 때에도 여전히 데이터베이스에 있는 특정 열의 색인을 생성하여 쿼리 속도를 높일 수 있습니다. 항목에 색인을 추가하려면 @Entity 주석 내에 indices 속성을 포함하여 색인 또는 복합 색인에 포함하려는 열 이름을 나열하세요. 다음 코드 스니펫은 이 주석 프로세스를 보여줍니다.

Kotlin

    @Entity(indices = arrayOf(Index(value = ["last_name", "address"])))
    data class User(
        @PrimaryKey val id: Int,
        val firstName: String?,
        val address: String?,
        @ColumnInfo(name = "last_name") val lastName: String?,
        @Ignore val picture: Bitmap?
    )
    

자바

    @Entity(indices = {@Index("name"),
            @Index(value = {"last_name", "address"})})
    public class User {
        @PrimaryKey
        public int id;

        public String firstName;
        public String address;

        @ColumnInfo(name = "last_name")
        public String lastName;

        @Ignore
        Bitmap picture;
    }
    

때로 데이터베이스의 특정 필드 또는 필드 그룹은 고유해야 합니다. @Index 주석의 unique 속성을 true로 설정함으로써 이 고유성 속성을 적용할 수 있습니다. 다음 코드 샘플은 테이블의 firstNamelastName 열에 동일한 값 세트를 포함하는 2개의 행이 없도록 방지합니다.

Kotlin

    @Entity(indices = arrayOf(Index(value = ["first_name", "last_name"],
            unique = true)))
    data class User(
        @PrimaryKey val id: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?,
        @Ignore var picture: Bitmap?
    )
    

자바

    @Entity(indices = {@Index(value = {"first_name", "last_name"},
            unique = true)})
    public class User {
        @PrimaryKey
        public int id;

        @ColumnInfo(name = "first_name")
        public String firstName;

        @ColumnInfo(name = "last_name")
        public String lastName;

        @Ignore
        Bitmap picture;
    }
    

AutoValue 기반 개체 포함

Room 2.1.0 이상에서는 @AutoValue를 사용하여 주석을 추가하는 자바 기반 불변 값 클래스를 앱 데이터베이스의 항목으로 사용할 수 있습니다. 이 지원은 항목의 두 인스턴스가 열에 똑같은 값을 포함하면 동일한 것으로 간주될 때 특히 유용합니다.

@AutoValue로 주석이 달린 클래스를 항목으로 사용할 때에는 @PrimaryKey, @ColumnInfo, @Embedded@Relation을 사용하여 클래스의 추상 메서드에 주석을 달 수 있습니다. 그러나 이러한 주석을 사용할 경우 Room이 메서드의 자동 생성된 구현을 적절하게 해석하도록 매번 @CopyAnnotations 주석을 포함해야 합니다.

다음 코드 스니펫은 Room이 항목으로 인식하는 @AutoValue로 주석이 달린 클래스의 예를 보여줍니다.

User.java

    @AutoValue
    @Entity
    public abstract class User {
        // Supported annotations must include `@CopyAnnotations`.
        @CopyAnnotations
        @PrimaryKey
        public abstract long getId();

        public abstract String getFirstName();
        public abstract String getLastName();

        // Room uses this factory method to create User objects.
        public static User create(long id, String firstName, String lastName) {
            return new AutoValue_User(id, firstName, lastName);
        }
    }