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 열의 동일한 값 세트가 포함된 두 행이 테이블에 없도록 합니다.

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);
        }
    }