Android 구성 요소 룸 안내
Room 은 Google 이 출시 한 Android 구성 요소 라 이브 러 리 의 데이터 영구 화 구성 요소 라 이브 러 리 이 며 SQLite 에서 이 루어 진 ORM 솔 루 션 이 라 고 할 수 있 습 니 다.
Room 은 주로 세 부분 을 포함 합 니 다.
Room Architecture Diagram
기본 사용
1.엔 터 티 만 들 기
1.1 간단 한 Entitiy
간단 한 Entity 정 의 는 다음 과 같 습 니 다.
@Entity(tableName = "user"
indices = {@Index(value = {"first_name", "last_name"})})
public class User {
@PrimaryKey
private int uid;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
@Ignore
public User(String firstName, String lastName) {
this.uid = UUID.randomUUID().toString();
this.firstName = firstName;
this. lastName = lastName;
}
public User(String id, String firstName, String lastName) {
this.uid = id;
this.firstName = userName;
this. lastName = userName;
}
// Getters and setters
}
현재 존재 하 는 대부분의 ORM 라 이브 러 리 와 달리 Room 은 Entitiy 대상 간 의 직접 인용 을 지원 하지 않 습 니 다.
다만 Room 은 엔 터 티 간 관 계 를 외부 키(Foreign Key)로 표시 할 수 있다.
@Entity(foreignKeys = @ForeignKey(entity = User.class,
parentColumns = "id",
childColumns = "user_id"))
class Book {
@PrimaryKey
public int bookId;
public String title;
@ColumnInfo(name = "user_id")
public int userId;
}
위의 코드 에서 보 듯 이 Book 대상 과 User 대상 은 속 하 는 관계 입 니 다.북 속 userid,사용자 의 id 에 대응 합 니 다.그렇다면 사용자 대상 이 삭 제 될 때 해당 하 는 북 은 어떻게 될 까?@ForeignKey 주석 에는 두 개의 속성 이 있 습 니 다.onDelete 와 onUpdate.이 두 속성 은 ForeignKey 의 onDelete()와 onUpdate()에 대응 합 니 다.이 두 속성의 값 을 통 해 User 대상 이 삭제/업데이트 되 었 을 때 Book 대상 이 하 는 응답 을 설정 합 니 다.이 두 속성의 선택 값 은 다음 과 같 습 니 다.
1.3 개체 내장
어떤 경우 에는 표 의 데이터 에 대해 여러 개의 POJO 클래스 로 표시 합 니 다.이 경우@Embedded 로 포 함 된 대상 을 설명 할 수 있 습 니 다.예 를 들 어:
class Address {
public String street;
public String state;
public String city;
@ColumnInfo(name = "post_code")
public int postCode;
}
@Entity
class User {
@PrimaryKey
public int id;
public String firstName;
@Embedded
public Address address;
}
위 코드 에서 생 성 된 User 표 에서 Column 은 id,firstName,street,state,city,post 입 니 다.code2.데이터 접근 대상 만 들 기(DAO)
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND "
+ "last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
@Insert
void insertAll(List<User> users);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Delete
void delete(User user);
@Update
public void updateUsers(List<User> users);
}
DAO 는 하나의 인터페이스 일 수도 있 고 추상 적 인 클래스 일 수도 있 습 니 다.Room 은 컴 파일 할 때 DAO 의 실현 을 만 듭 니 다.Tips:
DAO 의 첨삭 방법 에 대한 정 의 는 모두 비교적 간단 하 다.여 기 는 토론 을 하지 않 고 다음 에 조회 방법 에 대해 더 이야기 하 겠 다.
2.1 간단 한 조회
Talk is cheap,직접 표시 코드:
@Query("SELECT * FROM user")
List<User> getAll();
Room 은 컴 파일 할 때 sql 문 구 를 검사 합 니 다.@Query()의 sql 문 구 는 문법 오류 가 있 거나 조회 표 가 존재 하지 않 으 면 Room 은 컴 파일 타 임 스 가 잘못 되 었 습 니 다.2.2 조회 매개 변수 전달
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND "
+ "last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
코드 를 보면 이해 하기 쉬 울 것 입 니 다.방법 에서 매개 변수 arg 를 전달 하고 sql 구문 에서:arg 를 사용 하면 됩 니 다.컴 파일 할 때 Room 은 대응 하 는 인자 와 일치 합 니 다.전송 인삼 에 arg 에 대응 하 는 인자 가 일치 하지 않 으 면 Room 은 컴 파일 타 임 스 가 잘못 되 었 습 니 다.
2.3 조회 표 의 일부 필드 의 정보
실제 특정한 업무 장면 에서 우 리 는 표 부분 필드 의 값 에 만 관심 을 가 질 수 있 습 니 다.이때 저 는 관심 있 는 열 만 조회 하면 됩 니 다.
부분 집합 을 정의 하 는 POJO 클래스:
public class NameTuple {
@ColumnInfo(name="first_name")
public String firstName;
@ColumnInfo(name="last_name")
public String lastName;
}
DAO 에 검색 방법 추가:
@Query("SELECT first_name, last_name FROM user")
public List<NameTuple> loadFullName();
여기 서 정 의 된 POJO 도@Embedded 사용 을 지원 합 니 다.2.3 검색 결과 의 반환 유형
Room 에서 조회 작업 은 POJO 대상 과 List 를 되 돌려 주 는 것 외 에 도 지원 합 니 다.
LiveData
LiveData 는 구성 요소 라 이브 러 리 에서 제공 하 는 또 다른 구성 요소 로 데이터 변화 구동 UI 새로 고침 수 요 를 잘 만족 시 킬 수 있 습 니 다.Room 은 LiveData 코드 를 업데이트 합 니 다.
@Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
public LiveData<List<User>> loadUsersFromRegionsSync(List<String> regions);
Flowablbe<T> Maybe<T> Single<T>:
Room RxJava2 Flowablbe, Maybe Single , RxJava , gradle :android.arch.persistence.room:rxjava2。
@Query("SELECT * from user where id = :id LIMIT 1")
public Flowable<User> loadUserById(int id);
Cursor:Cursor 로 돌아 가 는 것 은 기 존 프로젝트 에서 Cursor 를 사용 하 는 장면 을 지원 하기 위해 서 입 니 다.공식 적 으로 는 Cursor 로 돌아 가 는 것 을 권장 하지 않 습 니 다.
Caution: It's highly discouraged to work with the Cursor API because it doesn't guarantee whether the rows exist or what values the rows contain. Use this functionality only if you already have code that expects a cursor and that you can't refactor easily.
2.4 연표 조회
Room 은 연결 표 조 회 를 지원 합 니 다.인터페이스 정의 에 있어 서 다른 조회 와 차이 가 크 지 않 습 니 다.주로 sql 문장의 차이 입 니 다.
@Dao
public interface MyDao {
@Query("SELECT * FROM book "
+ "INNER JOIN loan ON loan.book_id = book.id "
+ "INNER JOIN user ON user.id = loan.user_id "
+ "WHERE user.name LIKE :userName")
public List<Book> findBooksBorrowedByNameSync(String userName);
}
3.데이터베이스 만 들 기Room 에서 DataBase 는 SQLite API 에서 SQLiteOpenHelper 와 유사 하여 DB 작업 을 제공 하 는 착안점 이지 만 DB 를 가지 고 있 는 것 외 에 관련 데이터 시트(Entity)를 가 진 데이터 액세스 대상(DAO)도 책임 지기 때문에 Room 에서 Database 를 정의 하려 면 세 가지 조건 을 만족 시 켜 야 합 니 다.
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
이상 Room 의 3 대 구성 요 소 를 만 든 후 코드 에서 다음 코드 를 통 해 Database 인 스 턴 스 를 만 들 수 있 습 니 다.
AppDatabase db = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, "database-name").build();
3.데이터베이스 이전3.1 룸 데이터베이스 업그레이드
전통 적 인 SQLite API 에서 데이터 베 이 스 를 업그레이드 하려 면 SQLiteOpenHelper.onUpgrade 방법 으로 데이터 베 이 스 를 업그레이드 하 는 sql 문 구 를 실행 합 니 다.이러한 sql 문 구 는 보통 데이터 베이스 버 전에 따라 파일 방식 이나 배열 로 관리 합 니 다.이런 방식 으로 데이터 베 이 스 를 업그레이드 하 는 것 은 폭탄 을 뜯 는 것 과 같다 는 말 이 있다.그 에 비해 Room 에서 데이터 베 이 스 를 업그레이드 하 는 것 은 하나의 스위치 를 누 르 는 것 과 같다.
Room 은 데이터 베 이 스 를 업그레이드 하기 위해 Migration 류 를 제공 합 니 다.
Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
+ "`name` TEXT, PRIMARY KEY(`id`))");
}
};
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE Book "
+ " ADD COLUMN pub_year INTEGER");
}
};
Migration 클래스 를 만 들 때 startVersion 과 endVersion 을 지정 해 야 합 니 다.코드 에 MIGRATION1_2 와 MIGRATION2_3 의 startVersion 과 endVersion 은 점차 증가 합 니 다.Migration 은 버 전 1 에서 버 전 3 으로 바로 올 라 가 는 것 을 지원 합 니 다.migrate()방법 에서 실 행 된 문구 가 정상 적 이면 됩 니 다.그러면 Room 은 어떻게 데이터베이스 업 그 레이 드 를 실현 합 니까?사실은 본질 적 으로 SQLiteOpenHelper.onUpgrade 를 호출 합 니 다.Room 에서 자체 적 으로 SQLiteOpenHelper 를 실 현 했 습 니 다.onUpgrade()방법 이 호출 될 때 Migration 을 촉발 합 니 다.데이터 베 이 스 를 처음 방 문 했 을 때 Room 은 다음 과 같은 몇 가지 일 을 했 습 니 다.3.2 기 존 SQLite 데이터 베 이 스 를 Room 으로 이전
Room 도 SQLite 를 사용 하기 때문에 기 존 Sqlite 데이터 베 이 스 를 Room 으로 이전 하 는 것 을 잘 지원 할 수 있 습 니 다.
기 존 버 전 번호 가 1 인 데이터베이스 에 표 User 가 있다 고 가정 하고 Room 으로 이전 하려 면 Entity,DAO,Database 를 정의 한 다음 Database 를 만 들 때 빈 Migration 을 추가 하면 됩 니 다.주의해 야 할 것 은 데이터베이스 에 업그레이드 작업 이 없 더 라 도 버 전 을 업그레이드 해 야 합 니 다.그렇지 않 으 면 IllegalState Exception 을 버 릴 수 있 습 니 다.
@Database(entities = {User.class}, version = 2)
public abstract class UsersDatabase extends RoomDatabase {
…
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// Since we didn't alter the table, there's nothing else to do here.
}
};
…
database = Room.databaseBuilder(context.getApplicationContext(),
UsersDatabase.class, "Sample.db")
.addMigrations(MIGRATION_1_2)
.build();
4.복잡 한 데이터 의 처리일부 장면 에서 우리 의 응용 은 Date 와 같은 복잡 한 데이터 형식 을 저장 해 야 할 수도 있 습 니 다.그러나 Room 의 Entity 는 기본 데이터 형식 과 포장 류 간 의 전환 만 지원 하고 다른 대상 의 인용 은 지원 하지 않 습 니 다.그래서 Room 은 TypeConverter 를 제공 하여 사용자 자신 에 게 대응 하 는 전환 을 실현 합 니 다.
Date 형식의 변환 은 다음 과 같 습 니 다.
public class Converters {
@TypeConverter
public static Date fromTimestamp(Long value) {
return value == null ? null : new Date(value);
}
@TypeConverter
public static Long dateToTimestamp(Date date) {
return date == null ? null : date.getTime();
}
}
변환 방법 을 정의 한 후 대응 하 는 Database 에 지정 하면 됩 니 다.그러면 대응 하 는 POJO(User)에서 Date 클래스 를 사용 할 수 있 습 니 다.
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
@Entity
public class User {
...
private Date birthday;
}
총화SQLite API 방식 으로 데이터 영구 화 를 실현 하 는 프로젝트 에서 하나의 작업 이 힘 든 SQLite OpenHelper 가 실 현 될 것 이 라 고 믿 습 니 다.유지 보수 표 의 필드 에 있 는 Constant 류,코드 가 유사 한 데이터베이스 액세스 류(DAO)가 있 습 니 다.데이터 베 이 스 를 방문 할 때 Cursor 를 옮 겨 다 니 며 해당 하 는 POJO 류 를 구축 하고 되 돌려 야 합 니 다.비교 해 보면,Room 은 SQLite 위 에 포 장 된 ORM 라 이브 러 리 로 서 많은 장점 을 가진다.비교적 직관 적 인 체험 은 다음 과 같다.
위 에서 말 한 것 은 소 편 이 소개 한 안 드 로 이 드 구조 구성 요소 Room 안내 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.