์ด๋ฒ ๊ธ์์๋ Flutter์์ ๊ฐ์ฅ ์ธ๊ธฐ๊ฐ ์ข์ ๋ก์ปฌ ์ ์ฅ์์ธ Hive์ ๋ํด์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ๋ค.
Hive ์ฌ์ฉ์ ์์ ๋ก์ปฌ ์ ์ฅ์๊ฐ ์ ํ์ํ ๊น ? ๋ก์ปฌ ์ ์ฅ์๋ฅผ ์์ฃผ ์ฌ์ฉํ์ง ์๋ ๊ฐ๋ฐ์ ๋ถ๋ค๋ ์๊ฒ ์ง๋ง ๊ฑฐ์ ๋๋ถ๋ถ์ ํญ ๋๊ฒ ์ฌ์ฉํ๊ณ ์์๊ฑฐ๋ผ ์๊ฐํ๋ค.
์ ๋ ์ฑ ๊ฐ๋ฐ์ ์งํํ ๋ ์์ฝ๊ฒ Firebase๋ฅผ ์ฌ์ฉํด Fiestore DB๋ฅผ ์ฌ์ฉํ๊ณ ์์ง๋ง, ๋ฌด๋ฃ ํฐ์ด๊ฐ ์ง๋๊ณ ๋๋ฉด ๊ณผ๊ธ์ด ๋๊ธฐ์ ๋ก์ปฌ ์ ์ฅ์๋ฅผ ํจ๊ป ์ฌ์ฉํด ์ด๋ฌํ ๋ฆฌ์์ค๋ฅผ ์ค์ด๋๋ฐ ๋์์ด ๋๊ณ ์๋ค.
๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ก์ปฌ ์ ์ฅ์ ๋ง์ผ๋ก ์ฌ์ฉํ ์๋ ์์ง๋ง ์์๋๋ฉด ๊ผญ ์ฌ์ฉํ ์ผ์ด ์๊ธธ ๊ฒ์ด๋ค.
Hive๋ NoSQL DB์ธ๋ฐ, ๋ก์ปฌ ์ ์ฅ์๋ฅผ ๋ณต์กํ ๊ด๊ณํ ๊ตฌ์กฐ๋ก๋ ๊ตฌ์ถํ์ง ์๊ธฐ์ ์ ๋ Hive๊ฐ ๊ฐ์ฅ ์ข์ ์ ํ์ง๋ผ๊ณ ๋ณธ๋ค.
Hive๊ฐ ์๋๋๋ผ๋ SQLite, Sembast, Floor, Drift ๋ฑ ๋ค์ํ ๋ก์ปฌ ์ ์ฅ์ ํํ๋ฅผ ์ ๊ณตํ๊ณ ์๋ค.
NoSQL ๊ตฌ์กฐ๋ํ ์ต์ํ key-value ๊ตฌ์กฐ์ด๊ธฐ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฒ์ ๋ค๋ค๋ณด๋ ๊ฐ๋ฐ์ ๋ถ๋ค๋ ์์ฝ๊ฒ ์ฌ์ฉํด ๋ณผ ์ ์์ ๊ฒ ๊ฐ๋ค. NoSQL์ ๋ํด์ ์ ๋ชจ๋ฅด์๋ฉด CRUD์ ๊ฐ๋ ๋ง ํ์ ํ์ ๋ ๊ฐ๋จํ๊ฒ ์ฌ์ฉํ๋๋ฐ ๋ฌธ์ ๋ ์๋ค.
dependencies์ hive package ๋ค์ ์ถ๊ฐํด ์ฃผ๋๋ก ํ์.
๋จผ์ hive ์ฌ์ฉ์ ์ํด hive ํจํค์ง๋ ๋น์ฐํ ์ถ๊ฐ๋์ด์ผ ํ๊ณ , hive_flutter๋ hive ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ flutter์์ ์ฌ์ฉํ๊ธฐ ์ํด ๊ผญ ์ถ๊ฐ๋์ด์ผ ํ๋ ํ์ฅ ํจํค์ง์ด๋ค.
hive๋ Hive ๋ฐ์ดํฐ๋ฒ ์ด์ค ํจํค์ง์ด๊ณ , hive_flutter ํจํค์ง๊ฐ ๋ฐ๋ก flutter์์ hive ์ฌ์ฉ์ ๋์์ฃผ๋ ๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
dev_dependencies์ hive_generator, build_runner ํจํค์ง๊ฐ ์ถ๊ฐ๋์ด์ผ ํ๋๋ฐ, ์ด ๋ถ๋ถ์ ์ ํ ์ฌํญ์ด๋ค.
hive์์ ๊ฐ์ฒด๋ฅผ ์ด์ฉํ ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ฅผ ํ๊ณ ์ถ๋ค๋ฉด hive์์ ์ง์ํ๋ ๊ฐ์ฒด ์ง์ ๊ธฐ๋ฅ์ธ TypeAdapter๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
TypeAdapter๋ code generator๋ก ์์ฑ๋๊ธฐ ๋๋ฌธ์, build_runner, hive_generator๋ฅผ ์ถ๊ฐํด ์ฃผ์ด์ผ ํ๋ค.
๊ฐ์ฒด ์ฌ์ฉ์ด ํ์ ์๋ค๋ฉด ๊ตณ์ด ์ถ๊ฐํ์ง ์์๋ ๋ฉ๋๋ค.
dependencies:
hive: ^2.2.3
hive_flutter: ^1.1.0
dev_dependencies:
build_runner: ^2.4.7
hive_generator: ^2.0.1
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก hive ์ฌ์ฉ์ ํด๋ณด๋๋ก ํ์. hive ์ฌ์ฉ์ ์ํด ๊ฐ์ฅ ๋จผ์ ํด์ผ ํ๋ ๋ถ๋ถ์ ๋น์ฐํ hive ์ด๊ธฐํ๋ฅผ ์งํํด ์ฃผ์ด์ผ ํ๋ค.
Flutter Applications
await Hive.initFlutter();
Non Flutter Applications
await Hive.init();
main()
void main() async {
await Hive.initFlutter();
runApp(const MyApp());
}
hive ์ฌ์ฉ์ ์์๋์ด์ผ ํ๋ ๊ฐ๋ ์ด box์ด๋ค. ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํ๋์ ๊ณต๊ฐ์ box๋ผ๊ณ ํ๋๋ฐ, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Table, NoSQL ๊ตฌ์กฐ์ collection์ด๋ผ๊ณ ์ดํดํ๋ฉด ์ฌ์ธ ๊ฒ ๊ฐ๋ค.
box๋ ํค ๊ฐ์ ์ง์ ํ์ฌ ์ ๊ทผํด ์ฌ์ฉํ๋๋ฐ, box๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๋จผ์ box๋ฅผ ์ด๊ณ ์์ด์ผ๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค.
box๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค. ์๋ ์ฝ๋๋ฅผ ์ฌ์ฉํด์ ํธ์ถํ๋ฉด ๋๋๋ฐ, ํธ์ถ์ box๋ฅผ ์์ฑํ ๋ ์ง์ ํ ํค ๊ฐ์ผ๋ก ํธ์ถํ๋ฉด ๋๋ค.
๋ง์ผ ํด๋นํ๋ ํค ๊ฐ์ ์์ฑํ box๊ฐ ์๋ค๋ฉด ์๋ก์ด box๋ฅผ ์์ฑํ๊ฒ ๋๊ณ , ์กด์ฌ ํ๋ค๋ฉด ์ผ์นํ๋ box๋ฅผ ์ด์ด์ค๋ค.
await Hive.openBox("openBox");
๋ง์ผ box๋ฅผ ์คํํ์ง ์๊ณ ์ ๊ทผํ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น ? ์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
Unhandled Exception: HiveError: Box not found. Did you forget to call Hive.openBox()?
openBox()
๋ฅผ ํ๊ฒ๋๋ฉด, box๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฌ๋ ค๋๊ฒ ๋๋๋ฐ, openBox๋ฅผ ํธ์ถํ ์์ ์ด ์๋ box์ ์ ๊ทผํ๋ ์์ ์ box๋ฅผ ์ด๊ณ ์ถ๋ค๋ฉด lazyํ๊ฒ ์ฒ๋ฆฌํด ์ฃผ๋ฉด ๋๋ค.
Hive.openLazyBox("openBox");
์ด๋ฏธ ์คํ๋ box๋ฅผ ๋ฐ๋ณตํด์ ์คํํ๋ ๋ถ๋ถ์ ๋ํด์๋ ํด๋น ๊ธฐ๋ฅ์ด ์ฑ๊ธํค์ผ๋ก ์์ฑ ๋์๊ธฐ ๋๋ฌธ์, ๊ธฐ์กด box๋ฅผ ๋ฆฌํดํ๊ฒ ๋์ด ์์ด ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค๊ณ ํ๋ค.
์คํ๋ box์ ์ ๊ทผํด์ ๋ฐ์ดํฐ๋ฅผ ์ค์ ๋ก ์ ์ฅํด๋ณด๋๋ก ํ์.
hive์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ๋จผ์ key-value ๊ตฌ์กฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ , key ์์ด value๋ง ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
put
person box๋ฅผ ํ๋ ๋ง๋ค์ด์ put ํจ์๋ฅผ ์ฌ์ฉํด key: "name", value: "tyger"๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด๋ณด๋๋ก ํ์.
Hive.openBox("person");
Box box = Hive.box("person");
box.put("name", "tyger");
์ ์ฅ๋ ๊ฐ์ ํ์ธํ๊ณ ์ถ๋ค๋ฉด ๋ก๊ทธ๋ฅผ ์ฐ์ด๋ณด๋ฉด ๋๋ค.
print(box.values);
name์ผ๋ก tyger ๊ฐ์ด ์ ์ ์ฅ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด๋ฒ์ age ๊ฐ๋ ์ ์ฅํด๋ณด์. ์ ์ฅ ํ ์ถ๋ ฅํด๋ณด๋ฉด (20, tyger) ์ด๋ ๊ฒ ๊ฐ์ด ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
box.put("age", 20);
add
์ด๋ฒ์ add()
ํจ์๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด๋ณด์. ํค ๊ฐ์ด ๋ฐ๋ก ์๊ธฐ ๋๋ฌธ์, value๋ง ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
Box box = Hive.box("person");
box.add("tyger1");
์ ์ฐ์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒ์ ํ์ธํ๋ค. ์ด์ ์ ์ฅํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ์ค๋ฉด์ put()
, add()
์ ์ฅ ๋ฐฉ์์ ์ฐจ์ด์ ๊ณผ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง๋ฅผ ์ดํด๋ณด๋๋ก ํ์.
์ง๊ธ๊น์ง ์ ์ฅํ person box์ value๋ค์ ํธ์ถํด๋ณด๋ฉด, ๋ฌธ์ ์์ด ์ถ๋ ฅ์ด ๋๋ค.
Box box = Hive.box("person");
print(box.values);
// (tyger1, 20, tyger)
์ด๋ฒ์ person box์ key๋ค์ ํธ์ถํด๋ณด์.
์ถ๋ ฅํด ๋ณด๋ฉด "(0, age, name)" ์ด๋ ๊ฒ ์ถ๋ ฅ์ด ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
add๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฒ ๋๋ฉด, ํค ๊ฐ์ด ์ธ๋ฑ์ค ์์๋ก ์๋์ผ๋ก ์ง์ ๋์ด์ ํค์ 0์ด๋ผ๋ ๊ฐ์ด ์ง์ ๋ ๊ฒ์ด๋ค.
Box box = Hive.box("person");
print(box.keys);
// (0, age, name)
์ด๋ฒ์ key ๊ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํด ๋ณด์.
print(box.get("name"));
// tyger
print(box.get("age"));
// 20
add๋ฅผ ์ฌ์ฉํด ์ ์ฅ๋ ๋ฐ์ดํฐ๋ ํค ๊ฐ์ผ๋ก ์กฐํ๋ฅผ ํ ์ ์๋ค. ๋ฌผ๋ก ํค ๊ฐ์ ์ฐพ์ ์กฐํ๋ฅผ ํ๋ ค๋ฉด ํ ์๋ ์๊ฒ ์ง๋ง ์ข์ ๋ฐฉ์์ ์๋๋ค.
add()
์ put()
์ ๋ํด์๋ ์๋์์ TypeAdapter ๋ถ๋ถ์ ๋ฐฐ์ฐ๋ฉด์ ๋ ์์ธํ ๋ค๋ฃจ๋๋ก ํ๊ฒ ๋ค.
์ด์ด์ ๋ฐ์ดํฐ ์กฐํ์ ์กด์ฌํ์ง ์๋ ํค ๊ฐ์ผ๋ก ์กฐํ๋ฅผ ํ๊ฒ ๋๋ ๊ฒฝ์ฐ null์ ๋ฆฌํดํ๊ธฐ์ nullable ํ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ฉด ๋๊ณ , default ๊ฐ์ ์ง์ ํ์ฌ ์กฐํํ๊ณ ์ถ๋ค๋ฉด ๊ธฐ๋ณธ ๊ฐ ์ง์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
print(box.get("birthday"));
// null
print(box.get("birthday", defaultValue: 20230101));
// 20230101
์ด๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋๋ก ํ์. ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์ ํค ๊ฐ์ ์ฌ์ฉํด ์ญ์ ํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ , box ์์ฒด๋ฅผ ์ง์ฐ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
delete()
๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ง์ ๋ key ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๊ฒ ๋๋ค.
Box box = Hive.box("person");
box.delete("name");
deleteAll()
์ ํค ๊ฐ๋ค์ ๋ฐฐ์ด๋ก ๋ฐ์ ์กด์ฌํ๋ ํค ๊ฐ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
Box box = Hive.box("person");
box.deleteAll(["name", "age"]);
box ์์ฒด๋ฅผ ์๋ฌด๊ฒ๋ ์๋ ๋น ๋ฐ์ค๋ก ๋ง๋ค๊ณ ์ถ๋ค๋ฉด, clear()
๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
clear()
๋ box์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ์ง์๋ฒ๋ ค ๋น ์ํ๋ก ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ฃผ์ํ์ฌ ์ฌ์ฉํด์ผ ํ๋ค.
Box box = Hive.box("person");
box.clear();
์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
์ฌ์ค Update๋ hive์์๋ Create์ ํฌ๊ฒ ๋ค๋ฅธ๊ฒ ์๋ ๋ถ๋ถ์ด๊ธด ํ๋ค.
Box box = Hive.box("person");
box.put("name", "tyger");
print(box.get("name"));
// tyger
์ด๋ฒ์๋ ์๋ฌธ์๋ก ์ ์ฅํ name์ ๋๋ฌธ์๋ก ๋ณ๊ฒฝํด๋ณด๋๋ก ํ๊ฒ ๋ค.
Box box = Hive.box("person");
box.put("name", "TYGER");
print(box.get("name"));
// TYGER
์ด๋ ๊ฒ hive๋ ๋์ผ ํค ๊ฐ์ ๋ํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ ์ํค๊ณ ์๋ค.
์ง๊ธ๊น์ง hive์ ๊ธฐ๋ณธ ์ ์ธ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด ๋ดค๋ค. ์ฌ์ค key-value ํํ์ ์ ์ฅ์๋ก ์ฌ์ฉ ํ๋ค๋ฉด, shared_preferences์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋์ผํ๋ค๊ณ ๋ณผ ์ ์๋ค.
์ด๋ฒ์๋ ์์์ ์์ธํ ๋ค๋ฃจ์ง ๋ชปํ put()
, add()
์ ๋ํด์ ์ฐจ์ด์ ์ ์ดํด๋ณด๊ณ ์ ์ ํ๊ฒ ์ฌ์ฉํด์ผ ํ๋ ๋ถ๋ถ์ ๋ํด์๋ ๋ค๋ค๋ณด๋๋ก ํ์.
์์์ ์ฌ์ฉํ person ๋ฐ์ค๋ name, age ๋ฅผ ํค ๊ฐ์ผ๋ก ๊ฐ์ง๊ณ ์์ด, ํ๋์ person ๋ง ์์ฑํ ์ ์์๋ค.
์ฌ๋ฌ ๋ช ์ person์ ์ ์ฅํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น ? person ๋ฐ์ค๋ฅผ person1, person2 ... ์ด๋ฐ์์ผ๋ก ์ถ๊ฐํด์ค์ผ ํ ๊น ? .. ์๋๋ค
hive ์์๋ box๊ฐ ํธ์ถ๋ ๋, ๋ฉ๋ชจ๋ฆฌ ํ ์์ญ์ ๊ณต๊ฐ์ ์ฐจ์งํ๊ณ ์๊ธฐ์ ์ธ๋ฐ์์ด box๊ฐ ์์ฑ๋๋ ๊ฒ๋ ๋นํจ์จ ์ ์ผ ์ ์๋ค.
์ฌ๋ฌ ๊ฐ์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฐฐ์ด์ ๋ด์์ฃผ๋ ๋ฐฉ๋ฒ์ด ๋ ์ข์ ๋ฐฉ๋ฒ์ผ ๊ฒ์ด๋ค.
๋ฐ์ดํฐ๋ฅผ ์ข ๋ ๋ณต์กํ ๊ตฌ์กฐ๋ก ์ ์ฅํด ๋ณด๋๋ก ํ์. ํค๋ฅผ person์ผ๋ก ๋ฐ์ดํฐ๋ฅผ Map ๊ตฌ์กฐ๋ก ๋ฃ์ด์ ์ ์ฅํ์๋ค.
Box box = Hive.box("person");
box.put("person", {
"name": "tyger",
"age": 20,
});
final person = box.get("person");
print(person);
print(person["name"]);
// {name: tyger, age: 20}
// tyger
ํด๋น ๊ตฌ์กฐ์์ person1, person2 ๋ฅผ ์ถ๊ฐํ๋๋ก ํ์. ํ ๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ๋ค๋ฉด putAll()
๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ค.
box.putAll({
"person1": {
"name": "tyger1",
"age": 30,
},
"person2": {
"name": "tyger2",
"age": 40,
},
});
print(box.values);
// {name: tyger, age: 20}, {name: tyger1, age: 30}, {name: tyger2, age: 40}
์์ ๋ฐฉ๋ฒ์ด ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ๊น ? ๋ฌผ๋ก ์ ๋ ๊ฒ ์ ์ฅํด์ ์ฌ์ฉํด๋ ๋๋ค. ํ์ง๋ง ํค ๊ฐ์ ๋ฐ๋ก ์ฃผ์ง ์๊ณ , mapIndexed ํํ์ ์ํด ์๋์ผ๋ก ํค ๊ฐ์ด ๋ถ์ฌ ๋๊ฒ ์ ์ฅํด์ฃผ๋ ๋ฐฉ๋ฒ์ด ๋ ์ข์ ๊ฒ์ด๋ค.
person box๋ฅผ ์์์ ๋ฐฐ์ด clear()
ํจ์๋ฅผ ์ฌ์ฉํด ์ ๋ถ ๋น์์ฃผ๊ณ ์ด๋ฒ์๋ addAll()
๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด ๋ณด๋๋ก ํ์.
Box box = Hive.box("person");
box.addAll([
{
"name": "tyger",
"age": 20,
},
{
"name": "tyger1",
"age": 30,
},
{
"name": "tyger2",
"age": 40,
},
]);
print(box.values);
print(box.getAt(2));
// ({name: tyger, age: 20}, {name: tyger1, age: 30}, {name: tyger2, age: 40})
// {name: tyger2, age: 40}
์์ ๋ฐฉ์์ ์ฌ์ฉํด์ ๋์ผํ ๊ตฌ์กฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ์์ฝ๊ฒ ์ ์ฅํ ์ ์๊ฒ ๋ฌ๋ค.
ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ๋์ ์๋ก์ด ๋ฐฉ๋ฒ์ด ์ฌ์ฉ ๋ฌ๋๋ฐ, ๋ฐ๋ก getAt(index)
๊ธฐ๋ฅ์ด๋ค. ๋ฐฐ์ด์ ์ธ๋ฑ์ค ๊ฐ์ ์กฐํํ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ์์ ํ ๋์ผํ๋ฉฐ, ๋ฐฐ์ด์ ์ธ๋ฑ์ค ๊ฐ๋ณด๋ค ํฐ ๋ฒ์๋ฅผ ์กฐํํ๊ฒ ๋๋ฉด ๋น์ฐํ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์์ ๋ฐฉ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ ํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํ๋ฉด ๋ ๊น ? ํค ๊ฐ์ ๋ชจ๋ฅด๋ ์ํ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ฉด ์ฟผ๋ฆฌ๋ฅผ ํตํด ํค ๊ฐ์ ์ฐพ์์ฌ ์ ์๋ค.
hive ์ ์ฅ์์ ์ฟผ๋ฆฌ ์ง์ ๋ฐฉ์์ ํค ๊ฐ์ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด๋ ๋๊ณ , add ํจ์๋ฅผ ์ฌ์ฉํด ์๋ ํค๋ฅผ ์์ฑํ ๊ฒฝ์ฐ๋ผ๋ฉด, Flutter์ ๋ฆฌ์คํธ ์กฐํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
hive ๊ณต์ ๋ฌธ์์๋ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ์ง ์๋๊ฒ ๋จ์ ์ ์๋๋ผ๊ณ ๋์์๋ค. ์ค์ ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ Flutter์์ ์ง์ ์ฒ๋ฆฌํ๋๊ฒ ์๋๋ฉด์์๋ ๋ ์ข๋ค.
Hive does not have a query language and only has limited support for sorting, which is not necessarily a disadvantage, as you can see in the benchmark. Sorting and filtering are much faster if you do it yourself in Dart.
age๊ฐ 30์ธ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด ์ค๋๋ก ํ์. ๊ฐ๋จํ๋ค. ๊ธฐ์กด ๋ฐฐ์ด ์ฌ์ฉ ๋ฐฉ๋ฒ๊ณผ ์์ ํ ๋์ผํ๊ธฐ ๋๋ฌธ์ ์์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
List<dynamic> query = box.values.where((e) => e["age"] == 30).toList();
print(query);
// [{name: tyger1, age: 30}]
์กฐํํ ๋ฐ์ดํฐ์ age๋ฅผ 25๋ก ๋ณ๊ฒฝํด ๋ณด๋๋ก ํ์.
์กฐํํ ๋ฐ์ดํฐ์ ๋ฐฐ์ด index ๊ฐ์ ์ฐพ์ ํด๋น index์ ์ ๊ทผํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ ํด ์ค๋๋ก ํ์. ์ด ๋ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ด ๋ฐ๋ก putAt(index)
๊ธฐ๋ฅ์ด๋ค.
print(box.values);
// ({name: tyger, age: 20}, {name: tyger1, age: 30}, {name: tyger2, age: 40})
List<dynamic> query = box.values.where((e) => e["age"] == 30).toList();
int index = query.map((e) => box.values.toList().indexOf(e)).first;
box.putAt(index, {
"name": query.first["name"],
"age": 25,
});
print(box.values);
// ({name: tyger, age: 20}, {name: tyger1, age: 25}, {name: tyger2, age: 40})
์ด์ ๋ง์ง๋ง์ผ๋ก ์ข ๋ ๋ํ ์ผํ๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด์ hive์ ์ค์ํ ๊ธฐ๋ฅ์ธ TypeAdapter์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ๊ฒ ๋ค.
TypeAdapter๋ hive ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ ์ ์๋๋ก ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์ง๊ธ๊น์ง๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๊ณ Map ๊ตฌ์กฐ๋ก๋ง ๋ฐ์ดํฐ๋ฅผ ๋ค๋ค๋ดค๋๋ฐ, ๋ถํธํ๊ณ ์ํํ๋ค.
๋ณต์กํ ๊ตฌ์กฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ถ๋ค๋ฉด TypeAdapter๋ ํ์์ ์ผ๋ก ์ฌ์ฉํด์ผ ํ๋ ๊ธฐ๋ฅ์ผ ๊ฒ์ด๋ค.
์ด๋ฒ์๋ ์๋์ฐจ ๊ณต์ฅ์์ ์์ฐํ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ hive์ ์ ์ฅํ๊ณ ์์ ํ๊ณ ์ญ์ ํด ๋ณด๋ฉด์ ์ฌ์ฉํด ๋ณด๋๋ก ํ๊ฒ ๋ค.
๋จผ์ , ๊ณต์ฅ์์ ์์ฐํ ์ ์๋ ๋ชจ๋ธ์ ์์ฑํด์ฃผ๊ธฐ ์ํด Car ๋ชจ๋ธ์ ์์ฑํด ์ฃผ๋๋ก ํ์.
Code Generator๋ ์์ฑ๋๋ ์ ํด์ง ๊ท์น์ ๋ฐ๋์ ๋ฐ๋ผ์ผ๋ง ์ ๋๋ก ์ฝ๋๊ฐ ์์ฑ์ด ๋๋ค.
hive_generator์์๋ annotation์ผ๋ก ๊ฐ์ฒด์ HiveType(typeId: id)์ ๊ฐ ํ๋์ HiveField(id)๋ฅผ ๋ฃ์ด์ฃผ๊ฒ ๋์ด์๋ค.
๊ฐ์ฒด๊ฐ HiveType์ id๋ ์ค๋ณต๋ ์ ์์ผ๋ฉฐ, 1~222 ๋ฒ์ ๋ด์์๋ง ์ฌ์ฉํด์ผ ํ๋ค.
๊ฐ ํ๋๋ ๊ฐ์ฒด ๋ด์์๋ ์ค๋ณต๋ ์ ์์ผ๋ฉฐ, 0~255 ๋ฒ์ ๋ด๋ก๋ง ์ฌ์ฉํ ์ ์๋ค.
255๋ฒ์ด๋ฉด ํ๋ ์์ฑ์๋ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๊ธฐ์ ์ฐธ๊ณ ๋ง ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๋ณ์ ํ์ ์ผ๋ก๋ Flutter์ ๊ธฐ๋ณธ ํ์ ์ ์ง์ํ์ง๋ง, ๋ง์ผ MaterialColor๋ฅผ ์ ์ฅํ๊ณ ์ถ๋ค๋ฉด MatrialColor ๊ฐ์ฒด๋ฅผ ์์๋ฐ์ ์๋กญ๊ฒ ๋ง๋ค์ด์ฃผ๊ณ ์ฌ์ฉํด์ผ ํ๋ค.
part 'car.g.dart';
(typeId: 1)
class Car {
(0)
int number;
(1)
Brand type;
(2)
String name;
(3)
List<String> colors;
(4)
bool isRoof;
Car({
required this.number,
required this.brand,
required this.name,
required this.colors,
required this.isRoof,
});
String toString() =>
"Car(number: $number, brand: $brand, name: $name, colors: $colors, isRoof: $isRoof)";
}
enum ๊ฐ์ฒด๋ ์์ฑํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
part 'brand.g.dart';
(typeId: 2)
enum Brand {
(0)
hyundai,
(1)
kia,
(2)
genesis,
}
Code Generator
Code Generator๋ฅผ ์ฌ์ฉํด ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑ๋๋๋ก ํ๋ฉด ๋๋ค. ์ฌ์ฉ ๋ฐฉ๋ฒ์ ํฌ๊ฒ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ build_runner๋ฅผ ํ ๋ฒ๋ง ์คํํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ , ์ง์์ ์ผ๋ก ์คํํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ํธํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.
Generator๊ฐ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋๋ฉด _.g.dart ๋ผ๋ ํ์ผ์ด ์ถ๊ฐ๋ก ์์ฑ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
case 1 flutter pub run build_runner build
case 2 flutter pub run build_runner watch --delete-conflicting-outputs
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด ๋ณด๋๋ก ํ์.
Box box = Hive.box("car_factory");
box.add(Car(
number: 0,
brand: CarType.hyundai,
name: "name",
colors: ["red"],
isRoof: false,
),
);
์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ์์ฑํ TypeAdapter๋ฅผ ๋ฑ๋กํ์ง ์๊ณ ์ฌ์ฉํด์ ๋ฐ์ํ ๋ฌธ์ ์ด๋ค.
HiveError (HiveError: Cannot write, unknown type: Car. Did you forget to register an adapter?)
TypeAdapter๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ฐ๋์ ๋ฑ๋ก ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค.
๋ฑ๋ก ๋ฐฉ๋ฒ์ ์ฌ์ฉ ์ ํจ์๋ฅผ ํธ์ถํด ์ฃผ๋ฉด ๋๋ค. ์ฐ๋ฆฌ๋ Car, CarType ๊ฐ์ฒด 2๊ฐ๋ฅผ ์์ฑ ํ์๊ธฐ์, ๊ฐ๊ฐ ๋ฑ๋กํด์ฃผ๋ฉด ๋๋ค.
Hive.registerAdapter(CarAdapter());
Hive.registerAdapter(BrandAdapter());
๋ฐ์ดํฐ๋ฅผ ๋ค์ ์ ์ฅํด ๋ณด์.
final List<Car> cars = [
Car(
number: 0,
brand: Brand.hyundai,
name: "Grandeur",
colors: ["black", "white", "grey"],
isRoof: true),
Car(
number: 0,
brand: Brand.hyundai,
name: "Santafe",
colors: ["black", "white"],
isRoof: true),
Car(
number: 0,
brand: Brand.kia,
name: "Ray",
colors: ["black", "cyan", "red"],
isRoof: false),
Car(
number: 0,
brand: Brand.genesis,
name: "GV80",
colors: ["black", "khaki", "navy"],
isRoof: true),
];
addAll()
๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ํ ๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด ์ฃผ๋๋ก ํ์.
Box box = Hive.box("car_factory");
box.addAll(cars);
print(box.values);
๋ง์ง๋ง์ผ๋ก valueListenable ํ์ ์ ์ง์ํด ์ฃผ๊ณ ์์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณ๊ฒฝ์ ์ฆ์ ์๋ ค์ค ์ ์๋ค.
ValueListenableBuilder<Box>(
valueListenable: Hive.box("car_factory").listenable(),
builder: (BuildContext context, Box value, Widget? child) {
...
}),
To-Do ๋ฆฌ์คํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ๋จํ ์ฑ์ Hive ๋ก์ปฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์๋ค.
Hive DB๋ฅผ ์์ง ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง ์ดํด๊ฐ ๋์ง ์์ผ์ ๋ถ๋ค์ ํด๋น ์ฝ๋๋ฅผ ์คํ์์ผ ๋ณด๋ฉด, ์ฝ๊ฒ ์ดํดํ ์ ์์ ๊ฒ ๊ฐ๋ค.
To-Do ์ฑ์ ํ ์ผ์ ์์ฑํ๊ณ , ์์ ํ๊ณ , ์ญ์ ํ ์ ์๋ค.
NoSQL ๊ธฐ๋ฐ์ hive ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด์ ์ดํด ๋ดค๋๋ฐ, ์ฌ์ฉ ๋ฐฉ๋ฒ๋ ๊ฐ๋จํ๊ณ ์๋๋ฉด์์๋ ๊ธ์ ์ ์ธ ๋ถ๋ถ์ด ๋ง์ ๊ฒ ๊ฐ๋ค. ์ฒ์์ ์ฟผ๋ฆฌ ์ง์์ด ๋์ง ์๋ ๋ถ๋ถ์ด ๋ค์ ์์ฝ๋ค๊ณ ์๊ฐ์ ํ๋๋ฐ, ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ flutter์์ ๊ฐ๊ณตํ์ฌ ์ฌ์ฉ ํ ๋ค์ ํ์ํ ๋ฐ์ดํฐ๋ง ์ ์ฅํ๋ฉด ๋์ ๋ ์ฌํํ ๊ฒ ๊ฐ๋ค.
๋งค์ฐ ๋ณต์กํ ๊ตฌ์กฐ์ ๋ก์ปฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก๋ ์ข ๋ ์ฌ์ฉ์ ํด๋ด์ผ ์๊ฒ ์ง๋ง, ํ์ฌ๊น์ง ์ฌ์ฉํด๋ณธ ๋ก์ปฌ ์ ์ฅ์ ์ค์๋ ์ฌ์ฉํ ๋ง ํ ๊ฒ ๊ฐ๋ค.
๊ธํ๊ฒ ์ฌ์ฉํด๋ณด๋ฉด์ ์์ฑํ๋ค ๋ณด๋ ๋น ์ง ๋ด์ฉ์ด ์์ ์๋ ์์ด์, ์ถ๊ฐ๋ก ๊ถ๊ธํ์ ๋ถ์ ์ธ์ ๋ ๋๊ธ ๋จ๊ฒจ์ฃผ์ธ์ !