Flutter - MySQL DB 연동하기(데이터 조회, 추가, 수정, 삭제하기)

반응형

 

이 포스팅은 MySQL과 연동을 하여 쿼리 실행이 되는지 안되는지에 중점을 두었습니다.

그렇기 때문에 기능 확인을 위하여 쿼리 실행 결과는 콘솔로 출력합니다.

 

설명하는 포스팅에서의 환경

  • OS : windows 10
  • DBMS : MySQL
  • IDE : Visual Stduio Code
  • Language : Dart (Flutter)

DB 연동을 위한 기본 설정

Dependency Injection (의존성 주입)

  • pubspec.yaml : 프로젝트 내의 해당 파일 열기
    • dependencies 밑에 아래의 코드를 추가
dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.2.8
  mysql_client: ^0.0.27

 

 

  • 아웃풋에서 정상적으로 의존성이 주입되었는지 확인


Import MySQL (호출)

  • DB를 연동할 코드 파일의 최상위 줄에 아래의 코드 추가
import 'package:mysql_client/mysql_client.dart';

<임포트 예시>


MySQL Connection (DB 연결)

DB를 연결할 함수 생성

Future<void> dbConnector() async {
  print("Connecting to mysql server...");

  // MySQL 접속 설정
  final conn = await MySQLConnection.createConnection(
    host: host,
    port: port,
    userName: userName,
    password: password,
    databaseName: 'testdb', // optional
  );

  // 연결 대기
  await conn.connect();

  print("Connected");

  // 종료 대기
  await conn.close();
}

 

  • 접속 설정 예시
    • 포스팅에서는 AWS RDS를 이용하여 접속하였음


main.dart

import 'package:flutter/material.dart';
import 'package:mysql_client/mysql_client.dart';

void main() {
  dbConnector();
  runApp(const MyApp());
}

Future<void> dbConnector() async {
  print("Connecting to mysql server...");

  // MySQL 접속 설정
  final conn = await MySQLConnection.createConnection(
    host: 'your host name',
    port: 'your port number',
    userName: 'your user name',
    password: 'your password',
    databaseName: 'your database name', // optional
  );

  await conn.connect();

  print("Connected");

  await conn.close();
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        ),
        body: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'name',
              ),
            ],
          ),
        ),
      ),
    );
  }
}

접속 확인

  • 앱 실행
    • 빈 깡통 프로젝트

 

  • 콘솔 확인
    • 정상적으로 MySQL 연결 성공


반응형

Execute Query (DB 쿼리 실행)

CRUD 쿼리 명령어 (select, insert, update, delete)

  • SqlConnection 객체를 이용하여 execute 실행
  • execute 메서드에는 쿼리를 작성
  • 동적으로 SQL을 작성해야 하는 경우, 두번째 파라미터에 변수와 값을 키:값 형태로 입력
  • 주의 : delete 명령어는 실행하기 전에 꼭 조건을 확인하고 실행하는 것이 좋음
// base syntax
await conn.execute( "insert query" );


// select
var result = await conn.execute(
	"SELECT * FROM tableName");


// insert
res = await conn.execute(
	"INSERT INTO tableName (columns1, columns2) VALUES (:col1Content, :col1Content)",
	{
		"col1Content": "내용1",
		"col1Content": "내용2",
	},
);


// update
res = await conn.execute(
	"UPDATE tableName SET columns1 = :col1Content",
	{ "col1Content": "내용1" },
);


// delete : id가 2인 것을 찾아 삭제
await conn.execute("delete from tableName where id = :id", {"id": 2});


// 변수로 값을 받을 경우 (동적 SQL)
// 예시 id 컬럼에 var1이라는 변수의 값 입력
int var1 = 1
var result = await conn.execute( "select * from test where id = :idNumber", {"idNumber" : var1} );

쿼리 결과 확인

  • colAt(n) : n 행의 인덱스 번호 확인
  • colByName(컬럼명) : 특정 컬럼명의 내용 확인
  • assoc() : 모든 결과 출력
var result = await conn.execute(
  "SELECT * FROM memberTable");

for (final row in result.rows) {
	// 행의 인덱스 정보 출력
    print(row.colAt(0));
    
    // 컬럼의 내용 출력 : title 컬럼 조회
    print(row.colByName("title"));

    // 쿼리 실행 결과의 모든 내용 출력
    print(row.assoc());
}

 

  • 예시) memberTable 조회 - id가 1인 항목만 조회

<MySQL 조회 결과>

int id = 1;

var result = await conn.execute(
	"SELECT * FROM memberTable where id = :idNumber", {"idNumber": id});

for (final row in result.rows) {
    print(row.colAt(0)); // 1
    print(row.colByName("name")); // eunbyeol
    print(row.assoc()); // {id: 1, name: eunbyeol}
}

 

 

 

 

var isDelete =
      await conn.execute("delete from memberTable where id = :id", {"id": 2});
  if (isDelete.isEmpty) {
    print("Delete Success");
  } else {
    print("Delete Failed");
  }


사용자의 입력에 따라 쿼리 실행하기

소스 코드

  • 이해를 위한 예시일 뿐, 코드를 참고하여 각자 환경에 맞게 수정해주세요.
// 함수의 파라미터를 받아 특정 쿼리를 실행하는 예시
// queryState : 사용자가 입력한 문자열을 확인하여 조건에 맞는 쿼리 실행
Future<void> dbConnector(String queryState) async {
  print("Connecting to mysql server...");

  // MySQL 접속 설정
  final conn = await MySQLConnection.createConnection(
    host: 'your host name',
    port: 'your port number',
    userName: 'your user name',
    password: 'your password',
    databaseName: 'your database name', // optional
  );

  await conn.connect();

  print("Connected");

  // 쿼리 실행 결과를 저장할 변수
  IResultSet? result;
  
  // 인덱스 조회를 위한 임시 변수
  int id = 1;

  // 입력된 파라미터(queryState)로 조건 확인
  // 모든 결과 출력
  if (queryState == 'selectAll') {
    result = await conn.execute("SELECT * FROM memberTable");
  }
  // 특정 결과 출력
  else if (queryState == 'select') {
    result = await conn.execute(
        "SELECT * FROM memberTable where id = :idNumber", {"idNumber": id});
  }
  
  // 쿼리 실행 성공
  if (result != null && result.isNotEmpty) {
    for (final row in result.rows) {
      print(row.assoc());
    }
  }
  // 쿼리 실행 실패
  else {
  	print('failed');
  }

  await conn.close();
}


확인

  • MySQL
SELECT * FROM memberTable

 

  • flutter
    • 테스트 진행을 위해 main 에서 실행
    • select : 특정 행 조회
    • selectAll : 모든 행 조회
      • 위의 문자열 조건은 임의로 정의했을 뿐, 기본 제공되는 기능이 아닙니다. (위의 소스 코드 if 부분 확인)
void main() {
  // 특정 행 조회 (id=1)
  dbConnector('select');
  runApp(const MyApp());
}

 

void main() {
  // 모든 행 조회
  dbConnector('selectAll');
  runApp(const MyApp());
}


전체 소스 코드

  • main.dart
import 'package:flutter/material.dart';
import 'package:mysql_client/mysql_client.dart';

void main() {
  dbConnector('selectAll');
  runApp(const MyApp());
}

Future<void> dbConnector(String queryState) async {
  print("Connecting to mysql server...");

  // MySQL 접속 설정
  final conn = await MySQLConnection.createConnection(
    host: 'your host name',
    port: 'your port number',
    userName: 'your user name',
    password: 'your password',
    databaseName: 'your database name', // optional
  );

  await conn.connect();

  print("Connected");

  IResultSet? result;
  int id = 1;

  if (queryState == 'selectAll') {
    result = await conn.execute("SELECT * FROM memberTable");
  } else if (queryState == 'select') {
    result = await conn.execute(
        "SELECT * FROM memberTable where id = :idNumber", {"idNumber": id});
  }

  if (result != null && result.isNotEmpty) {
    for (final row in result.rows) {
      print(row.assoc());
    }
  }
  
  await conn.close();
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        ),
        body: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'name',
              ),
            ],
          ),
        ),
      ),
    );
  }
}

참고

반응형