컴퓨터공부/Kotlin & Java

Android Room annotation 정리(어노테이션)

achivenKakao 2020. 10. 6. 12:42

안드로이드 앱에서 SQLite 데이터베이스를 쉽고 편리하게 사용할 수 있도록 하는 기능이다. SQLite 위에 만든 구글의 ORM(Object-relational mapping)이다. 룸을 사용하면 앱의 단일 정보 소스로 제공되는 캐시를 통해 인터넷 연결 여부와 관계없이 앱에 있는 주요 정보의 일관된 사본을 볼 수 있다.

 

 

룸의 구성요소는 Database, Entity, DAO 이다. 

 

Database

// 데이터 베이스에서 사용하는 엔티티와 버전을 지정합니다.
@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {

    // 데이터베이스와 연결할 데이터 접근 객체를 정의합니다.
    abstract fun getUserDao() : UserDao

    companion object {
        private var INSTANCE: UserDatabase? = null
        fun getInstance(context: Context): UserDatabase? {
            if (INSTANCE == null) {
                synchronized(UserDatabase::class) {
                    INSTANCE = Room.databaseBuilder(
                        context.applicationContext,
                        UserDatabase::class.java,
                        "black_jin.db"
                    ).build()
                }
            }
            return INSTANCE
        }


    }
}

 

Entity

데이터베이스 내의 테이블 전체를 말한다. 

쉽게 설명해서 저장될 class 형식이다.

    @ColumnInfo(name = "fullname")  : column의 이름을 지정해 준다, 생략 가능

    @Embedded  : 항목의 내용이 Object(not primitive) 일 때 지정해준다.

@Entity(tableName = "userTable")
data class User(
    /*
     변수 이름과 SerializedName 이 같으면 생략 가능하다.
     SerializedName 를 이용해서 json 데이터와 변수 이름을 다르게 지정할 수 있다.
        ex)
            @SerializedName("gender")
            var sex: String = "",
     */

    var gender: String = "maleDefault",

    @ColumnInfo(name = "fullname")
    @Embedded
    var name: Name,

    @Embedded
    var location: Location,

    @Embedded
    var login: Login,

    @Embedded
    var picture: Picture,

    @PrimaryKey
    @NonNull
    var email: String = "emailDefault",

    var phone: String = "phone",
    var cell: String = "cell"

) : Serializable {

    public var linkCnt = 0

    fun getFullName(): String? {
        return name.title + "." + name.first + " " + name.last
    }

    fun getLikeCnt(): String {
        return "Like : $linkCnt"
    }

}

 

 

DAO(Data Access Object)

데이터베이스에 액세스하는데 사용되는 메서드를 가진다.

쿼리를 사용하는 메서드를 매핑 시킨다. 

모두 interface class 라는 게 특징이며, 컴파일 할 때 UserDao_Impl class를 생성하여 DB 쿼리를 대신 만들어 준다.

(Entity를 제대로 정의 못하면 컴파일 에러가 난다.-_-)

 

// 기본적으로 무조건 쓰는걸 BaseDao로 만들어 봤다.
interface BaseDao<T> {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun add(entity: T)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun addAll(entity: Array<T>)

    @Update
    fun update(entity: T)

    @Delete
    fun delete(entity: T)
}
@Dao
interface UserDao: BaseDao<User> {

    // 저장되어 있는 저장소 목록을 반환합니다.
    // Flowable 형태의 자료를 반환하므로, 데이터베이스가 변경되면 알림을 받아 새로운 자료를 가져옵니다.
    // 따라서 항상 최신 자료를 유지합니다.
    @Query("SELECT * FROM userTable")
    fun getUser(): Flowable<List<User>>

    // repositories 테이블의 모든 데이터를 삭제 합니다.
    @Query("DELETE FROM userTable")
    fun clearAll()
}

 

     DAO의 Query 매개변수 전달

// Query에 매개변수 전달
// :minAge 이런 식으로 작성해줘야 한다. 
//    컴파일 시 :minAge bind 매개변수와 minAge 메서드 매개변수를 일치시킨다. 

@Dao
interface MyDao {
    @Query("SELECT * FROM user WHERE age > :minAge")
    fun loadAllUsersOlderThan(minAge: Int): Array<User>
    
    @Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")
    fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :search " +
           "OR last_name LIKE :search")
    fun findUserWithName(search: String): List<User>
}

     DAO의 Observable 쿼리    

// Observable 쿼리

// 쿼리의 리턴값으로 LiveData를 사용하면 데이터 변경 시 앱 UI를 자동으로 업데이트 할 수 있다.

@Dao
interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    fun loadUsersFromRegionsSync(regions: List<String>): LiveData<List<User>>
}

 

 

더 자세한 것은 출처를 참고 하세요.

 

 


출처: https://leveloper.tistory.com/161 [꾸준하게]