저도 윗님처럼 DB를 연동 하려고 하니 소비자에서 연결 테스트가 되지 않았는데요.. 특이하게 전 원격지 DB라서 그런것 같아요. http://pantarei.tistory.com/699 검색해보니 안될 경우에는 IP뒤에 포트를 넣어주면 되내요. 유익한 글 잘 보고 갑니다. ^^;
이 작업을 하게 해줄 시기는 리스트가 생성될 당시(Initialize Dialog)이므로,
Dlg.cpp 내부에 있는
해당 함수 내부에 다음과 비슷한 코드를 작성해준다.
실행해보면 리스트에 컬럼구분이 생겼다.
우리 목표는 이 다이얼로그 창에 있는 버튼을 누르면 DB자료를 가져와서 보여주도록 하는 것이다.
3. 아까 만들었던 DB 클래스의 헤더 파일에 가 보면
클래스가 두개 있다. 보기 편하게 하기 위해 임의로 닫아두었다.
CSNACK과 CSNACKAccessor 가 있다. (클래스 이름은 만든 사람에 따라 다름.)
그냥 CSNACK 클래스는 DB 자체에 접근하게 해주는 일을 하며, (자세힌 모른다.)
CSNACKAccessor 는 DB에 접근할 방식 / 얻어올 데이터. DB에 던질 쿼리문등을 설정한다. (역시 자세힌 모른다.)
4.
바로 사용해도 되긴 하겠지만, 이 헤더를 여러 기능으로 재사용할 수 있게 템플릿으로 만들어줬다.
가급적이면 템플릿화 하는것이 좋다.
5.
class CSNACKAccessor 를 복사해서 하나 붙여넣기하고 이름을 마음대로 바꾸자.
나는 스낵 테이블의 모든 정보를 다 얻어오는 기능이므로
CSNACKGetInfoAccessor 로 하였다.
물론 복붙한 클래스 내부에서 CSNACKAccessor로 변수가 들어가고 있는 부분은, 모두 이름을 내가 설정한 이름으로 바꿔주어야 한다.
6. 복붙했던 클래스를 열어 내용을 살피면 다음과 같은 부분이 있다.
DEFINE_COMMAND_EX () 괄호 안 내부의 형식은 DB에서 보던 SQL 문장이다.
여기에 내 쿼리를 입력한다. 내가 버튼을 눌렀을 때 원하는 기능은 테이블의 모든 내용을 보여주는 것이므로
로 입력하였다.
BEGIN_COLUMN_MAP ~END_COLUMN_MAP 사이의 내용은, 해당 클래스인 CSNACKGetInfoAccessor의
멤버 변수인 m_ID, m_Name, m_TASTE 에 DB테이블에 있는 값을 넣겠다는 것이다.
수정할 필요가 없으므로 다음으로 넘어간다. ^^
7.
이제 다이얼로그 버튼을 누르면 디비가 출력되게 해야 하므로,
리소스 뷰의 다이얼로그에서 버튼을 더블클릭.
8. 버튼을 더블클릭하면 자동으로 Dlg.cpp로 가면서, 더블클릭 이벤트 발생시 할 행동에 대한 코드를 채우라고 한다.
9. 다음과 같이 코딩. 내가 만든 디비 헤더를 인클루드하는것을 잊지 말자.
여기서 OpenAll() 함수는 데이터베이스에 연결하는 기능을 하는 함수이다.
(좀더 자세히 설명하면, OpenAll 함수는 내부적으로 OpenDataSource 함수를 호출한다. OpenDataSource는 데이터베이스에 접근하는 함수이다. 또한 OpenRowSet 함수도 호출한다. 이 OpenRowSet 함수는 GetDefaultCommand를 호출하는데, GetDefaultCommand 함수는 실행시킬 SQL 문장을 바인딩해주는 함수라고 한다. 마지막으로 Execute() 함수도 호출하는데 SQL 문장을 실행한다. Execute 함수에서 에러가 났다면, 내가 쓴 SQL 쿼리의 문법이 잘못된 것이다. )
또한 MoveNext() 함수는 DB 데이터로 진입하여 데이터를 하나씩 읽는다.
10. 컴파일시켜보면 이런 에러 메세지가 뜬다.
에러가 난 곳으로 가보면 아래와 같은 #error 구문과 주석이 있는데, 드래그한 부분을 지워준다.
11. 다시 컴파일해본다. 제대로 된다. 다이얼로그 창의 버튼을 누르면 DB가 뜨는 것을 볼 수 있다.
사족 1. 여기까지 컴파일에러없이 잘 되었는데, DB불러오기 버튼을 눌러보니 값을 못 읽을 경우.
여기까지 했는데 에러가 생겼을 수도 있다. 이건 컴에 따라 생기기도 하고 안 생기기도 한다.
(내 컴퓨터는 에러가 나는 쪽이다.)
만약 DB가 불려오지 않는다면 다음과 같은 조치를 하도록 하자.
-먼저 가장 바깥쪽 메인인 cpp파일로 간다.
나의 경우에는 프로젝트이름이 usingDB 였으므로, usingDB.cpp 파일이다.
-InitInstance 함수에서, 아래에 나타나온 스샷대로 코드를 입력해준다.
빨강색 네모로 표시해둔 CoInitialize(NULL); 과 CoUninitialize(); 를 입력해주도록 하자.
사족 2.
DB 쿼리문을 작성할때 어떤 조건을 설정하고 싶을 때가 있다.
위의 쿼리문은, MEMID 가 ?라는 값을 가지고 있는 전체 row를 DB에서 지우겠다는 뜻이다.
컴퓨터는 이 조건 '?' 를 어디서 찾을까?
해당 클래스에서, BEGIN_PARAM_MAP 과 END_PARAM_MAP 사이에서 순서대로 찾는다.
즉 물음표 (조건변수) 여러개를 설정해놓으면, 파라미터 맵에서 대응될 변수를 입력해놓으면 된다.
COLUMN_ENTRY(1, m_MEMID) 는 첫번째(1) 물음표 값에, m_MEMID의 값을 대입하겠다는 뜻이다.
사족 3.
무지무지 강력하고 좋은 RowsAffected 변수를 템플릿화해놓은 클래스에 추가해서 쓰면 좋다.
어디다 어떻게 추가하냐면..
RowsAffected를 어떻게 활용하면 되나?
OpenAll() 등으로 쿼리문을 실행한 뒤 RowsAffected에는 쿼리문에 의해 변화가 일어나는 대상 행이 몇 개였는지가 저장된다.
MFC에서 mssql로 접속을 하기 위해서는 자신의 pc에 mssql DSN을 설정 해주어야한다.
시작->제어판->관리도구->데이터원본(ODBC)를 클릭하면 아래와 같은 화면이 나온다.
mssql에 접속하기 위한 DSN을 설정 해주므로 시스템DSN탭에서 추가를 누른다.
(만약 mdb파일을 사용하려면 사용자 DSN에 추가)
mssql 서버와 연동을 할것이므로 Sql Server를 선택한다.
이름은 임의로 DBTest로 정했고 아래 설명은 자신이 알아볼 수 있게 아무거나 입력한다.
서버는 Mssql에 깔려 있는 IP를 쓴다. 나는 내 피시에 깔았기 때문에 내 ip를 그대로 썼다.
당연히 알겠지만 자신의 ip를 그대로 써도 되고 127.0.0.1을 써도 된다.
사용자가 입력한 로그인 ID와 암호 블라블라~~를 선택한 후 로그인 ID 암호를 입력후 클라이언트 구성을 클릭
내가 이것때문에 엄청 고생했다. 알고 보면 별것 아니지만 안될때는 아무리 찾아봐도 정확한 문제가 뭔지 안나오더라..아무튼 네트워크 라이브러리에서 TCP/IP를 선택해 주고 Default로 동적으로 포트 번호를 받게 설정이 되어있다. 하지만 동적으로 받으면 무슨 이유인지 안된다고 하더라..나도 대충 봐서...-_-;;;;
그래서 동적 포트 확인 체크란을 해제하고 포트번호를 써준다. (이거 동적으로 할당하면 밑에 그림에서 다음 버튼 누를 때 에러 발생한다.) 확인 누르면 바로 위에 화면이 뜰것이다 그러면 그냥 다음 누르고
다음을 누른다.
그리고 마침
그럼 네모와 같은 것이 하나 추가 되었으면 설정은 끝났다. 확인!
MFC는 접한지 얼마 되지 않아 엄청나게 허접스럽게 만들어 놓았다. -_-;; (난 Qt전문가)
그냥 버튼만 누르면 메세지 박스에서 칼럼의 값이 하나씩 찍힌다.
아래는 다이얼로그의 버튼을 눌렀을 때 실행하는 함수이다.
//----------------------------------------------
void CDBTestDlg::OnDBTest() { // TODO: Add your control notification handler code here
CDatabase db; //db.OpenEx(_T("DSN=UserList")); db.OpenEx(_T("DSN=DBTest;UID=sa;PWD=rootroot")); //자신이 설정해주었던 DSN이름을 쓰고 id,pass를 입력 CRecordset record(&db);
record.Open(CRecordset::snapshot,"SELECT * FROM UserList");//UserList라는테이블이 이미 만들어져 있다. short col = record.GetODBCFieldCount(); char *data = NULL;
for( short i=0; i < col; i++ )
{
CString tmp;
//이 함수는 char\*형을 지원하지 않는다
record.GetFieldValue(i, tmp);
data = (char\*)malloc(tmp.GetLength()+1);
strcpy(data, tmp);
this->MessageBox(data);
//cout<<data<<"\\t";
free(data);
}
record.MoveNext(); //다음행으로 이동
} } }
실행하면 DB에 있는 table의 필드를 차례 차례 검색해서 메세지박스에 보여진다.
//Mysql도 거의 비슷하다. 관리도구->데이터원본->시스템DSN에서 추가를 눌러 mysql을 선택하면 된다.
(물론 Mysql Server가 설치가 되어잇거나 클라이언트가 설치가 되어있어야 시스템 DSN에 보인다.사실 깔아놓고 확인한거라 정확한지는 모르겠다.--;; 안보이시면 까시라~)
//mysql을 외부 ip와 연동하기 위해서는 도스창에서 mysql 열던지 mysql client로 mysql로 들어가서 아래와 같이 설정을 해주어야지
접속이 가능하다.
도스창에서 접속방법:
시작->실행->cmd입력
c:\) mysql -u 아이디 -p
엔터를 치면 비번 입력하라는 메세지. 비번 입력
mysql> grant all privileges on db명.* to 사용자계정@'IP주소' identified by '비밀번호' with grant option; mysql> grant reload,process on *.* to admin@localhost; mysql> FLUSH PRIVILEGES;
==========
점점 더 귀차니즘에 의해 ODBC_Oracle 연동도 여기서 적는다. 이것 또한 비슷하지만 약간 더 복잡하다.
//------------------------------------------------------------ // Name : ConnectionDB.java // Desc : Mysql DB와 연결을 담당 하는 클래스 //------------------------------------------------------------
예제 실습을 하기 전에, 여기서 잠시 닷넷과 자바의 차이점을 이해해야 할 부분이 있는데, 바로 모듈을 찾는 규칙입니다. 닷넷의 경우에는 EXE 와 동일한 폴더(또는, 웹 App의 경우 /bin)이거나 GAC(Global Assembly Cache) 가 대표적인데, 자바는 여러 환경을 지원하다 보니 제각각입니다. 자세한 내용은 "Microsoft SQL Server JDBC Driver 3.0" 설치 후 "\sqljdbc_3.0\enu\help\default.htm" 문서의 "Overview of the JDBC Driver" / "Using the JDBC Driver" 에 언급되어 있으니 생략하고, 여기서는 지난 번에 실습해 보았던 Servlet 내용에서 했던 데로 다음과 같이 구성했습니다.
sqljdbc4.jar 를 '[톰캣 설치폴더]\lib' 폴더에 복사 (실행을 위해!)
Eclipse IDE 에서 Java Build Path / Libraries / Add External JARs 를 통해 sqljdbc4.jar를 지정 (컴파일을 위해!) (만약, sqljdbc4.jar 내부의 클래스를 직접 사용하는 경우가 아니라면 참조 생략 가능)
예제 코드는, 지난 번 서블릿 코드를 재사용해서 다음과 같이 DB 관련 코드만 넣어보았습니다. (아래의 예제 코드는 "\sqljdbc_3.0\enu\help\default.htm" 문서의 "Sample JDBC Driver Applications" / "Connecting and Retrieving Data" / "Connection URL Sample" 을 가져온 것입니다.)
DB 접근에 대한 추상화는 자바가 더 나은 것 같습니다. 왜냐하면 닷넷의 경우에는 물론 인터페이스가 있다고는 하지만 대부분의 경우에 DB 제공자마다 다르게 사용하기 때문입니다. (예를 들어, SQL Server - SqlConnection, Oracle - OracleConnection, Postgre - NpgsqlConnection, ...)
RDB라는 것이 SQL 쿼리로 인해 정형화되어 있는 접근 방식을 제공하므로, 닷넷에서 DB를 다루던 경험이 있다면 자바의 DB 접근 방법을 배우는 것이 그다지 어려운 문제는 아니더군요. ^^
참고로, 딱 한가지... 닷넷 개발자 입장에서 주의해야 할 점이 있다면 ResultSet의 get... 메서드에 전달되는 인덱스가 0 이 아닌 1 부터 시작한다는 예외(?) 사항이 존재합니다. 만약 rs.getInt(0) 처럼 접근한다면 다음과 같은 예외가 발생합니다.
com.microsoft.sqlserver.jdbc.SQLServerException: Index 0 is out of range (인덱스 0이(가) 범위를 벗어났습니다.) at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:171) at com.microsoft.sqlserver.jdbc.SQLServerResultSet.verifyValidColumnIndex(SQLServerResultSet.java:504) at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getterGetColumn(SQLServerResultSet.java:1948) at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getValue(SQLServerResultSet.java:1981) at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getValue(SQLServerResultSet.java:1966) at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getInt(SQLServerResultSet.java:2209) at HelloWorld.doGet(HelloWorld.java:36) ...[생략]... at java.lang.Thread.run(Thread.java:619)
1. JDBC를 설치한다.. jdbc는 자바 디비 커넥터 약자로... 자바에서 해당 디비 프로그램에 연결하려면 필요하다 mssql용 jdbc는 http://msdn.microsoft.com/en-us/data/aa937724.aspx 여기에서 받을수 있다.. 압축을 푼후 폴더를 열어보면 sqljdbc.jar 와 sqljdbc4.jar 가 나오는데 본인이 jre6.0이상이면 sqljdbc4.jar 를.. 그 이하이면 sqljdbc.jar 를 사용하면 되는데 해당 파일을 jre폴더\lib\ext 에 복사해주면 아주 잘 작동한다.. 둘다 복사하지 말고 자신에 맞는것만 복사하자..
2. 자바 코딩 모든 jdbc 커넥터가 그렇듯.. 일단 드라이버 클래스를 읽어야한다. Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 이 한줄이면 클래스를 찾은후에 드라이버 리스트에 자동등록되게 된다.. 원하는 디비에 연결하려면 DriverManager.getConnection("jdbc:sqlserver://서버이름[:포트][;옵션=값[;추가옵션=값]]") 이런 형식을 따르게 된다.. 예를 들어 자신컴퓨터에 윈도우계정인증으로 접속할경우 jdbc:sqlserver://localhost;intergratedSecurity=true 자신컴퓨터에 지정된 계정과 비번을 쓸 경우 jdbc:sqlserver://localhost;user=아이디;password=암호 포트가 다를경우 jdbc:sqlserver://localhost:1234;user=아이디;password=암호 대강 이런식으로 하면된다..
이 다음부턴 다른 자바 디비 프로그래밍과 동일하다..
3. 접속이 안될경우.. http://msdn.microsoft.com/ko-kr/library/ms378845(SQL.90).aspx 나의 경우 sql서버 기본포트 1433으로 접속되지 않아 삽질을 했는데 일단 sql서버 설정 관리자에서 SQLServer네트워크구성 -> 프로토콜 -> TCP/IP 를 사용으로 변경해 주고 IP 주소 탭에서, IPALL부분의 TCP포트를 1433으로 직접 적어주어야 sql서버에서 잘 대기하게 된다.. 1433가 기본값이라곤 하는데 Visual Stduio 2008을 깔면서 자동으로 같이 깔리면서 설정이 마음대로 바뀌어서 설치된듯하다..
4. SQL Server Management Studio Express 만약 visual studio 2008 설치하면서 sqlserver2005가 깔렸다면 따로 db관리 프로그램이 설치되지 않았을것이다.. 이 프로그램으로 편하게 관리하길 http://go.microsoft.com/fwlink/?LinkId=65110