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 경고를 제거해줄 수 있다.