Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 4개 있습니다.)

C# - 닷넷 응용 프로그램에서 MySQL(MySqlConnector) 사용

예전에 PHP를 통해 MySQL을 사용하는 방법을 소개했었는데요.

.NET 개발자가 처음 해보는 PHP + MySQL 연동
; https://www.sysnet.pe.kr/2/0/1058

MySQL의 환경 설정은 중복 설명하지 않고 ^^ 위의 것을 그대로 따를 것입니다. (하지만, 이 글에서 테스트한 MySQL 버전은 5.5입니다. 별 차이는 없겠지만. ^^)

DB(Schema): mytestdb
테이블: mytable
        칼럼:  id int NOT NULL
               name varchar(50)
               age int
               description varchar(150) 

C#에서 MySQL을 사용하려면 ODBC나 전용 ADO.NET Data Provider를 사용해야 할텐데요. 다행히 MySQL 측에서 Connector/Net이라는 "ADO.NET driver for MySQL"을 제공해 주고 있으니 이를 사용하면 됩니다. (소스 코드도 공개되어 있습니다.)

다운로드는 다음의 경로에서 받고,

Download Connector/Net
; http://dev.mysql.com/downloads/connector/net/

오늘 날짜(2012-01-16) 기준으로 6.6.4 버전이 최신입니다. 제 경우에는 MSI 파일로 설치했습니다.

정상적으로 설치되고 나면, C:\Program Files (x86)\MySQL\MySQL Connector Net 6.6.4\Assemblies 경로에 v2.0, v4.0의 하위 폴더가 생기고 그 안에 각각 다음의 어셈블리들이 포함되어 있습니다. (물론, GAC에도 등록됩니다.)

  • MySql.Data.CF.dll
  • MySql.Data.dll
  • MySql.Data.Entity.dll
  • MySql.Web.dll

이 중에서 일반적인 ASP.NET에서 사용하는 용도로는 MySql.Data.dll만 있으면 됩니다. 그 파일만 복사해서 다른 컴퓨터의 Visual Studio에서 참조 추가한 후 다음과 같이 코딩을 해도 MySQL 사용이 가능합니다. (즉, 굳이 MSI 파일을 설치할 필요는 없습니다.)

nuget을 통해 설치할 수 있습니다.

// https://www.nuget.org/packages/MySqlConnector/

Install-Package MySqlConnector

using System;
using System.Data;
using MySql.Data.MySqlClient;

namespace ConsoleApplication1
{
    class Program
    {
        private void CreateMySqlTable(MySqlConnection connection)
        {
            string query = "CREATE TABLE IF NOT EXISTS mytable(";
            query += " id INT NOT NULL, ";
            query += " NAME VARCHAR(50) NOT NULL PRIMARY KEY, ";
            query += " age INT NOT NULL, ";
            query += " DESCRIPTION VARCHAR(150) NOT NULL)";

            MySqlCommand createCommand = new MySqlCommand();
            createCommand.Connection = connection;
            createCommand.CommandText = query;

            createCommand.ExecuteNonQuery();
        }

        static void Main(string[] args)
        {
            using (MySqlConnection myConnection =
                new MySqlConnection(@"Data Source=192.168.0.11;Database=mytestdb;User Id=mytest;Password=mytest@2008"))
            {
                myConnection.Open();

                CreateMySqlTable(myConnection);

                // Create
                MySqlCommand insertCommand = new MySqlCommand();
                insertCommand.Connection = myConnection;
                insertCommand.CommandText = "INSERT INTO mytable(id, NAME, age, DESCRIPTION) VALUES (@id, @NAME, @age, @DESCRIPTION)";

                insertCommand.Parameters.Add("@id", MySqlDbType.Int32, 50);
                insertCommand.Parameters.Add("@NAME", MySqlDbType.VarChar, 50);
                insertCommand.Parameters.Add("@age", MySqlDbType.Int32, 50);
                insertCommand.Parameters.Add("@DESCRIPTION", MySqlDbType.VarChar, 150);

                string nameValue = "Name" + Guid.NewGuid().ToString();
                insertCommand.Parameters[0].Value = 0;
                insertCommand.Parameters[1].Value = nameValue;
                insertCommand.Parameters[2].Value = 10;
                insertCommand.Parameters[3].Value = nameValue + "_Description";

                int affected = insertCommand.ExecuteNonQuery();
                Console.WriteLine("# of affected row: " + affected);

                // Update
                MySqlCommand updateCommand = new MySqlCommand();
                updateCommand.Connection = myConnection;
                updateCommand.CommandText = "UPDATE mytable SET DESCRIPTION=@DESCRIPTION WHERE NAME=@NAME";

                updateCommand.Parameters.Add("@NAME", MySqlDbType.VarChar, 50);
                updateCommand.Parameters.Add("@DESCRIPTION", MySqlDbType.VarChar, 150);

                updateCommand.Parameters[0].Value = nameValue;
                updateCommand.Parameters[1].Value = nameValue + "_Description2";

                affected = updateCommand.ExecuteNonQuery();
                Console.WriteLine("# of affected row: " + affected);

                // Select - ExecuteScalar
                MySqlCommand selectCommand = new MySqlCommand();
                selectCommand.Connection = myConnection;
                selectCommand.CommandText = "SELECT count(*) FROM mytable";

                object result = selectCommand.ExecuteScalar();
                Console.WriteLine("# of records: " + result);

                // Select - DataTable
                DataSet ds = new DataSet();
                MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM mytable", myConnection);
                da.Fill(ds, "mytable");

                DataTable dt = ds.Tables["mytable"];
                foreach (DataRow dr in dt.Rows)
                {
                    Console.WriteLine(string.Format("Name = {0}, Desc = {1}", dr["NAME"], dr["DESCRIPTION"]));
                }

                // Delete
                MySqlCommand deleteCommand = new MySqlCommand();
                deleteCommand.Connection = myConnection;
                deleteCommand.CommandText = "DELETE FROM mytable WHERE NAME=@NAME";

                deleteCommand.Parameters.Add("@NAME", MySqlDbType.VarChar, 50);
                deleteCommand.Parameters[0].Value = nameValue;

                affected = deleteCommand.ExecuteNonQuery();
                Console.WriteLine("# of affected row: " + affected);
            }
        }
    }
}

사용이 정말 쉬워졌군요. ^^ 영국의 어떤 개발자 한 분이 애플리케이션 서버는 C#/닷넷/윈도우가 담당하고 그 외 기반은 오픈 소스 기반으로 한다는데... 제법 현실성이 있습니다. C#/닷넷의 생산성과 인프라의 저비용화가 적절히 맞아떨어지는 것 같습니다.




참고로, mysql.exe 실행시 Access denied 오류가 발생하는 경우가 있었습니다.

C:\Program Files\MySQL\MySQL Server 5.5\bin>mysql
ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)

C:\Program Files\MySQL\MySQL Server 5.5\bin>mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

이럴 때는 그냥 -p 옵션을 부과해서 암호까지 입력하겠다고 명시해야 합니다.

C:\Program Files\MySQL\MySQL Server 5.5\bin>mysql -u root -p
Enter password: 

첨부된 파일은 MySql.Data.dll이 포함된 간단한 소스 코드 예제입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 10/6/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2013-01-16 01시28분
[ㅇ.ㅇ] 커넥터 라이센스 주의하세요. GPL 입니다.
구매하든 소스까든 하나는 강요될 것 같네요.
[guest]
2013-01-16 02시20분
덧글 감사합니다. ^^ 그러고 보니, MySQL 자체가 GPL 라이선스이고... 은근한 상용 라이선스 구매를 종용하는군요. ^^

"MySQL open source software is provided under the GPL License. OEMs, ISVs and VARs can purchase commercial licenses."
정성태
2013-01-16 03시14분
[Lyn] 걔들도 먹고 살아야죠 ㅎㅎ
[guest]
2013-01-16 03시47분
오라클 정도 되면... 먹고 사는 거에 걱정은 좀 덜하지 않을까요? ^^
정성태
2013-01-17 03시17분
[wafe] GPL이긴 하지만 어차피 MySQL을 사용하고 있는지를 확인할 수 있는 방법이 없지 않을까요... ^^;;;
[guest]
2013-01-19 01시29분
wafe 님, 현실적으로 단속반이 뜨는 경우는 많지 않고, 게다가 MySQL뿐만 아니라 Oracle DB도 확인할 수 있는 방법이 없지만... 음... 그래도 불법 복제해서 기업에서 안 쓰는 거 보면 이유가 있겠지요. ^^ 개인이나 startup에게는 별다른 문제가 아니겠지만 웬만한 규모의 기업에서는 라이선스를 속이며 사용하기에는 부담일 것입니다. 사실, 대부분의 소프트웨어가 기업으로부터만 대금을 잘 회수해도 성공하는 데 별 문제는 없을 것 같고. ^^
정성태
2013-05-16 05시30분
mysql-connector-net-6.6.5.msi를 다운로드한 후, 설치하지 않고도 파일을 추출할 수 있습니다. 다음의 명령을 내리면 d:\temp\mysql 폴더에 MSI 파일 내부에 있던 모든 파일들이 해제됩니다.

msiexec /a mysql-connector-net-6.6.5.msi targetdir="d:\temp\mysql" /qn
정성태

... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...
NoWriterDateCnt.TitleFile(s)
1741정성태8/26/201422597.NET Framework: 459. GetModuleHandleEx로 알아보는 .NET 메서드의 DLL 모듈 관계파일 다운로드1
1740정성태8/25/201433998.NET Framework: 458. 닷넷 GC가 순환 참조를 해제할 수 있을까요? [2]파일 다운로드1
1739정성태8/24/201427846.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201423497.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201420955VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201426956VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201419549.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201421299오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201427544.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201435898Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201428357개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201423521개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
1729정성태8/11/201419529오류 유형: 236. SqlConnection - The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
1728정성태8/8/201431755.NET Framework: 453. C# - 오피스 파워포인트(Powerpoint) 파일을 WinForm에서 보는 방법파일 다운로드1
1727정성태8/6/201421966오류 유형: 235. SignalR 오류 메시지 - Counter 'Messages Bus Messages Published Total' does not exist in the specified Category. [2]
1726정성태8/6/201420751오류 유형: 234. IIS Express에서 COM+ 사용 시 SecurityException - "Requested registry access is not allowed" 발생
1725정성태8/6/201422711오류 유형: 233. Visual Studio 2013 Update3 적용 후 Microsoft.VisualStudio.Web.PageInspector.Runtime 모듈에 대한 FileNotFoundException 예외 발생
1724정성태8/5/201427496.NET Framework: 452. .NET System.Threading.Thread 개체에서 Native Thread Id를 구하는 방법 - 두 번째 이야기 [1]파일 다운로드1
1723정성태7/29/201459951개발 환경 구성: 233. DirectX 9 예제 프로젝트 빌드하는 방법 [3]파일 다운로드1
1722정성태7/25/201422299오류 유형: 232. IIS 500 Internal Server Error - NTFS 암호화된 폴더에 웹 애플리케이션이 위치한 경우
1721정성태7/24/201425631.NET Framework: 451. 함수형 프로그래밍 개념 - 리스트 해석(List Comprehension)과 순수 함수 [2]
1720정성태7/23/201423520개발 환경 구성: 232. C:\WINDOWS\system32\LogFiles\HTTPERR 폴더에 로그 파일을 남기지 않는 설정
1719정성태7/22/201427462Math: 13. 동전을 여러 더미로 나누는 경우의 수 세기(Partition Number) - 두 번째 이야기파일 다운로드1
1718정성태7/19/201436925Math: 12. HTML에서 수학 관련 기호/수식을 표현하기 위한 방법 - MathJax.js [4]
1716정성태7/17/201436577개발 환경 구성: 231. PC 용 무료 안드로이드 에뮬레이터 - genymotion
1715정성태7/13/201431629기타: 47. 운영체제 종료 후에도 USB 외장 하드의 전원이 꺼지지 않는 경우 [3]
... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...