Room 컴파일러 옵션 중 room.expandProjection 사용하기

Charlezz
3 min readNov 7, 2019

--

room.expandProjection 옵션

2019년 10월 9일 Room 2.2.0 stable 버전이 출시 됨에 따라 room.expandProjection 옵션을 사용할 수 있게 되었다.

room.expandProjection 옵션 설정하기

android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.expandProjection":"true"]
}
}
}
}

릴리즈 노트 및 공식문서에 다음과 같은 내용이 있다.

room.expandProjection: Configures Room to rewrite queries such that their top star projection is expanded to only contain the columns defined in the DAO method return type.

스타(*) 프로젝션을 사용하는 DAO 메소드에 대해 해당 메소드가 가진 컬럼만 가져오기 위해 쿼리를 재작성 한다는 내용이다.

예제를 통해 알아보자.

다음과 같은 POJO 클래스가 있다고 가정한다.

@Entity
public class User {
@PrimaryKey(autoGenerate = true)
public int id;
public String name;
public int age;
public User(String name){
this.name = name;
}
}
public class UserName {
public String name;
}

User 엔터티 클래스가 있고, User 클래스가 가지고 있는 필드의 일부만을 가지고 있다. 이제 DAO 인터페이스를 살펴보자.

@Dao
public interface UserRepository {
@Query("SELECT * FROM User")
LiveData<List<UserName>> loadUserNames();
}

User 테이블의 모든 레코드를 가져오지만, UserName은 name컬럼만 가지고 있다.

room.expandProjection 옵션이 비활성화 되어있을 때 Room 어노테이션 프로세서에 의해 생성되는 UserRepository_Impl.java의 코드를 확인하면 다음과 같다.

@Override
public LiveData<List<UserName>> loadUserNames() {
final String _sql = "SELECT * FROM User";
...
}

이번엔 room.expandProjection을 활성화 해보자.

@Override
public LiveData<List<UserName>> loadUserNames() {
final String _sql = "SELECT `name` FROM User";
...
}

UserName이 가지고 있는 필드들로 프로젝션이 변경되고 쿼리가 재작성된것을 확인할 수 있다.

TL;DR

room.expandProjection 사용시 쿼리의 비용을 줄여주고, 근본적으로 CURSOR_MISMATCH 경고를 제거해줄 수 있다.

--

--

Charlezz
Charlezz

Written by Charlezz

A passionate developer who’s curious about Android

No responses yet