일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 안드로이드
- Compose
- livedata
- 계측
- Coroutines
- data
- tabbar
- android
- intent
- LifeCycle
- Kotlin
- viewmodel
- Navigation
- scroll
- DART
- textfield
- 테스트
- textview
- 앱
- Button
- activity
- 앱바
- TEST
- appbar
- Flutter
- ScrollView
- drift
- Dialog
- CustomScrollView
- binding
- Today
- Total
Study Record
[Flutter] drift 에서 테이블 데이터 가져오기 (insert, select, delete, update etc) 본문
[Flutter] drift 에서 테이블 데이터 가져오기 (insert, select, delete, update etc)
초코초코초코 2023. 3. 25. 19:24🎁 drift 테이블과 데이터
test_database.dart
import 'package:drift/drift.dart';
import 'dart:io';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
part 'test_database.g.dart';
class Students extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
IntColumn get grade => integer()();
TextColumn get clubName => text()();
}
@DataClassName('ClubRoom')
class Clubs extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get clubName => text()();
IntColumn get studentTotal => integer()();
TextColumn get description => text()();
}
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
TestDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
}
만약 위의 코드와 같이 Todos 테이블과 Clubs 테이블을 설정했다면 "flutter pub run build_runner build" 을 실행한 뒤 생기는 test_database.g.dart 파일에는 각 테이블마다 테이블 클래스와 데이터 클래스, Companion 이 붙은 클래스가 생성된다.
😶 테이블 클래스
ex) Clubs 테이블
😶 데이터 클래스
보통 데이터 클래스는 테이블 이름 뒤의 's' 를 제거한 이름으로 생기는데 @DataClassName 어노테이션에 의해 Clubs 테이블의 데이터 클래스는 Club 가 아닌 ClubRoom 이 된다. Students 테이블은 Student 데이터 클래스가 생긴다.
ex) Clubs 테이블
😶 Companion 클래스
칼럼 변수들이 전부 Value() 에 감싸여 있다.
ex) Clubs 테이블
😶 table
test_database.g.dart 파일에는 데이터베이스 클래스(_$TestDatabase)가 있는데 이곳에 테이블들이 정의되어 있다. (students, clubs) 따라서 test_database.dart 파일에 있는 TestDatabase 클래스에서 테이블에 대한 정보는 students, clubs 로 불러오면 된다.
table, 데이터 클래스 Companion 클래스 등이 실제로 어떻게 사용되는지는 sql 구문을 통해 보면 다음과 같다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
TestDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
Future<int> addStudent(StudentsCompanion entry) {
return into(students).insert(entry);
}
Future<List<Student>> getStudent() {
return select(students).get();
}
}
_TestDatabase 를 상속받는 TestDatabase 는 테이블 변수들을 가볍게 students, clubs 로 참고하면 된다.
addStudent() 는 students 테이블에 데이터를 삽입하는 기능을 하는데 into() 에 테이블 정보를 students, 데이터 정보를 StudentsCompanion 으로 삽입한다.
getStudent() 는 students 테이블에 있는 데이터 전부를 가져오는데 select() 에 테이블 정보를 students 로 get() 해서 가져온다. 가져온 데이터의 타입은 students 의 데이터 클래스로 가져올 수 있다.
✍ SQL queries 사용하기
😶 데이터 삽입 (insert)
int() 함수에 테이블 정보를 넣고 insert() 함수에 Companion 타입의 데이터를 넣으면 된다.
await TestDatabase().addStudent(const StudentsCompanion(
name: Value("choho"),
grade: Value(2),
clubName: Value("Soccer"),
));
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// returns the generated id
Future<int> addStudent(StudentsCompanion entry) {
return into(students).insert(entry);
}
// 여러개의 데이터 한번에 넣기
Future<void> insertMultipleEntries() async {
await batch((batch) {
batch.insertAll(clubs, [
ClubsCompanion.insert(
clubName: 'hahaha',
studentTotal: 30,
description: 'This is a hahaha',
),
ClubsCompanion.insert(
clubName: 'lalala',
studentTotal: 20,
description: 'This is a lalala',
),
]);
});
}
}
😶 데이터 가져오기 (select)
테이블에 있는 데이터 전부를 가져오려면 select() 함수에 원하는 테이블 정보를 넣고 get() 으로 가져온다. Stream 형식으로 자동 업데이트받고 싶으면 watch() 를 사용하면 된다. get() 함수는 단순히 select(students) 를 한 결과인 Selectable<T> 타입을 Future<List<T>> 타입으로 바꿔준다. watch() 함수도 Selectable<T> 타입을 Stream<List<T>> 타입으로 바꿔준다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// select * from students;
Future<List<Student>> getStudent() {
return select(students).get();
}
// 자동 업데이트
Stream<List<Student>> watchStudent() {
return select(students).watch();
}
}
😶 (where) 칼럼 비교하기
where() 함수를 사용하여 조건에 따라 데이터를 거를 수 있는데 where 함수의 리턴값은 void 이므로 ".." 을 사용하여 where() 함수를 사용한 select(clubs) 를 리턴하여 get() 또는 watch() 함수를 사용하여 데이터를 가져온다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// select * from students where studentTotal <= 10;
Future<List<ClubRoom>> getClubsFromTotal(int studentTotal) {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isSmallerOrEqualValue(10),
))
.get();
}
// 자동 업데이트
// select * from students where studentTotal > 10;
Stream<List<ClubRoom>> watchClubsFromTotal(int studentTotal) {
return select(clubs)
..where(
(tbl) => tbl.studentTotal.isBiggerThanValue(10),
))
.watch();
}
}
[Dart] ..
✍ .. "." 을 사용해서 함수를 실행하고 return 값으로 실행한 함수의 return 값이 반환된다. 하지만 ".." 은 리턴값으로 함수를 실행한 대상이 리턴된다. int a = 3; String aStr = a.toString(); final aInt = a..toStri
laustudy.tistory.com
비교 조건으로 사용할 수 있는 함수
...
..where(
(tbl) => tbl.studentTotal.isBiggerThanValue(10),
)
tbl.studentTotal.isBiggerThanValue(10) // > 10
tbl.studentTotal.isBiggerOrEqualValue(10) // >= 10
tbl.studentTotal.isSmallerThanValue(10) // < 10
tbl.studentTotal.isSmallerOrEqualValue(10) // <= 10
tbl.studentTotal.equals(20) // = 10
😶 (where) 칼럼 여러개 비교하기
&, | 키워드를 사용하여 여러개의 조건을 비교할 수 있다.
() & () : "그리고"의 의미로 양쪽의 조건이 모두 참일때만 참이다.
() | () : "또는"의 의미로 한쪽이 참이면 참이다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// select * from clubs where studentTotal > 5 and studentTotal <= 10;
Future<List<ClubRoom>> getClubsFromTotal(int studentTotal) {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isSmallerOrEqualValue(10) &
tbl.studentTotal.isBiggetThanValue(5),
))
.get();
}
// 자동 업데이트
Stream<List<ClubRoom>> watchClubsFromTotal(int studentTotal) {
return select(clubs)
..where(
(tbl) => tbl.studentTotal.isSmallerOrEqualValue(10) &
tbl.studentTotal.isBiggetThanValue(5),
))
.watch();
}
}
😶 (where) null, not null 인 데이터만 가져오기
isNull(), isNotNull() 함수를 사용하여 null 혹은 null 이 아닌 칼럼의 데이터를 가져올 수 있다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future<List<ClubRoom>> getClubsNullTotal() {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isNull(),
))
.get();
}
// 자동 업데이트
Stream<List<ClubRoom>> watchClubsNotNullTotal() {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isNotNull(),
))
.watch();
}
}
😶 (where) IN or Not IN
특정 데이터 집단에 속하는 데이터만 가져올 수 있다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// select * from clubs where studentTotal IN (10, 40, 30);
Future<List<ClubRoom>> getClubsNullTotal() {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isIn([10, 40, 30]),
))
.get();
}
// 자동 업데이트
// select * from clubs where studentTotal NOT IN (10, 40, 30);
Stream<List<ClubRoom>> watchClubsNotNullTotal() {
return (select(clubs)
..where(
(tbl) => tbl.studentTotal.isNotIn([20, 30]),
))
.watch();
}
}
😶 (where) 날짜 타입 비교하기
날짜 데이터(dateTime)일 경우, year, month, day, hour, minute, second 별로 각각을 쉽게 비교할 수 있다.
select(users)..where((u) => u.birthDate.year.isLessThan(1950));
😶 (where) 문자열 찾기(like)
TextCloumn 타입을 가진 칼럼 중 like 를 사용하여 일치하는 문자열이 있는 데이터만 가져올 수 있다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
// name 칼럼에 "kim" 문자열이 포함된 데이터 가져오기
Future<List<Student>> getStudentPattern(String pattern) {
return (select(students)..where((tbl) => tbl.name.like("%kim%")))
.get();
}
Stream<List<Student>> watchStudentPattern(String pattern) {
return (select(students)..where((tbl) => tbl.name.like("%kim%")))
.watch();
}
}
😶 Single Value
List 데이터가 아닌 단일 데이터를 가져오고 싶다면 getSingle() 혹은 watchSingle() 로 가져오면 된다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future<Student> getStudentSingle() {
return select(students).getSingle();
}
Stream<Student> watchStudentSingle() {
return select(students).watchSingle();
}
}
😶 오름차순 / 내림차순
orderby() 함수로 칼럼에 따라 오름차순, 내림차순을 설정할 수 있다. OrderingTerm.desc() 는 내림차순이고 OrderingTerm.asc() 는 오름차순이다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future<List<Student>> getStudent() {
return (select(students)..orderBy([(t) => OrderingTerm.desc(t.grade)]))
.get();
}
Stream<List<Student>> watchStudent() {
return (select(students)..orderBy([(t) => OrderingTerm.asc(t.grade)]))
.watch();
}
}
😶 (join) 테이블 조인
join 은 join() 함수를 사용하여 구현할 수 있다. 다음 예시는 stduents 과 clubs 를 조인한 예시이다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future<List<Student>> getStudentsClubsFromStudentTotal(int total) {
final query = select(students)
.join([innerJoin(clubs, clubs.clubName.equalsExp(students.clubName))]);
query.where(students.name.length.isSmallerThanValue(3));
return query.map((row) => row.readTable(students)).get();
}
Stream<List<Student>> watchStudentsClubsFromStudentTotal(int total) {
final query = select(students)
.join([innerJoin(clubs, clubs.clubName.equalsExp(students.clubName))]);
query.where(students.name.length.isSmallerThanValue(3));
return query.map((row) => row.readTable(students)).watch();
}
}
😶 데이터 삭제(delete)
delete() 를 사용해서 테이블의 데이터를 삭제할 수 있다. where() 조건으로 조건에 맞는 데이터만 삭제할 수 있다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future allDeleteStudents() {
// students 데이터 전부 삭제
return delete(students).go();
}
Future deleteStudentsFromName(String name) {
// students name 이 동일한 데이터만 삭제
return (delete(students)..where((tbl) => tbl.name.equals(name))).go();
}
}
😶 데이터 업데이트(update)
update() 를 사용하여 데이터를 업데이트할 수 있다.
@DriftDatabase(tables: [Students, Clubs])
class TestDatabase extends _$TestDatabase {
...
Future updateStudent(int id, StudentsCompanion student) {
return (update(students)..where((tbl) => tbl.id.equals(id))).write(student);
}
}
Writing queries
Writing queries Learn how to write database queries in pure Dart with drift Note: This assumes that you've already completed the setup. For each table you've specified in the @DriftDatabase annotation on your database class, a corresponding getter for a ta
drift.simonbinder.eu
'Flutter > 라이브러리' 카테고리의 다른 글
[Flutter] 간단한 데이터 저장 (flutter_secure_storage) (0) | 2023.04.07 |
---|---|
[Flutter] drift 에서 Future 와 Stream 차이점 (2) | 2023.03.26 |
[Flutter] 데이터베이스 importing (drift) (0) | 2023.03.26 |
[Flutter] 데이터베이스 table 만들기 (drift) (0) | 2023.03.24 |
[Flutter] drift 시작하기 (Sql 기반 데이터베이스와 테이블 만들기) (0) | 2023.03.23 |