Dart Lesson 46 – Database Integration | Dataplexa

Dart Database Integration

In this lesson, you will learn how Dart applications interact with databases. Database integration is essential for storing, retrieving, and managing persistent data in real-world applications.

We will focus on practical workflows such as saving records, querying data, updating values, and handling failures — exactly how databases are used in production systems.


Why Database Integration Is Important

Without a database, application data is lost when the program stops. Databases allow applications to:

  • Store user information
  • Save transactions and logs
  • Retrieve historical data
  • Maintain application state

Common Databases Used with Dart

  • SQLite (local storage)
  • PostgreSQL
  • MySQL
  • NoSQL databases (MongoDB, Firebase)

Dart interacts with databases using packages and drivers.


Simulating a Database Connection

Before using a real database, let’s simulate a database connection. This helps understand the workflow without external dependencies.

Future connectDatabase() async {
  await Future.delayed(Duration(seconds: 1));
  return true;
}

void main() async {
  bool connected = await connectDatabase();
  print(connected ? "Database Connected" : "Connection Failed");
}

This pattern mirrors real connection logic.


Inserting Data into a Database

Inserting records is one of the most common operations. Below is a simulated insert operation.

Future insertUser(String name, int age) async {
  await Future.delayed(Duration(seconds: 1));
  print("User $name added with age $age");
}

void main() async {
  await insertUser("Sophia", 29);
}

In real systems, this would execute an SQL INSERT query.


Reading Data from a Database

Applications often fetch records to display dashboards or reports.

Future> fetchUsers() async {
  await Future.delayed(Duration(seconds: 1));
  return ["Alice", "Bob", "Charlie"];
}

void main() async {
  var users = await fetchUsers();
  print("Users: $users");
}

This simulates a SELECT query returning rows.


Updating Records

Updating existing records is required when user data changes.

Future updateUserAge(String name, int newAge) async {
  await Future.delayed(Duration(seconds: 1));
  print("Updated $name age to $newAge");
}

void main() async {
  await updateUserAge("Alice", 32);
}

This represents an SQL UPDATE operation.


Deleting Records

Deleting unused or outdated records keeps databases clean.

Future deleteUser(String name) async {
  await Future.delayed(Duration(seconds: 1));
  print("Deleted user $name");
}

void main() async {
  await deleteUser("Charlie");
}

Handling Database Errors

Database operations can fail due to network issues or invalid queries. Proper error handling is critical.

Future safeInsert() async {
  try {
    await Future.delayed(Duration(seconds: 1));
    throw Exception("Database write error");
  } catch (e) {
    print("Error occurred: $e");
  }
}

void main() async {
  await safeInsert();
}

This prevents application crashes and improves reliability.


Batch Operations

Batch operations improve performance by grouping database actions.

Future batchInsert(List users) async {
  await Future.delayed(Duration(seconds: 2));
  print("Inserted ${users.length} users");
}

void main() async {
  await batchInsert(["Tom", "Jerry", "Mia"]);
}

Best Practices for Database Integration

  • Use async/await for non-blocking operations
  • Validate data before inserting
  • Handle errors gracefully
  • Close database connections properly
  • Use batch operations for performance

📝 Practice Exercises

Exercise 1

Create a function that inserts a list of product prices into a database.

Exercise 2

Simulate fetching transaction history and calculate the total amount.

Exercise 3

Implement error handling for a failed database update.


What’s Next?

In the next lesson, you will explore file operations in Dart, learning how applications read from and write to files efficiently.