Cara Cepat Membuat CRUD dengan Flutter dan SQFlite

Share:
Cara Cepat Membuat CRUD dengan Flutter dan SQFlite
Halo semuanya, kembali lagi di sahretech. Pada kesempatan kali ini kita akan belajar membuat CRUD flutter dan SQflite dengan studi kasus aplikasi kontak. Penasaran?, ayo ikuti pembahasannya di bawah ini.


Pada tutorial kali ini, kita akan membuat project sederhana. Kita akan mengimplementasikan proses create, read, update, dan delete dengan database SQFlite. Jadi nantinya kita akan membuat tampilan listview di halaman utama yang menampilkan info kontak dari setiap orang, berisi nama, email, no telpon, dan company. Lalu terdapat floating action button yang berfungsi untuk menambah data nantinya. Kita akan belajar banyak hal di tutorial ini. Apa saja?

    ⦿ Membuat daftar/list dengan Listview Builder
    ⦿ Konsep Model,
    ⦿ Menampilkan, Menyimpan, Meng-update, dan delete data dengan SQFlite
    ⦿ Menampilkan Alert dengan Alert Dialog
    ⦿ Melakukan perpindahan halaman dengan Navigator
    ⦿ Dan masih banyak lainnya.....

Cukup banyak ilmu yang bisa kita dapatkan dari tutorial singkat ini, dan sangat berguna untuk improvisasi pembuatan aplikasi berbasis flutter yang lebih kompleks lagi. Dan jika kalian ingin melihat hasil akhirnya, silahkan langsung scroll saja ke bagian paling bawah tutorial ini.


Baca Artikel Lain ✨
📰 1. Cara Membuat Pencarian pada ListView Flutter read more
📰 2. Cara Mudah Install dan Menggunakan SQLite di Laravel read more
📰 3. Cara Switch Tampilan dari ListView Menjadi GridView di Flutter read more



Cara Membuat CRUD dengan Flutter dan SQFlite

1. Buatlah sebuah project flutter dengan nama flutter_contact.

2. Buka pubspec.yaml, lalu copy library SQFlite di bawah ini lalu paste di bawah cupertino icon. 

sqflite: ^2.0.0+3

Ikuti instruksinya seperti gambar di bawah ini. Setelah ditambahkan, silahkan save untuk mengunduh library SQFlite.

Cara CRUD Flutter dan SQFlite
Import Library SQFlite


3. Buatlah struktur folder project kita seperti gambar di bawah ini. Terdapat folder model berisi file kontak.dart, terdapat folder database berisi file db_helper.dart, dan terdapat 3 file lain diantaranya main.dart, list_kontak.dart dan form_kontak.dart.

CRUD Flutter dan SQFlite
Struktur Folder 



4. Silahkan buka file model/kontak.dart. Lalu copy dan paste script di bawah ini.
    

// ignore_for_file: file_names, unnecessary_this, prefer_collection_literals class Kontak{     int? id; String? name; String? mobileNo; String? email; String? company; Kontak({this.id, this.name, this.mobileNo, this.email, this.company}); Map<String, dynamic> toMap() {     var map = Map<String, dynamic>(); if (id != null) { map['id'] = id; } map['name'] = name; map['mobileNo'] = mobileNo; map['email'] = email; map['company'] = company; return map;     } Kontak.fromMap(Map<String, dynamic> map) {     this.id = map['id']; this.name = map['name']; this.mobileNo = map['mobileNo']; this.email = map['email']; this.company = map['company'];     } }


5. Selanjutnya buka file database/db_helper.dart. Copy dan paste script di bawah ini. File ini memuat fungsi-fungsi database. Seperti pembuatan database, fungsi penyimpanan, fungsi tampil, fungsi update, dan fungsi delete. Fungsi-fungsi ini akan dipanggil saat dibutuhkan nantinya.
        

// ignore_for_file: non_constant_identifier_names //dbhelper ini dibuat untuk //membuat database, membuat tabel, proses insert, read, update dan delete import 'package:flutter_contact/model/kontak.dart'; import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqlite_api.dart'; import 'package:path/path.dart'; class DbHelper {     static final DbHelper _instance = DbHelper._internal(); static Database? _database; //inisialisasi beberapa variabel yang dibutuhkan final String tableName = 'tableKontak'; final String columnId = 'id'; final String columnName = 'name'; final String columnMobileNo = 'mobileNo'; final String columnEmail = 'email'; final String columnCompany = 'company'; DbHelper._internal(); factory DbHelper() => _instance; //cek apakah database ada Future<Database?> get _db async {     if (_database != null) {     return _database; } _database = await _initDb();     return _database; } Future<Database?> _initDb() async {     String databasePath = await getDatabasesPath(); String path = join(databasePath, 'kontak.db'); return await openDatabase(path, version: 1, onCreate: _onCreate); } //membuat tabel dan field-fieldnya Future<void> _onCreate(Database db, int version) async {     var sql = "CREATE TABLE $tableName($columnId INTEGER PRIMARY KEY, "     "$columnName TEXT," "$columnMobileNo TEXT," "$columnEmail TEXT," "$columnCompany TEXT)"; await db.execute(sql);     } //insert ke database Future<int?> saveKontak(Kontak kontak) async {     var dbClient = await _db; return await dbClient!.insert(tableName, kontak.toMap());     } //read database Future<List?> getAllKontak() async {     var dbClient = await _db; var result = await dbClient!.query(tableName, columns: [     columnId, columnName, columnCompany, columnMobileNo, columnEmail         ]); return result.toList();     } //update database Future<int?> updateKontak(Kontak kontak) async {     var dbClient = await _db;     return await dbClient!.update(tableName, kontak.toMap(), where: '$columnId = ?', whereArgs: [kontak.id]); } //hapus database Future<int?> deleteKontak(int id) async {     var dbClient = await _db; return await dbClient!.delete(tableName, where: '$columnId = ?', whereArgs: [id]); } }


6. Selanjutnya buka main.dart. Hapus isi di dalamnya dan ganti dengan script di bawah ini.
    

// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, unused_element, non_constant_identifier_names, avoid_types_as_parameter_names, avoid_function_literals_in_foreach_calls, unused_local_variable, unused_import, use_key_in_widget_constructors import 'package:flutter/material.dart'; import 'database/db_helper.dart'; import 'form_kontak.dart'; import 'list_kontak.dart'; import 'model/kontak.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', home: ListKontakPage(), ); } }



7. Selanjutnya buka file list_kontak.dart. Copy script di bawah ini dan paste ke dalam file tersebut. File ini akan membuat list/daftar yang menampilkan seluruh data dari database nantinya, tidak lupa juga kita tambahkan fungsi tampil data dari db_helper.dart
    

// ignore_for_file: prefer_const_literals_to_create_immutables, prefer_const_constructors, avoid_function_literals_in_foreach_calls, non_constant_identifier_names, unused_element, unused_local_variable, sized_box_for_whitespace import 'package:flutter/material.dart'; import 'form_kontak.dart'; import 'database/db_helper.dart'; import 'model/kontak.dart'; class ListKontakPage extends StatefulWidget { const ListKontakPage({ Key? key }) : super(key: key); @override _ListKontakPageState createState() => _ListKontakPageState(); } class _ListKontakPageState extends State<ListKontakPage> { List<Kontak> listKontak = []; DbHelper db = DbHelper(); @override void initState() { //menjalankan fungsi getallkontak saat pertama kali dimuat _getAllKontak(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Center( child: Text("Kontak App"), ), ), body: ListView.builder( itemCount: listKontak.length, itemBuilder: (context, index) { Kontak kontak = listKontak[index]; return Padding( padding: const EdgeInsets.only( top: 20 ), child: ListTile( leading: Icon( Icons.person, size: 50, ), title: Text( '${kontak.name}' ), subtitle: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only( top: 8, ), child: Text("Email: ${kontak.email}"), ), Padding( padding: const EdgeInsets.only( top: 8, ), child: Text("Phone: ${kontak.mobileNo}"), ), Padding( padding: const EdgeInsets.only( top: 8, ), child: Text("Company: ${kontak.company}"), ) ], ), trailing: FittedBox( fit: BoxFit.fill, child: Row( children: [ // button edit IconButton( onPressed: () { _openFormEdit(kontak); }, icon: Icon(Icons.edit) ), // button hapus IconButton( icon: Icon(Icons.delete), onPressed: (){ //membuat dialog konfirmasi hapus AlertDialog hapus = AlertDialog( title: Text("Information"), content: Container( height: 100, child: Column( children: [ Text( "Yakin ingin Menghapus Data ${kontak.name}" ) ], ), ), //terdapat 2 button. //jika ya maka jalankan _deleteKontak() dan tutup dialog //jika tidak maka tutup dialog actions: [ TextButton( onPressed: (){ _deleteKontak(kontak, index); Navigator.pop(context); }, child: Text("Ya") ), TextButton( child: Text('Tidak'), onPressed: () { Navigator.pop(context); }, ), ], ); showDialog(context: context, builder: (context) => hapus); }, ) ], ), ), ), ); }), //membuat button mengapung di bagian bawah kanan layar floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: (){ _openFormCreate(); }, ), ); } //mengambil semua data Kontak Future<void> _getAllKontak() async { //list menampung data dari database var list = await db.getAllKontak(); //ada perubahanan state setState(() { //hapus data pada listKontak listKontak.clear(); //lakukan perulangan pada variabel list list!.forEach((kontak) { //masukan data ke listKontak listKontak.add(Kontak.fromMap(kontak)); }); }); } //menghapus data Kontak Future<void> _deleteKontak(Kontak kontak, int position) async { await db.deleteKontak(kontak.id!); setState(() { listKontak.removeAt(position); }); } // membuka halaman tambah Kontak Future<void> _openFormCreate() async { var result = await Navigator.push( context, MaterialPageRoute(builder: (context) => FormKontak())); if (result == 'save') { await _getAllKontak(); } } //membuka halaman edit Kontak Future<void> _openFormEdit(Kontak kontak) async { var result = await Navigator.push(context, MaterialPageRoute(builder: (context) => FormKontak(kontak: kontak))); if (result == 'update') { await _getAllKontak(); } } }



8. Selanjutnya buka file form_kontak.dart. Copy script di bawah ini dan paste. File ini akan kita gunakan sebagai form add dan edit sekaligus, jadi tidak perlu menggunakan dua file yang berbeda untuk membuat dua form yang sama.
    

// ignore_for_file: prefer_const_constructors_in_immutables, use_key_in_widget_constructors, prefer_const_constructors, non_constant_identifier_names import 'package:flutter/material.dart'; import 'database/db_helper.dart'; import 'model/kontak.dart'; class FormKontak extends StatefulWidget { final Kontak? kontak; FormKontak({this.kontak}); @override _FormKontakState createState() => _FormKontakState(); } class _FormKontakState extends State<FormKontak> { DbHelper db = DbHelper(); TextEditingController? name; TextEditingController? lastName; TextEditingController? mobileNo; TextEditingController? email; TextEditingController? company; @override void initState() { name = TextEditingController( text: widget.kontak == null ? '' : widget.kontak!.name); mobileNo = TextEditingController( text: widget.kontak == null ? '' : widget.kontak!.mobileNo); email = TextEditingController( text: widget.kontak == null ? '' : widget.kontak!.email); company = TextEditingController( text: widget.kontak == null ? '' : widget.kontak!.company); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Form Kontak'), ), body: ListView( padding: EdgeInsets.all(16.0), children: [ Padding( padding: const EdgeInsets.only( top: 20, ), child: TextField( controller: name, decoration: InputDecoration( labelText: 'Name', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), )), ), ), Padding( padding: const EdgeInsets.only( top: 20, ), child: TextField( controller: mobileNo, decoration: InputDecoration( labelText: 'Mobile No', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), )), ), ), Padding( padding: const EdgeInsets.only( top: 20, ), child: TextField( controller: email, decoration: InputDecoration( labelText: 'Email', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), )), ), ), Padding( padding: const EdgeInsets.only( top: 20, ), child: TextField( controller: company, decoration: InputDecoration( labelText: 'Company', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), )), ), ), Padding( padding: const EdgeInsets.only( top: 20 ), child: ElevatedButton( child: (widget.kontak == null) ? Text( 'Add', style: TextStyle(color: Colors.white), ) : Text( 'Update', style: TextStyle(color: Colors.white), ), onPressed: () { upsertKontak(); }, ), ) ], ), ); } Future<void> upsertKontak() async { if (widget.kontak != null) { //update await db.updateKontak(Kontak.fromMap({ 'id' : widget.kontak!.id, 'name' : name!.text, 'mobileNo' : mobileNo!.text, 'email' : email!.text, 'company' : company!.text })); Navigator.pop(context, 'update'); } else { //insert await db.saveKontak(Kontak( name: name!.text, mobileNo: mobileNo!.text, email: email!.text, company: company!.text, )); Navigator.pop(context, 'save'); } } }


9. Sampai disini semua tahap sudah selesai kita kerjakan. Tinggal saatnya kita melakukan uji coba. Silahkan nyalakan emulator kalian dan running app ini. Jika berhasil maka tampilannya akan terlihat seperti gambar di bawah ini.

Cara Membuat CRUD Flutter
Tampilan Akhir




Bagi yang merasa kesulitan mengikuti tutorial kali ini bisa mengunduh projectnya melalui github saya di link berikut ini https://github.com/nabilchen96/flutter_contact

Ok mantap sekali teman-teman!. Sekarang kalian sudah bisa menggunakan database untuk keperluan penyimapanan, menampilkan, peng-updatetan, dan penghapusan data. Saat ini kalian sudah bisa membuat berbagai macam aplikasi. Seperti note keeper, aplikasi pencatatan keuangan, dll.

Ok sekitan tutorial saya kali ini tentang cara membuat aplikasi crud dengan flutter dan sqflite, studi kasus aplikasi kontak. Semoga bermanfaat. Jika ada kesulitan silahkan tanyakan di kolom komentar atau bertanya langsung melalui fanspage sahretech. Sekian dan terima kasih :)

No comments

Jangan lupa kasih komentar ya!. Karena komentar kalian membantu kami menyediakan informasi yang lebih baik