2016년 12월 27일 화요일

JSP에서 MySQL 사용하기





JSP에서 MySQL 사용하기

JSP에서는 보통 Oracle DB와 연동을 하는 경우가 많은데 
MySQL과 연동하는 경우도 있다. 이를 위한 설정 작업에 대해서이다.

(1) APM을 설치하는 방식
Apache, PHP, MySQL을 설치한 경우에도 JSP에서 간단히 MySQL과 연동할수 있다.
APM은 설치하기가 간단하기 때문에 이 방식이 편리할수도 있다.

 ① MySQL용 JDBC 드라이버 설치
APM을 통해서 MySQL이 설치가 되었다면 JSP에서 MySQL에 접속하기 위해서는 JDBC라는 드라이버를 설치해야 한다. 이를 설치하기 위해서는

http://www.mysql.com/ ⇒ Downloads 탭 ⇒ Community라는 하위 탭 ⇒ 우측의 MySQL Connectors 항목 클릭 ⇒ Connector/J  ⇒ Connector/J 5.1.40 하위의 ZIP 파일 다운로드 ⇒ 압축을 푼 후 mysql-connector-java-5.1.40-bin.jar를 Java가 설치된 폴더 중 jre7/lib/ext 폴더에 복사해 넣는다. 그리고 JSP 프로젝트의 WEB-INF/lib 폴더에도 복사해 넣는다.
여기까지가 되면 JSP에서 MySQL을 사용할 준비가 된것이다.

※ MySQL Connectors가 각 언어별(C++, .Net, Python...) 접속 드라이버를 제공하는데 그 중에서 Connector/J가 Java를 위한 연결(접속) 드라이버이다. 즉 JDBC 라이브러리이다.

(2) MySQL을 독립적으로 설치하기
http://www.mysql.com/ ⇒ Downloads 탭 ⇒ Community라는 하위 탭 ⇒ 우측의 MySQL Community Server 클릭 ⇒ Download MySQL Community Server로 이동 ⇒ MySQL Community Server 5.7.17에대한 다운로드들 중 ZIP 압축파일이 아닌 MSI 형태의 Installer를 다운로드 할 것 즉 Windows (x86, 32-bit), MSI Installer를 다운로드 할 것  ⇒ 설치

※ 설치 방법은 좀 복잡한데 다음 사이트 참조
http://withcoding.com/26

(3) JSP에서 사용하기
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>

... 중 략 ...

<%
Class.forName("com.mysql.jdbc.Driver");

/*
Connection java.sql.DriverManager.getConnection(String url, String user, String password) throws SQLException
Parameters:
url - a database url of the form jdbc:subprotocol:subname
user - the database user on whose behalf the connection is being made
password - the user's password
Returns:
a connection to the URL
Throws:
SQLException - if a database access error occurs
*/
//아래에서 world는 DB 이름이다.
//2번째 매개인자 aabb : world라는 DB의 계정 id
//3번째 매개인자 ccee : world라는 DB의 계정 비번
Connection conn = null;
  conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/world?useUnicode=true&characterEncoding=utf8", "aabb", "ccee");
String qry = "select Name, Population, CountryCode from city";
Statement stmt = null;
ResultSet rt = null;
if (conn != null){
out.println("world DB로 연결 성공<br/>");
stmt = conn.createStatement();
rt = stmt.executeQuery(qry);
%>
<table border="1" cellspacing="0" cellpadding="5" valign="middle">
<tr>
<th>국가명</th>
<th>인 구</th>
<th>국가코드</th>
</tr>
<%
  while(rt.next())
{
%>
<tr>
<td><%= rt.getString("Name") %></td>
<td><%= rt.getString("Population") %> 명</td>
<td><%= rt.getString("CountryCode") %></td>
<tr>
<%
} //while 
%>

</table>
<%
conn.close();
out.println("DB close~<br/>");
} else {
out.println("world DB로 연결 실패<br/>");
}
%>

2016년 12월 22일 목요일

MySQL insert시 홑 따옴표(single quotes) 처리하는 법





MySQL 테이블에 데이터를 insert하다보면 어떤 데이터는 insert가 실패하는 경우가 있다.
이때 exception을 발생하는 것도 아니고 mysqli_query()의 반환 값을 false로 반환하는 정도 선에서 끝난다.
그래서 80개의 레코드를 가진 테이블을 읽어 와서 새로운 테이블에 insert 작업을 하는데 
78개만 insert가 된다거나와 같은 상황이 발생하는 것이다.
이유와 원인은 홑따옴표(') 처리에서의 문제다.
게시판의 경우 제목이나 내용에 홑따옴표(')가 포함되는 경우가 있다.
이 경우 insert는 보기 좋게 실패한다.

예를들어 $result에 select한 결과 셋이 있다고 할때

while($data = mysqli_fetch_array($result))
{
... 전략 ...
$title = $data['title'];
$con = $data['content'];
... 후략...
    $qry = "insert into my_table (...생략... title, content ...생략...)
                  values (...생략... '$title', '$con' ...생략... )";
    mysqli_query($qry, $connect);
}


이 경우 title 내용이나 content에 홑따옴표가 있다면 해당 레코드가 insert가 되지 않는다.
해법은 title과 content에 addslashes()함수를 사용한다. 그렇게 되면 홑따옴표에 \를 추가해서 MySQL에 insert를 하게 되고 정상적으로 입력이 된다.
다음과 같이...
$title = addslashes($data['title']);
$con = addslashes($data['content']);

Python에서 list 항목 치환시 slice 사용의 주의할 점





Python의 list를 다룰 때 특히 list의 특정 항목을 다른 항목으로 치환하고자 할 때 사용하는 slice에서 자칫 잘못하면
원래의 list 항목을 날려 먹거나 원치 않는 value가 끼워넣어지는 문제가 발생한다.
그래서 list의 length가 원치 않게 변해 버리는 문제가 발생한다.
아래 코드가 전형적으로 이런 문제를 유발하는 예제이다.

#-*- coding: utf-8 -*-
a = []
b = [101, 102, 103, 104, 105]
for i in range(10):
   a.insert(i, i)

print("원본", a)
print('길이', len(a))

#아래 코드는 index 2~4까지를 바꾼다. 총3개를 바꾼다.
#그런데 list b에 있는 값은 5개이다. 따라서 b의 앞 3개는
#치환이 되지만 나머지 2개(104, 105)는 끼워넣기가 되어 버린다.
#따라서 list a가 원래 10개였는데 아래 코드 실행 후 len()은 12개가 된다
#a[2:5] = b[0:] 
#print(a)
#print("길이", len(a)) #12가 나온다


#아래 코드는 index 1~7까지 총 7개를 바꾸는데 바꿀 내용인 
#list b에는 값이 5개 뿐이다(101 ~ 105). 이럴 경우 발생하는 현상은
#list a의 index 1~5까지는 101~105로 각각 치환이 되고 
#list a에서 나머지 index 6~7에 해당하는 값은 사라져 버린다.
#그래서 아래 코드 실행후 list a의 len()은 8이 되어져 버린다.
#a[1:8] = b[0:] #이 코드를 실행하고자 하면 위 a[2:5] = b[0:]를 주석 처리 할 것
#print(a)
#print("길이", len(a)) #8이 나온다.

#이러한 문제를 해결하기 위해서는 다음과 같이 처리해 주어야 안전하다.
a[1:len(b)+1] = b[0:]
print(a)
print("길이", len(a))

2016년 12월 20일 화요일

putty로 접속한 vi editor 색상 조합 설정하기





putty나 telnet으로 원격 리눅스 서버에 접속해서 vi로 php 코드나 프로그램 소스를 작성/수정하는 작업을 할 일이 있는데 
이때 vi의 화면 색상들이 눈에 잘 띄는 색상조합이 아니다.
다음과 같이 특히 주석 부분이 검정 바탕에 파랑색이어서 보기가 많이 불편하다.
이것을 자신이 원하는 색상으로 변경할 수 있다.



vi의 색상을 변경할려면 자신의 home 디렉토리 root로 이동해서 .vimrc 파일에 다음 내용을 입력해 넣으면 된다.
만일 .vimrc 파일이 없다면 새로 만들어서 색상 설정 값을 입력한다.

highlight Comment term=bold cterm=bold ctermfg=2
highlight String ctermfg=3

여기서 중요한 값은 ctermfg이다. 터미널 foreground 색상을 뭘로 할지를 설정하는 부분이다.
여기서 사용할수 있는 컬러 값은 아래와 같다.

1 빨강
2 녹색
3 노랑
4 파랑
5 보라색
6 cyon
7,8,9 흰색

ctermfg=2를 했을 때는 녹색으로 글자색상이 표시된다.

그 다음으로 어떤 항목의 글자색상을 설정할지를 지정해 주어야 하는데
위의 경우 Comment는 소스 코드의 주석에 대해서 2(녹색)으로 설정하겠다는 것이고
그 다음으로 String은 " "안에 있는 문자열의 색상을 3(노랑)으로 설정하겠다는 뜻이다.
이렇게 .vimrc를 작성했으면 logout했다가 다시 login해서 vi로 열어보면 다음과 같은 형태로 변경이 되어 있을 것이다.



여기서 색상을 설정할 수 있는 어떤 항목들이 있는지를 볼려면 vi 화면상에서
:highlight를 입력하고 엔터키를 치면 다음과 같이 색상 설정을 할수 있는 항목들 리스트가 보인다.









2016년 12월 1일 목요일

Python 코드 상에서 한글 사용하기





Python은 좀 특이한 언어이다. 들여쓰기가 그렇게 의미 있는 행동이다.
또 공백이 있고 없고가 큰 차이를 만들어내는 경우도 있다.
대표적으로 Python 코드는 기본적으로 ASCII 문자로 처리해서 해석을 한다.
따라서 소스 코드 상에서 한글을 사용하면 컴파일 단계에서 에러 발산한다.
심지어는 #로 시작하는 주석에서 한글을 사용해도 컴파일 에러 발생한다.
에러 메시지는 다음과 같은 걸 뿜는다.

SyntaxError: Non-ASCII character '\xec' in file test.py on line 16, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details


따라서 파이썬에서 한글을 사용할려면 다음의 코드를 소스 맨 첫줄에 삽입해 주어야 한다.

#-*- coding: utf-8 -*-

그런데 다음과 같이 하면 여전히 한글을 사용할수 없는 상황이 변하지 않는다.

#-*- coding : utf-8 -*-

coding과 콜론(:) 사이에 있는 공백 때문이다. 

참고로 이 글은 Python 버전 2.7에서 실행했을 때의 상황이다.
Python 버전 3에서는 이상의 문제 발생하지 않는다.

2016년 11월 23일 수요일

Java JDK 1.7 버전 다운로드 받기





Java JDK 1.7 버전 다운로드 받기

Oracle에서 이제 더 이상 Java 7 버전을 지원해 주지 않은관계로 JDK 1.7을 다운 받을수 있는 창구가 제대로 제공되지 않고 있다.
아래는 JDK 1.7버전에 대해 다운로드 받을수 있는 경로이다.

https://www.oracle.com/technetwork/java/javase/archive-139210.html

아무튼 언제 없어질지 모르겠지만 Java 7버전이 필요할 경우가 있어서 ...

2016년 11월 16일 수요일

리눅스 rm 명령어를 이용한 디렉토리 관리에서 주의 및 안전장치 옵션





리눅스에서 파일이나 디렉토리를 삭제하는 명령은 자칫 잘못 사용하면 원치않는 파일뿐만 아니라 디렉토리 전체 혹은 농협 해킹에서 발생했던 것과 같이 시스템 전체를 날려버리는 불상사가 발생할수 있다.

우선 현재 위치가 
/home/myjob
에 위치해 있다고 가정할 경우

존재하지 않는 test1, test2, test3라는 디렉토리를 손쉽게 만들수 있는 방법에 대해서 먼저 살펴 본다.

현재 위치에서 test1/test2/test3와 같은 계층 구조를 가진 디렉토리를 만들고자 한다면
~$ mkdir test1
~$ cd test1
~/test1$ mkdir test2
~/test1$ cd test2
~/test1/test2$ mkdir test3
와 같이 통상적으로 만들수 있으나 위의 동작을 하나의 명령어로 손쉽게 만들수 있는 방법이
~$ mkdir -p test1/test2/test3
와 같이 간단히 처리할수 있다.

위와 같은 계층 구조를 가진 디렉토리가 존재하고
현재위치는 /home/myjob에 있을 경우 test1이라는 디렉토리를 삭제하고자 한다면 다음과 같이 하면 된다.

~$ rm -r test1
그런데 이렇게 되면 test1뿐만 아니라 그 하위의 test2 test3까지 모두 한꺼번에 삭제가 된다.
뿐만아니라 삭제할지를 묻지도 않고 날려버린다....;;;
과묵한 리눅스이다.

test1을 삭제할 경우 최소한의 안전장치에 해당하는 옵션을 이용하면 삭제할때 다음과 같은 질문으로 대화식으로 처리를 할수 있어 뜻밖의 실수를 그래도 어느정도 막을수 있다.
그 옵션은 -i 옵션이다.

~$ rm -ri test1

이 명령을 실행하면 다음과 같은 질문이 시스템으로부터 주어지고 그에 대해 대화식으로 처리를 할수가 있다.




2016년 10월 19일 수요일

MySQL limit 기능에 대해서





MySQL limit 기능에 대해서

게시판을 만들때 주로 사용하는 기능인데 DB에 있는 데이터를 모두 조회해서 가져오지 않고 
원하는 갯수만큼의 데이터만 조회해서 가져 오기 위한 기능이 DBMS마다 마련되어 있다.
MySQL을 예로 든다면 limit이라는 키워드를 쿼리문에 사용하여 이 기능을 이용할수 있다.

MySQL의 limit은 2개의 매개변수를 가지는데 
첫 번째는 「시작 위치」,  
두 번째는 「가져올 게시물 수」 이다. 

여기서 「시작 위치」라는 것은 그룹으로 묶었을 때 각 그룹들의 첫 번째 게시물(데이터)의 번호 번호를 의미한다.
예를 들어 10,000개의 데이터를 5개씩 가져온다고 할때(「가져올 게시물 수」가 5이라는 뜻)
전체 데이터를 5개씩 묶었을 때 묶여진 각 그룹들의 첫 번째 게시물(데이터)의 일련 번호를 「시작 위치」라고 한다는 뜻이다.
예를 들어 5개씩 묶으면
0~4
5~9
10~14
15~19
...

이때 「시작 위치」는 0, 5, 10, 15...가 될 것이다.
이때 각 그룹들에 일련 번호를 붙일 때 1번부터가 아니라 0번부터 일련 번호가 붙여 진다는 점을 주의해야 한다.

select * from bbs1 where id='bbs1' order by number desc limit (5 - 1) * 10, 15
⇒ 40번째 이후부터 15개의 게시물을 가져오라는 뜻

만일 limit의 매개변수를 1개만 사용하면 해당 매개변수의 갯수만큼 게시물을 가져오라는 뜻이다.

select * from bbs1 where id='bbs1' order by number desc limit 10
⇒ 이건 limit 0, 10와 동일한 뜻이다.

아래와 같이 변수 형태로도 당근 사용이 가능하다.
$page는 시작 위치이고 $view_total은 가여올 게시물의 수이다.

$query = "select * from bbs1 where id='bbs1' order by no desc limit $page, $view_total";

2016년 10월 16일 일요일

Oracle DB 접속 시 ORA-12560: TNS:protocol adapter error 발생 시





Oracle DB 접속 시 ORA-12560: TNS:protocol adapter error 발생 시

1) DOS 창에서 sqlplus로 접속시 다음과 같은 에러 발생시
ORA-12560: TNS:protocol adapter error


2) Oracle SQL developer로 접속시 다음과 같은 에러 발생시
IO 오류: The Network Adapter could not establish the connection


해갤책은
“내 컴퓨터 - 관리 - 서비스 및 응용프로그램 - 서비스”에서 Oracle 관련 서비스들이 실행이 되지 않아서의 문제이다.
아래와 같이 최소한 3개의 서비스 프로그램이 시작 상태이어야 한다.
  • OracleServiceXE 
  • OracleXEClrAgent 
  • OracleXETNSListener







2016년 9월 5일 월요일

C# 그래픽 작업시 화면 깜빡임을 없애주는 double buffering에 대해





C#에서 실시간 그래프를 그리다 보면 그리기 화면이 깜빡이는 현상을 볼수 있다.
이 문제를 해결하기 위해서는 그리기 할 대상을 double buffering 처리를 해 주면 깔끔하게 해결이 된다.
보통은 System.Windows.Forms::Panel위에 그리기 작업을 하게 될텐데, 혹은 Bitmap에 먼저 그린 후 그 Bitmap을 Panle에 그리는 방식이거나...
아무튼 이 경우 Panel을 double buffering 처리를 해 주면 된다.
문제는 Form은 화면 디자인 시점에 DoubleBuffered라는 속성 값을 true로 해 주면 되지만 Panel의 경우는 double buffering을 설정하는 메소드나 속성(property)이 막바로 접근이 안된다.
즉 protected 메소드이고 protected 속성이다. 

MSDN을 보면 속성의 정의가 아래와 같이 protected이고
protected virtual bool DoubleBuffered { get; set; }

메소드도 아래와 같이 protected이다.
protected virtual bool DoubleBuffered { get; set; }

따라서 Panel에 double buffering을 설정할려면 Panel을 상속받은 사용자 정의 클래스를 만들어서 이 사용자 정의 Panel을 사용해야 가능하다.

(1) Visual Studio의 해당 프로젝트명에서 마우스 우측 클릭 ⇒ 추가(Add) ⇒ New Item(새 항목) ⇒ Class를 선택 후 Class 이름 지정

(2) 아래의 내용을 추가한다.
    class DoubleBufferPanel : Panel
    {
        public DoubleBufferPanel()
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | 
   ControlStyles.UserPaint |
                                ControlStyles.AllPaintingInWmPaint, true
                );

            this.UpdateStyles();
        } 
    }

(3) Form1.Designer.cs에서 기존의 Panel을 사용자가 정의한 Panel로 변경한다.

위의 적색 사각형 영역 (Windows Form Designer generated code 영역)을 더블 클릭하여 InitializeComponent() 안에 있는

this.panel1 = new System.Windows.Forms.Panel();
this.panel1 = new Bitmap_Panel.DoubleBufferPanel();
와 같이 사용자 정의 Panel로 변경해 준다.
이후 부터 화면이 깜빡이는 현상 없이 잘 처리 될 것이다.

MSDN이 소개하는 DoubleBuffered에 대한 설명이다.
Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker.