본문 바로가기
Android 개발/Room, Realm, Databases

Room DB 에서 검색 구현하기 # Like ExactMatch SQL

by Developer88 2023. 4. 24.
반응형

오늘은 RoomDB에서 검색하기를 구현하는 방법에 대해서 정리해 보겠습니다.

entity, dao 등 RoomDB에 관한 기본적인 내용은 아래 글을 참조해 주세요.

>> Room DB 사용방법 총정리 # Android SQLite

 

1. 검색을 위해 준비한 데이터

검색을 구현하기 전에 먼저 데이터가 저장되어 있어야 하는데요.

아래와 같이 아주 간단한 데이터가 있다고 가정해 보겠습니다.

표에는 안적혀 있으나, Database명은 "student" 로 하였습니다.

 

studentId Name
1 Aileen lee
2 Eyenie park
3 Ive Kim

 

2. 검색을 위한 DAO 작성

2-1. 단순한 like 검색

위의 데이터에서 이름으로 학생데이터를 검색하기 위해서는 아래와 같이 Dao를 작성해 주어야 합니다.

 

@Dao
interface StudentDao {
    @Query("SELECT * FROM student WHERE name LIKE :searchQuery")
    suspend fun searchStudentsByName(searchQuery: String): List<Student>
}

 

 

2-2. exactMatch 를 우선순위로

예를 들어서, 

'12'로 검색하면,

like 검색기준으로 하면, '123', '1234', '12' 등이 나옵니다.

당연히 유저에게는 '12'가 먼저 보여야 하는데요.

이렇게 정확하게 매칭되는 것을 먼저 보여주기 위해서는 SELECT 문을 다르게 작성해주어야 합니다.

 

@Dao
interface StudentDao {
    @Query("""
        SELECT * FROM student
        WHERE name LIKE :searchQuery
        ORDER BY
            CASE
                WHEN name = :exactMatch THEN 1
                ELSE 2
            END,
            name
    """)
    suspend fun searchStudentsByName(searchQuery: String, exactMatch: String): List<Student>
}

 

 

3. Repository 작성

3-1. like 검색 구현

이제 위의 dao를 실행할 Repository클래스를 작성해 줍니다.

그런데 잘 보시면, 인자로 받은 이름 앞뒤에 %를 붙인 것을 볼 수 있습니다.

여기서 "%"의 의미는 와일드 카드인데, 아래와 같은 의미로 사용할 수 있습니다.

 

  • A%: A로 시작하는 문자열 전부
  • %A%: A를 포함되는 문자열 전부

 

즉, 앞뒤로 이 단어를 포함한 것을 검색하는 것 입니다.

먼저 위의 2-1의 단순한 like 검색을 구현할 때는 아래와 같이 해주면 되구요.

 

class StudentRepository(private val dao: StudentDao) {
    suspend fun searchStudentsByName(name: String): List<Student> {
        val searchQuery = "%$name%"
        return dao.searchStudentsByName(searchQuery)
    }
}

 

 

위와 같이 해주고,

만약, 실행하는 코드에서 name에 "im"을 넣어주면

실제 실행되는 SQL문은 아래와 같이 됩니다.

 

SELECT * FROM student WHERE name LIKE '%im%'

 

그럼 실행결과로 아래의 Row가 나오게 됩니다.

왜냐하면, im이 포함된 열이기 때문입니다.

 

studentId Name
3 Ive Kim

 

3-2. exactMatching 우선하는 Repository 구현

이번에는 위의 2-2에서 봤던,

exactMatching 즉, 정확한 단어를 먼저 보여주도록 해 보겠습니다.

 

class StudentRepository(private val dao: StudentDao) {
    suspend fun searchStudentsByName(name: String): List<Student> {
        val searchQuery = "%$name%"
        return dao.searchStudentsByName(searchQuery, name)
    }
}

 

저희가 가진 데이터가 아주 적어서 크게 차이는 안나겟지만,

이렇게 구현해주면, 정확하게 구현된 것부터 유저에게 보여줄 수 있게 됩니다.

728x90

댓글