Room - boostcampwm-2024/and04-Nature-Album GitHub Wiki

์•ฑ ๋ฐ์ดํ„ฐ ๋ฐ ํŒŒ์ผ 

Android Developers ์•ฑ ๋ฐ์ดํ„ฐ ๋ฐ ํŒŒ์ผ

์™ธ๋ถ€ ์ €์žฅ์†Œ ์‚ฌ์šฉ ๊ถŒํ•œ ๋ฐ ์•ก์„ธ์Šค ๊ถŒํ•œ

Android์—์„œ ์ •์˜ํ•˜๋Š” ์ €์žฅ์†Œ ๊ด€๋ จ ๊ถŒํ•œ์€ READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGEMANAGE_EXTERNAL_STORAGE์ž…๋‹ˆ๋‹ค.

์ด์ „ ๋ฒ„์ „์˜ Android์—์„œ๋Š” ์•ฑ์ด ์™ธ๋ถ€ ์ €์žฅ์†Œ์˜ ์•ฑ๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ ์™ธ๋ถ€์— ์žˆ๋Š” ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก READ_EXTERNAL_STORAGE ๊ถŒํ•œ์„ ์„ ์–ธํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•ฑ๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ ์™ธ๋ถ€์˜ ํŒŒ์ผ์— ์“ธ ์ˆ˜ ์žˆ๋„๋ก WRITE_EXTERNAL_STORAGE ๊ถŒํ•œ๋„ ์„ ์–ธํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฒ„์ „์˜ Android๋Š” ์•ฑ์ด ์ง€์ •๋œ ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•˜๊ณ  ํŒŒ์ผ์— ์“ฐ๋Š” ๊ธฐ๋Šฅ์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ํŒŒ์ผ์˜ ์œ„์น˜๋ณด๋‹ค ์šฉ๋„์— ๋” ๋งŽ์ด ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ์•ฑ์ด Android 11(API ์ˆ˜์ค€ 30) ์ด์ƒ์„ ํƒ€๊ฒŸํŒ…ํ•œ๋ฉด WRITE_EXTERNAL_STORAGE ๊ถŒํ•œ์€ ์•ฑ์˜ ์ €์žฅ์†Œ ์•ก์„ธ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์šฉ๋„ ๊ธฐ๋ฐ˜ ์ €์žฅ์†Œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์ด ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๊ธฐ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ ์˜์—ญ์—๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ๊ฐ€ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.

Android 11์—์„œ๋Š” ์•ฑ๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ MediaStore ์™ธ๋ถ€์˜ ํŒŒ์ผ์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” MANAGE_EXTERNAL_STORAGE ๊ถŒํ•œ์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ถŒํ•œ์— ๊ด€ํ•ด ํ•™์Šตํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์•ฑ์—์„œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ์ด์œ ๋ฅผ ์•Œ์•„๋ณด๋ ค๋ฉด ์ €์žฅ์†Œ ๊ธฐ๊ธฐ์—์„œ ๋ชจ๋“  ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€ํ•œ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

Room์ด๋ž€?

[Android] Room

Room์ด๋ž€?

Room์€ ์Šค๋งˆํŠธํฐ ๋‚ด์žฅ(๋กœ์ปฌ) DB์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

ํ‰์†Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฉ”๋ชจ ์ €์žฅ, ์ผ์ • ์ €์žฅ ๋“ฑ ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด์žฅ DB์— ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋•Œ, SQLite๋ผ๋Š” DB๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ–ˆ๋Š”๋ฐ ์ด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด Room์ด๋‹ค.

[Storage] ์•ˆ๋“œ๋กœ์ด๋“œ ์ €์žฅ์†Œ ์ •๋ฆฌ

  • ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์—์„œ ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๋ชจ๋‘ SQLite๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ, ๊ทธ ์—ญํ• ๊ณผ ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.
๊ตฌ๋ถ„ ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
์—ญํ•  ์‹œ์Šคํ…œ ์„ค์ •, ์—ฐ๋ฝ์ฒ˜, ๋ฏธ๋””์–ด ํŒŒ์ผ ์ •๋ณด ๋“ฑ ์‹œ์Šคํ…œ ์ „๋ฐ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌ ํŠน์ • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ณ ์œ ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌ
์ €์žฅ ์œ„์น˜ ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ ์˜์—ญ์— ์œ„์น˜ํ•˜๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ /data/data/com.android.providers ๊ฒฝ๋กœ์— ์žˆ์Œ ๊ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ „์šฉ ๋””๋ ‰ํ† ๋ฆฌ์— ์œ„์น˜ํ•˜๋ฉฐ, /data/data/[ํŒจํ‚ค์ง€๋ช…]/databases ๊ฒฝ๋กœ์— ์žˆ์Œ
์ ‘๊ทผ ๋ฐฉ๋ฒ• ์ฝ˜ํ…์ธ  ํ”„๋กœ๋ฐ”์ด๋”(Content Provider)๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•˜๋ฉฐ, ContentResolver๋ฅผ ์‚ฌ์šฉ SQLiteOpenHelper ๋˜๋Š” Room ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์ ‘๊ทผ
๋ณด์•ˆ ๋ฐ ๊ถŒํ•œ ๋ฏผ๊ฐํ•œ ์ •๋ณด์ด๋ฏ€๋กœ ์ ‘๊ทผ ์‹œ ํŠน์ • ๊ถŒํ•œ์ด ํ•„์š”ํ•˜๋ฉฐ, ๋ณด์•ˆ์ด ๊ฐ•ํ™”๋˜์–ด ์žˆ์Œ ํ•ด๋‹น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋‹ค๋ฅธ ์•ฑ์€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ
์˜ˆ์‹œ ์—ฐ๋ฝ์ฒ˜, ์บ˜๋ฆฐ๋”, ๋ฏธ๋””์–ด ํŒŒ์ผ ์ •๋ณด ๋“ฑ ๋ฉ”๋ชจ ์•ฑ์˜ ๋ฉ”๋ชจ ๋‚ด์šฉ, ๊ฒŒ์ž„ ์•ฑ์˜ ์‚ฌ์šฉ์ž ์„ค์ • ๋“ฑ
  • ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ณด์•ˆ๊ณผ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€
  • ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํŠน์„ฑ๊ณผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜์—ฌ ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ

๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด ๋นŒ๋“œ

Android Developers ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด ๋นŒ๋“œ

image

Android Developers SQL์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ

[Android] ์•ˆ๋“œ๋กœ์ด๋“œ - SQLLiteDatabase ๊ตฌํ˜„ํ•˜๊ธฐ

SQLiteDatabase

Android Developers SQLiteDatabase

GDSC HUFS [5ํŒ€] ์ฝ”ํ‹€๋ฆฐ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ธฐ์ดˆ ๊ฐ•์˜_41,42 | SQLite, Room

SQLiteOpenHelper์—์„œ Room์œผ๋กœ

์•ˆ๋“œ๋กœ์ด๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ดˆ๊ธฐ์—๋Š” SQLiteOpenHelper ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ด€๋ฆฌํ•ด์™”๋‹ค. SQLiteOpenHelper๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ๊ณผ ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด SQL ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ์ปดํŒŒ์ผ ์‹œ์ ์—์„œ ์ฟผ๋ฆฌ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์—†๊ณ , ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„ ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

โ–ผ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ

Android Developers SQLite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ €์žฅ

private const val SQL_CREATE_ENTRIES =
        "CREATE TABLE ${FeedEntry.TABLE_NAME} (" +
                "${BaseColumns._ID} INTEGER PRIMARY KEY," +
                "${FeedEntry.COLUMN_NAME_TITLE} TEXT," +
                "${FeedEntry.COLUMN_NAME_SUBTITLE} TEXT)"

private const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${FeedEntry.TABLE_NAME}"

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Room ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋„์ž…๋˜์—ˆ๋‹ค. Room์€ SQLite์— ๋Œ€ํ•œ ์ถ”์ƒํ™” ๋ ˆ์ด์–ด๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์„ ๋ณด๋‹ค ๊ฐ„ํŽธํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค. Room์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— SQL ์ฟผ๋ฆฌ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์–ด ์˜ค๋ฅ˜๋ฅผ ์ค„์ด๊ณ , Entity, DAO, Database๋กœ ๊ตฌ์„ฑ๋œ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ๋ช…ํ™•ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค . Room์€ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผ ์ค„์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๋ฉฐ, SQLite๋ณด๋‹ค ํ˜„๋Œ€์ ์ธ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ์ง€์›ํ•œ๋‹ค.

Android Developers Room์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ ์ €์žฅ

Room ์ง€์†์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” SQLite๋ฅผ ์™„๋ฒฝํžˆ ํ™œ์šฉํ•˜๋ฉด์„œ ์›ํ™œํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์•ก์„ธ์Šค๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก SQLite์˜ ์ถ”์ƒํ™” ๊ณ„์ธต์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ Room์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • SQL ์ฟผ๋ฆฌ์˜ ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ํ™•์ธ
  • ๋ฐ˜๋ณต์ ์ด๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์šด ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ํŽธ์˜ ์ฃผ์„
  • ๊ฐ„์†Œํ™”๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ด์ „ ๊ฒฝ๋กœ

์ด๋Ÿฌํ•œ ์ ์„ ๊ณ ๋ คํ•  ๋•Œ SQLite API๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  Room์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

image

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
           "last_name LIKE :last LIMIT 1")
    fun findByName(first: String, last: String): User

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
}

๋”ฐ๋ผ์„œ, ๊ธฐ์กด์— SQLiteOpenHelper๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋˜ ๋ฐฉ์‹์„ Room์œผ๋กœ ์ „ํ™˜ํ•˜๋ฉด ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ๊ณผ ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ