[C#] C#에서 MySQL 연동 사용하기

MySQL Connector/Net 사용

C#에서 MySQL을 엑세스하기 위해서는 일반적으로 MySQL을 위한 ADO.NET 드라이버인 MySQL Connector/Net을 사용하는데, 이 MySQL Connector/Net은 MySQL 웹사이트에서 무료 다운 받아 설치할 수 있다. 드라이버를 설치한 후에 C# 프로젝트에서 MySql.Data.dll를 참조한 후 MySql.Data.MySqlClient 네임스페이스를 참조하면, MySQL버젼의 ADO.NET 클래스들 (예: MySqlConnection, MySqlCommand, MySqlDataReader 등)을 이용할 수 있다.

 

[dropshadowbox align=”none” effect=”lifted-both” width=”100%” height=”” background_color=”#ffffff” border_width=”1″ border_color=”#dddddd” ]

using MySql.Data.MySqlClient;

MySqlConnection conn = new MySqlConnection(strConn);

[/dropshadowbox]

MySQL 데이타베이스 연결

MySQL 데이타베이스를 연결하기 위해서는 MySqlConnection 클래스를 사용한다. 이 클래스를 생성할 때, Connection String을 넣어 주어야 하는데, 여기에는 Server명, DB명, 사용자명, 암호등을 지정해 준다. 아래 예는 로컬 MySQL 서버에 root 사용자명과 암호명 123을 사용하여 test 데이타베이스에 접속하는 예이다.

[dropshadowbox align=”none” effect=”lifted-both” width=”100%” height=”” background_color=”#ffffff” border_width=”1″ border_color=”#dddddd” ]

string strConn= “Server=localhost;Database=test;Uid=root;Pwd=123;”;
MySqlConnection conn = new MySqlConnection(strConn);

conn.Close();

[/dropshadowbox]

MySQL 데이타 INSERT, UPDATE, DELETE 

데이타의 삽입, 삭제, 갱신등은 MySqlCommand에 해당 SQL문을 지정하여 실행한다. 일반적인 절차는 MySqlConnection을 사용해 서버 연결을 한 후, MySqlCommand에 INSERT, UPDATE, DELETE 등의 SQL문을 지정한 후 실행한다. 아래 예제는 한 ROW를 INSERT한후 이를 UPDATE하는 예이다.

[csharp]

private static void InsertUpdate()
{
string strConn = "Server=localhost;Database=test;Uid=root;Pwd=zzz;";

using (MySqlConnection conn = new MySqlConnection(strConn))
{
conn.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO Tab1 VALUES (2, ‘Tom’)", conn);
cmd.ExecuteNonQuery();

cmd.CommandText = "UPDATE Tab1 SET Name=’Tim’ WHERE Id=2";
cmd.ExecuteNonQuery();
}
}

 

[/csharp]

MySQL 데이타 읽기 

MySQL의 데이타를 가져오기 위해서는 MySqlCommand/MySqlDataReader 혹은 MySqlDataAdapter를 사용한다. MySqlDataReader는 연결모드로 데이타를 서버에서 가져오는 반면, MySqlDataAdapter는 한꺼번에 클라이언트 메모리로 데이타를 가져온후 연결을 끊는다. MySqlDataAdapter에서 가져온 데이타는 주로 DataSet 객체 안에 메모리상의 테이블 형태로 존재하는데, 이를 각종 컨트롤들에게 바인딩시킬 수 있다.

[csharp]
private static void SelectUsingReader()
{
string connStr = "Server=localhost;Database=test;Uid=root;Pwd=zzz;";

using (MySqlConnection conn = new MySqlConnection(connStr))
{
conn.Open();
string sql = "SELECT * FROM Tab1 WHERE Id>=2";

//ExecuteReader를 이용하여
//연결 모드로 데이타 가져오기
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine("{0}: {1}", rdr["Id"], rdr["Name"]);
}
rdr.Close();
}
}

private static void SelectUsingAdapter()
{
DataSet ds = new DataSet();
string connStr = "Server=localhost;Database=test;Uid=root;Pwd=zzz;";

using (MySqlConnection conn = new MySqlConnection(connStr))
{
//MySqlDataAdapter 클래스를 이용하여
//비연결 모드로 데이타 가져오기
string sql = "SELECT * FROM Tab1 WHERE Id>=2";
MySqlDataAdapter adpt = new MySqlDataAdapter(sql, conn);
adpt.Fill(ds, "Tab1");
}

foreach (DataRow r in ds.Tables[0].Rows)
{
Console.WriteLine(r["Name"]);
}
}

[/csharp]

한글 깨짐 현상이 있을 경우..
C# 과 mysql 연동시 한글깨짐 현상

DATABASE=AnyKeeperDBMS;SERVER=61.96.223.78;Connect Timeout=30;USER id=cnt;pwd=cnt;CHARSET=utf8
마지막에 CHARSET=utf8 추가 (DataBase 언어set이 utf8로 정의 되어있을 경우)

두선 사이의 교차점 구하기

두 선의 교차점 구하기
이 글은 두 선분의 교차점을 구하는 알고리즘이 작업에 필요해서 작성해둔 글이다. 참고로, 예전에 두선분의 교차점을 구하는 것 자체가 쉬울 것으로 생각하고 흔히 생각하는 기울기, y 절편을 이용하여 접근하려고 하였다. 이는 상당히 비효율적 방법이였고 조금 더 효율적인 방법으로 접근하였다.

먼저 직선의 방정식으로써, 기울기와 절편으로 나타내지 말고, t 매개변수를 이용해 나타내면 다음과 같다.


P1과 P2는 직선의 시작점과 끝점을 나타내며, t의 범위는 0에서 1까지이다. (P1, P2에서 1, 2는 아래첨자로 생각하기 바란다)

선의 식을 알았으니, 이제 두선의 교점을 구해보는 것으로 응용해보자. 먼저 아래 그림을 보자.


Line1은 P1과 P2로 이루어져 있으며, Line2는 P3와 P4로 이루어져 있다. 두개의 라인을 식으로 표현해보면 다음과 같다.


이미 알겠지만, t와 s는 0에서 1부터의 값이며, 두선의 교점은 두선의 공통된 값이므로 P(t)와 P(s)는 같으므로 위의 2개의 식은 아래의 1개의 식으로 나타낼 수 있다.


다시 위의 식을 x, y로 분리해보면 아래와 같은 두개의 식들로 분리된다.


위의 식을 t와 s에 대해서 정리를 해보면 다음과 같다.


즉, 위의 t와 s는 두선이 서로 만날때의 값이므로, 최종적으로 두선의 교점은 다음과 같이 나타낼 수 있다.


위의 x, y가 우리가 구하고자하는 두 직선의 교점이다.

마지막으로 t와 s에 대해 정리해 보도록 하자.

s와 t의 값이 0과 1 사이를 벗어나는 경우, 두 선은 교차하지 않는다고 판정해야 한다. 그리고 s와 t를 구하는 공식에서 분모가 0인 경우 두 선은 평행하다는 의미이므로 교점은 존재하지 않다. 분모와 분자 모두 0인 경우 두 선은 동일한 선이다.

아래의 코드는 위의 설명을 토대로 작성하였다.

bool GetIntersectPoint(const POINT& AP1, const POINT& AP2, 
                       const POINT& BP1, const POINT& BP2, POINT* IP) 
{
    double t;
    double s; 
    double under = (BP2.y-BP1.y)*(AP2.x-AP1.x)-(BP2.x-BP1.x)*(AP2.y-AP1.y);
    if(under==0) return false;

    double _t = (BP2.x-BP1.x)*(AP1.y-BP1.y) - (BP2.y-BP1.y)*(AP1.x-BP1.x);
    double _s = (AP2.x-AP1.x)*(AP1.y-BP1.y) - (AP2.y-AP1.y)*(AP1.x-BP1.x); 

    t = _t/under;
    s = _s/under; 

    if(t<0.0 || t>1.0 || s<0.0 || s>1.0) return false;
    if(_t==0 && _s==0) return false; 

    IP->x = AP1.x + t * (double)(AP2.x-AP1.x);
    IP->y = AP1.y + t * (double)(AP2.y-AP1.y);

    return true;
}

CFileDialog 파일을 읽거나 저장할때 파일창 띄우기


파일에 변수의 내용을 직렬화 해서 저장,읽어들이는  예제

CFileDialog dlg(
  TRUE(읽기)/FALSE(저장),
  기본확장자,
  기본파일명,
  열기모드->MSDN 참고,
  파일창 아래쪽에 나오는 필터링
)


파일을 열어 변수에 읽어들일때
 char szFilter[] = “PCMON (*.CFG) | All Files(*.*)|*.*||”;
 CFileDialog dlg(TRUE, “cfg”, “pcmon”, OFN_HIDEREADONLY, szFilter);
 if(IDOK == dlg.DoModal())
 {
  CString strPathName = dlg.GetPathName();
  CFile fp;
  CFileException e;
  if(!fp.Open(strPathName, CFile::modeRead, &e)) {
   e.ReportError();
   return;
  }

 CString str;
 CArchive ar(&fp, CArchive::load);
 ar >> str;
}

파일을 선택해서 저장할때
char szFilter[] = “PCMON (*.CFG) | All Files(*.*)|*.*||”;
 CFileDialog dlg(FALSE, “cfg”, “pcmon”, OFN_HIDEREADONLY, szFilter);
 if(IDOK == dlg.DoModal())
 {
  CString strPathName = dlg.GetPathName();


  CFile fp;
  CFileException e;
  if(!fp.Open(strPathName,CFile::modeWrite|CFile::modeCreate, &e)) {
   e.ReportError();
   return;
  }


  CString str = _T(“문자열”);
  CArchive ar(&fp, CArchive::store);
  ar << str;
 }


출처: http://wyseburn.tistory.com/94

[C++]MAP 클래스 사용법

1. 맵(Map)이란?

 맵(Map)은 set, multiset, multimap등과 같이 STL이 제공하는 자료형 중 하나이다.


2. 맵(Map)의 특징

 첫번째, 두 개의 요소가 한 쌍을 이루어 하나의 자료를 이룬다.  첫 번째 요소는 first로써 인덱스이고, 두 번째 요소는 second로써 데이터이다. 그러므로, 인덱스와 데이터가 분리된 상태이며 독립적으로 자료형을 지정해줄 수 있다.

두번째, 반복자(iterator)와 배열 첨자를 사용하여 접근할 수 있다.
 
 세번째, 자동적으로 정렬된 상태를 유지한다. 만약에 정렬할 수 없다면 출력 순서는 먼저 입력된 것이 가장 나중에 출력된다.

 네번째, 인덱스가 중복되서 추가를 한다면, 기존의 데이터는 없어지고 새로운 데이터로 덮어씌여진다.

 다섯번째, Template를 사용하여, 인덱스나 데이터나 형식에 대하여 자유롭다.


3. 선언 방법

  map<인덱스형식,데이터형식> 사용할이름; 과 같이 선언하면 된다.
Example : map<int, string> iMapt;


4. 접근 방법

 접근 방법엔 두 가지가 있다.

 ㄱ. iterator를 사용한 접근 방법.
map<인덱스형식,데이터형식>::iterator iterator이름; 과 같이 iterator를 선언 한 후, 사용한다. 접근 방법은 iterator->first, iterator->second와 같은 형식으로 접근한다.

 ㄴ. 인덱스 요소를 이용하여 접근할 수 있다.


5. 요소 추가, 삭제 방법

 추가를 하고 싶다면 map[인덱스]=데이터; 식으로 추가를 해주자. 물론, 인덱스에는 문자열이 와도 된다.
 그리고 삭제를 하고 싶다면 map.erase(인덱스)와 같이 삭제은 방법으로 인덱스를 통하여 삭제를 할 수 있다.


6. Map사용 예제

#include <map>
#include <string>
#include <stdio.h>

using namespace std;

void main()
{
     map<int, string> iMap;

     iMap[5] = “5번요소의 데이터”; //요소에 대한 데이터를 임의 순서로 추가
     iMap[3] = “3번요소의 데이터”;
     iMap[9] = “9번요소의 데이터”;

     map<int, string>::iterator itMap;

     printf(“iMap\n”);
     for(itMap = iMap.begin(); itMap != iMap.end(); itMap++)
          printf(“%d : %s\n”,itMap->first, itMap->second.c_str()); //정렬된 상태
     printf(“\n”);

     iMap[9] = “안녕하세요!”; //덮어 씌우기

     printf(“iMap\n”);
     for(itMap = iMap.begin(); itMap != iMap.end(); itMap++)
          printf(“%d : %s\n”,itMap->first, itMap->second.c_str());
     printf(“\n”);

     printf(“iMap[5] = %s\n\n”,iMap[5].c_str()); //인덱스를 통한 접근

     map<char*, string> sMap; //char*과 string 둘다 문자열이지만
                                           //char*는 정렬되지 않는다.

     sMap[“미국”] = “United State of America”;
     sMap[“중국”] = “China”;
     sMap[“일본”] = “Japan”;
     sMap[“한국”] = “Korea, Republic”;

     map<char*, string>::iterator itStrMap;

     printf(“sMap\n”);
     for(itStrMap = sMap.begin(); itStrMap != sMap.end(); itStrMap++)
          printf(“%s : %s\n”,itStrMap->first, itStrMap->second.c_str());
     printf(“\n”); //마지막으로 넣은 한국이 가장 먼저 출력됨

     sMap.erase(“일본”); //일본을 삭제

     printf(“sMap\n”);
     for(itStrMap = sMap.begin(); itStrMap != sMap.end(); itStrMap++)
          printf(“%s : %s\n”,itStrMap->first, itStrMap->second.c_str());
     printf(“\n”);
}

[Result]
iMap
3 : 3번요소의 데이터
5 : 5번요소의 데이터
9 : 9번요소의 데이터


iMap
3 : 3번요소의 데이터
5 : 5번요소의 데이터
9 : 안녕하세요!


iMap[5] = 5번요소의 데이터


sMap
한국 : Korea, Republic
일본 : Japan
중국 : China
미국 : United State of America


sMap
한국 : Korea, Republic
중국 : China
미국 : United State of America


출처 : http://blog.newms.org/41

배열 초기화 방법

배열을 선한하고 배열의 값들을 초기화 해줘야 하는데 For 같은 반복문을 사용하지 않고 초기화 할수 있다.

double [] test = new double[24]; // 왼쪽과 같이 배열을 선언했을경우 각각의 배열에는 쓰레기값이 들어간다.
Array.Clear(test,0,24); // 왼쪽과 같이 사용하면 배열이 전부 초기화된다.