출처 : https://stackoverflow.com/questions/2157282/generate-days-from-date-range


-- STR_TO_DATE 파라미터에 들어가는 날짜 역순으로 해서 최대 1000개 row를 생성하여 조회조건으로 걸러낸다.

SELECT DT.YYYYMMDD
  FROM (SELECT STR_TO_DATE('20170914', '%Y%m%d') - INTERVAL(A.A + (10 * B.A) + (100 * C.A)) DAY AS YYYYMMDD
            -- SELECT DATE_ADD(STR_TO_DATE('20170914', '%Y%m%d'), INTERVAL -(A.A + (10 * B.A) + (100 * C.A)) DAY) YYYYMMDD
             , A.A AS AA
             , B.A AS BA
             , C.A AS CA
          FROM (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS A
         CROSS JOIN (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS B
         CROSS JOIN (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS C
        ) DT
 WHERE DT.YYYYMMDD BETWEEN '20170801' AND '20170914';




-- 현재 날짜 역순으로 해서 최대 1000개 row를 생성하여 조회조건으로 걸러낸다.

SELECT DT.YYYYMMDD
  FROM (SELECT DATE_ADD(NOW(), INTERVAL -(A.A + (10 * B.A) + (100 * C.A)) DAY) YYYYMMDD
             , A.A AS AA
             , B.A AS BA
             , C.A AS CA
          FROM (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS A
         CROSS JOIN (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS B
         CROSS JOIN (SELECT 0 AS A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS C
        ) DT
 WHERE DT.YYYYMMDD BETWEEN '20170801' AND '20170914';








출처 : http://blog.kurien.co.kr/116


Gimp : https://www.gimp.org/

Gimp Korea : http://gimp.kr

Gimp 문서 : https://docs.gimp.org/ko/

김프란?


GIMP 는 많은 플랫폼에서 사용가능한 사진 편집 프로그램으로 GNU Image Manipulation Program 의 약자입니다. GIMP는 사진 편집이나 이미지 생성 및 편집 등 다양한 이미지 편집 작업을 하기에 적절한 프로그램입니다.

김프는 간단한 페인트 프로그램, 전문적인 사진 편집 프로그램, 온라인 배치 프로세싱 시스템, 대량의 이미지 렌더링, 이미지 포맷 변환기 등의 다양한 용도로 사용할 수 있습니다.

김프는 확장성이 뛰어나며 유연합니다. 플러그인과 확장기능의 추가로 어떠한 일도 할 수 있도록 디자인되었습니다. 발전된 스크립팅 인터페이스는 간단한 작업부터 굉장히 복잡한 이미지 편집 작업까지 모든 것을 할 수 있는 스크립트를 쉽게 작성할 수 있게 해줍니다.

김프의 장점 중 하나는 많은 소스로부터 다양한 운영체제를 위한 기능들을 제공받을 수 있다는 점입니다. 대부분의 GNU/Linux 배포판에서는 GIMP를 기본 프로그램으로 포함합니다. 또한 Microsoft Windows™ 나 Apple 사의 Mac OS X™(Darwin) 등의 다른 운영체제에서도 사용할 수 있습니다. 하지만 김프는 공짜 프로그램이 아닙니다. General Public License( GPL license, GNU 일반 공중 사용 허가서)에 의해 보호되는 공개 프로그램입니다. GPL 은 사용자로 하여금 프로그램 소스에 대한 자유로운 접근과 수정을 허용합니다.


이렇게 여러가지의 장점이 있습니다.

몇가지만 말해보자면, 가장 중요한건 먼저 오픈소스 프로그램으로 "무료"이구요!

한글 지원이 되어있어 따로 한글 패치가 필요없습니다!

사용자가 직접 플러그인을 확장하여 어떤 기능이든 만들어 사용하는것도 가능합니다.

그리고 Windows, Mac OS, Linux 모든 OS에서 사용이 가능하죠.


기본 기능만 하더라도 포토샵과 큰 차이가 없습니다.


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램


포토샵에 있는 영역선택, 올가미, 마법봉, 펜 툴, 색 선택, 색상 추출, 확대, 글꼴, 자유변형, 붓, 펜, 복원도구, 흐림, 선명하게, 문지르기, 닷지, 번 등

다 적진 못했지만 이것 외에도 무지 많은 기능이 있습니다.


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램


포토샵 못지 않게 많은 기능, 포토샵에도 없는 다양한 기능이 있습니다.

도구상자와 레이어 창이 따로 선택되어서 작업에도 편하구요


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램

메모리도 포토샵에 비해 월등히 적게 먹습니다.

왠만한 게임 다 돌리는 컴퓨터에서도 포토샵을 쓰면 언제나 느리더라구요...

김프는 그럴 걱정이 없어요!


그리고 포토샵을 다운받는 이유가 포토샵 고유 확장자인 PSD 파일 때문이신분!

김프는 PSD도 걱정 없이 돌아갑니다.

포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램

logo_0161.zip


지금 위의 이미지가 이미지 아래 있는 PSD 파일을 김프로 열었던 이미지입니다.

문제 없이 실행이 되는걸 볼 수 있습니다!


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램


다운로드는 아래의 주소에서 가능하시구요.

영어 울렁증이신분은 주황색 HTTP만 눌러주시면 다운로드 가능합니다^^


Gimp 다운로드 하기 : http://www.gimp.org/


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램


다운받으시고 난 후에 설치하시면 그냥 다음만 눌러주시면 되는데요!

시작할 때 language 설정이 있습니다.

기본이 English인데 한국어가 없는걸 보고 영어로 설치되는거 아니냐! 라고 생각하시는분들이 계실것 같아 말씀드리지만,

어떤 언어를 선택하시더라도 결과는 한국어입니다.


시작할 때 물어보는 언어는 설치 프로그램 언어이니 걱정말구 설치하세요!


포토샵과는 다른점이 있어서 어려워 하시는 분들을 위해서 김프 강좌 사이트인 김프 코리아 주소를 올려드릴께요.


김프코리아 주소 : http://www.gimp.kr/


포토샵, 김프, 무료 포토샵, 이미지 편집 프로그램이렇게 이미지 수정이 가능합니다.


이 프로그램은 오픈소스 프로그램으로 집, 회사, 관공서 어디서든 무료로 이용하실 수 있습니다!


무료 이미지 편집 프로그램, 이젠 가격 걱정 마시고 김프(Gimp)를 써보세요!



출처 : https://velopert.com/1712


이전부터 Sass 의 존재를 알고있었고,배우고싶었는데, 미뤄오셨나요? 그렇다면 잘 오셨습니다.
이 포스트에서는 Sass 의 특징에 대하여 알아보고, Sass 로 할 수 있는 멋진 것들을 알아볼테니까요.

Sass 가 뭐죠?

Sass (Syntactically Awesome Style Sheets : 문법적으로 멋진 스타일시트) 는 CSS pre-processor 로서, 복잡한 작업을 쉽게 할 수 있게 해주고, 코드의 재활용성을 높여줄 뿐 만 아니라, 코드의 가독성을 높여주어 유지보수를 쉽게해줍니다.

CSS pre-processor 란?

CSS 를 확장하는 스크립팅 언어로서, 컴파일러를 통하여 브라우저에서 사용 할 수 있는 일반 CSS 문법 형태로 변환합니다


어떻게 컴파일하죠?

SASS 를 컴파일하는방법은 여러가지가 있습니다:

  • 오리지널 Ruby Sass 사용하기
    gem install sass 로 설치하고,
    sass style.scss style.css 로 컴파일한다.
  • GUI 어플리케이션 사용하기 – Koala, Hammer, Compass
  • libsass 사용하기
    이는 C언어로 작성된 매우 빠른 Sass compiler 입니다.
    많은 환경에서 사용될 수 있습니다.

어떤걸 선택해야하냐구요? 여러분이 무엇을 만드는지, 어떤 환경에서 작업하는지에 따라 다릅니다.

저는 빠른 컴파일속도를 선호하고, Node.js 환경에서 작업을 하므로 node 환경에서 libsass 를 사용 할 수 있게 해주는 node-sass 를 사용합니다.

node-sass 사용하기

# NPM 을 통하여 node-sass 글로벌 설치
$ sudo npm install -g node-sass

# 컴파일하여 현재 디렉토리에 저장
$ node-sass style.scss -o .

# style.scss 파일에 변화가 있을 떄 마다 자동으로 리컴파일
$ node-sass style.scss -w -o .

성능 차이

이미지 2

libsass 이 오리지널 Ruby Sass 에 비하여 훨씬 빠른 성능을 지니고 있습니다.

주의: libsass는 Ruby Sass 의 기능의 100% 를 지원하지는 않습니다 지금 시점으로는 모든 기능이 지원되기는 합니다.
허나, Ruby Sass 가 업데이트 되었을 때는, LibSass 역시 업데이트 될 때까지 기다려야합니다.
이에 대한 자세한 내용은 Sass Compatibility 를 참고하세요.

그냥 공부만 하거나, 예제를 만들어 공유하고싶은 분들께는 Sassmeister 를 사용하는것을 추천드립니다.
웹상에서 SASS 코드를 CSS 를 변화해주는 웹서비스이며, 예제를 만들어 공유 할 수도있습니다.


.SASS 와 .SCSS 의 차이는 뭐죠?

Sass 가 처음 릴리즈 되었을 때, 주 문법은 CSS와 많이 달랐습니다. 괄호 { } 대신 들여쓰기 (indentation) 을 사용하였으며 세미콜론 ; 을 사용하지 않고 단축 연산자를 사용하였습니다.

대략 다음과 같은 형태이지요.

=myclass // = means @ mixin
  font-size: 12px

p
  +myclass // + means @include

그 시절, 일부 개발자는 이 새로운 문법에 익숙하지 않아서, Sass 버전 3 이상부터는 주 문법이 .scss 로 변경되었습니다.
SCSS 는 CSS 의 상위집합으로서, CSS와 동일한 문법으로 SASS 의 특별한 기능들이 추가되어있습니다.

이 강좌에서는 .scss 문법을 사용하도록 하겠습니다. (오리지널 문법도 아직까지 지원되므로, 옛날 문법이 맘에 드시는분들은 그 문법을 사용해도 됩니다)



0. Comment (주석) 

Sass의 주석이 CSS 와 다른점은 한 줄 주석이 추가되었다는 점 입니다.

한 줄 주석은 // 로 표기하며,  CSS로 컴파일 되었을 때 나타나지 않습니다

여러 줄 주석은 CSS 와 동일하며 CSS 로 컴파일 되었을 때 나타납니다.

Sass

/* You can See me */

// You can't see me

/* You
   Can
   See
   Mee
*/

CSS

/* You can See me */
/* You
   Can
   See
   Mee
*/

1. Variable (변수)

Sass 는 CSS에 변수 개념을 도입해줍니다.

변수로 사용 가능한 형태는 숫자, 문자열, 폰트, 색상, null, listsmaps 가 있습니다.

변수를 사용 할 떄는 $ 문자를 사용합니다. 첫 변수를 한번 만들어볼까요?

Sass

$primary-color: #333;

CSS

변수를 만들어도, 사용하지 않으면 컴파일된 CSS 파일에는 아무것도 나타나지 않습니다.

한번 body 에서 사용을 해봅시다.

Sass

$primary-color: #333;

body {
  background-color: $primary-color;
}

CSS

body {
  background-color: #333;
}

Variable Scope (변수 범위)

Sass 의 변수엔 변수범위가 있습니다.  변수를 특정 selector (선택자) 에서 선언하면 해당 selector 에서만 접근이 가능합니다.

Sass

$primary-color: #333;

body {
  $primary-color: #eee;
  background-color: $primary-color;
}

p {
  color: $primary-color;
}

CSS

body {
  background-color: #eee;
}

p {
  color: #333;
}

변수를 선언 할 때, 변수를 global (전역) 하게 설정 할 때는 !global 플래그를 사용합니다.

Sass

$primary-color: #333;

body {
  $primary-color: #eee !global;;
  background-color: $primary-color;
}

p {
  color: $primary-color;
}

CSS

body {
  background-color: #eee;
}

p {
  color: #eee;
}

추가적으로, !default 플래그는 해당 변수가 설정되지 않았거나 값이 null 일떄 값을 설정합니다.

이 플래그는 나중에 mixin 을 작성 할 떄 유용하게 사용됩니다. (mixin 에 대한 설명은 강좌 하단부에 있습니다)

Sass

$primary-color: #333;

$primary-color: $eee !default;

p {
  color: $primary-color;
}

CSS

p {
  color: #333;
}

2. Math Operators (수학 연산자)

Sass 에서는 수학 연산자들을 사용 할 수 있습니다. 지원되는 연산자들은 다음과 같습니다:

Operator Description
+  addition
- subtraction
/ division
* multiplication
% modulo
== equality
!= inequality

주의하실점은, +, - operator 를 사용 할 떄는 단위를 언제나 통일시켜야합니다.

예를들어, 다음과 같은 코드는 오류가 발생하게됩니다: $box-width: 100% - 20px

이런 작업을 해야한다면 css 의 calc() 함수를 사용해야합니다.

다음과 같은 식은 오류 없이 작동합니다: $box-width: 300px / 960px * 100%

Sass

.container { width: 100%; }


article[role="main"] {
  float: left;
  width: 600px / 960px * 100%;
}

aside[role="complementary"] {
  float: right;
  width: 300px / 960px * 100%;
}

CSS

.container {
  width: 100%;
}

article[role="main"] {
  float: left;
  width: 62.5%;
}

aside[role="complementary"] {
  float: right;
  width: 31.25%;
}

3. Built-in Functions (내장함수)

이전에 여러분들이 CSS 작업을 하실 때, 멋진 버튼을 만드려고 컬러 팔레트 툴로 적절한 그림자 색깔을 찾으려고 노력한적이 있으신가요?

그런 여러분들께 darken() 함수를 소개합니다!
이 함수는 특정 색깔과, 얼마나 어둡게 할지 인수로 던져주면 자동으로 색상을 계산해서 나타내줍니다.
See the Pen <a href="http://codepen.io/velopert/pen/MewQvp/">MewQvp</a> by velopert (<a href="http://codepen.io/velopert">@velopert</a>) on <a href="http://codepen.io">CodePen</a>.<br />

(위 예제에서 사용된  & 문자에 대한 설명은 다음 섹션에서 설명됩니다)

이 함수 외에도, 많은 유용한 함수들이 엄청 많습니다. 모든 내장함수들의 목록은 여기서 확인 할 수 있습니다.

색깔에 관한 함수들의 보이는 예제는 Jackie Balzer 의 Visual Guide to Sass & Compass Color Functions 에서 확인 할 수 있습니다.


4. Nesting (중첩)

Sass 의 매우 유용한 기능중 하나는 선언을 중첩시킬 수 있다는 것 입니다. 어떻게 작동하는지, 또 어떤점을 주의해야 할 지 알아봅시다.

일반 CSS 에선 특정 선택자 안의 선택자를 스타일링 하려면 이렇게 했었죠?

/* CSS */
.container {
    width: 100%;
}

.container h1 {
    color: red;
}

간단한 CSS 면, 큰 문제는 없지만, CSS 파일이 커지면 유지보수가 어려워지죠..

Sass 에선, 이런식으로 작성하면 위와 같은 결과물을 얻을 수 있게 됩니다!

/* Sass */
.container {
    width: 100%;
    h1 {
        color: red;
    }
}

부모 선택자를 리퍼런스 할떄는 & 문자를 사용합니다. (내장함수 예제에서도 이 문자가 사용됐었죠?)

Sass

a {
  color: black;
  &:hover {
    text-decoration: underline;
    color: gray;
  }
  &:visited {
    color: purple;
  }
}

CSS

a {
  color: black;
}
a:hover {
  text-decoration: underline;
  color: gray;
}
a:visited {
  color: purple;
}

코드 중첩을 하는건 위와같이 하면 됩니다. 하지만 중첩에서 벗어나려면 (de-nest) 어떻게 할까요? 예를들어.. 다음과 같은 코드가 있을 때

/* Sass */
.container {
  .child {
    color: blue;
  }
  .sibling {
    color: gray;
  }
}

sibling 클래스가 container 클래스 밖에서도 사용되는것을 알게되었을땐, @at-root directive (지시자) 를 사용합니다.

Sass

.container {
  .child {
    color: blue;
  }
  @at-root .sibling {
    color: gray;
  }
}

CSS

.container .child {
  color: blue;
}
.sibling {
  color: gray;
}

위는 그냥 사실 사용 예제일 뿐이고 사실상 이런 상황이 오면 코드를 잘라내서 밖에 붙여넣는게 맞죠.

보통 @at-root 는 Sass 코드를 깔끔하게 정리하면서 작성 할 때 사용됩니다 (참조링크: Writing modular CSS (BEM/OOCSS) selectors with Sass 3.3)

인셉션 규칙: Sass 코드 중첩을 할 때, 4 레벨 보다 깊게 들어가지 말 것

영화 인셉션에서 보면, 레벨 5의 꿈을 꾸게 될 땐 림보에 빠져서 개고생하게되죠..
더 깊게 들어간다고해서 오류가 나거나 Sass 개발자가 화를 내지는 않겠지만.. 코드가 복잡해질 확률이 높고 유지보수가 어려워집니다.
자세한 내용은 제목부분의 링크를 클릭하여 참조하세요.


5. Import (불러오기) 

import 기능은 스타일들을 여러 파일들로 나누고, 다른 파일에서 불러와서 사용하는 기능입니다.

다음과 같이 @import directive 를 사용하여 특정.scss 파일을 불러 올 수 있습니다:

@import "layout.scss";

참고로, 확장자를 붙이지 않아도 됩니다.

@import "layout";

partial

partial 기능에 대하여 알아봅시다.

만약에 .sass 파일이나 .scss 파일의 파일이름을 underscore _ 로 시작하면 css 파일로 따로 컴파일되지 않습니다.

html 에서 해당 css 파일을 불러올일이 없고, import 만 되는경우에는이 기능을 사용하세요.


6. Extend (상속) 

Sass 에서 특정 선택자를 상속 할 때, @extend directive를 사용합니다.

Sass

.box {
  border: 1px solid gray;
  padding: 10px;
  display: inline-block;
}

.success-box {
  @extend .box;
  border: 1px solid green;
}

CSS

.box, .success-box {
  border: 1px solid gray;
  padding: 10px;
  display: inline-block;
}

.success-box {
  border: 1px solid green;
}

Placeholder

Placeholder 선택자 % 를 사용하면 상속은 할 수 있지만 해당 선택자는 컴파일되지 않습니다.

Sass

%box {
  padding: 0.5em;

}

.success-box {
  @extend %box;
  color: green;
}

.error-box {
  @extend %box;
  color: red;
}

CSS

.success-box, .error-box {
  padding: 0.5em;
}

.success-box {
  color: green;
}

.error-box {
  color: red;
}

7. Mixin (믹스인)

Mixin 은 Sass 의 아주 유용한 기능 중 하나인데요, extend 와 비슷하지만 argument (인수) 를 받을 수 있습니다.

mixin 을 선언 할 떄는 @mixin directive 를 사용하며, 이를 사용 할 때는 @include directive 를 사용합니다.

Sass

@mixin headline ($color, $size) {
  color: $color;
  font-size: $size;
}

h1 {
  @include headline(green, 12px);
}

CSS

h1 {
  color: green;
  font-size: 12px;
}

Mixin 을 응용하면 이런식으로도 사용 가능합니다:

Sass

@mixin media($queryString){
    @media #{$queryString} {
      @content;
    }
}

.container {
    width: 900px;
    @include media("(max-width: 767px)"){
        width: 100%;
    }
}

CSS

.container {
  width: 900px;
}
@media (max-width: 767px) {
  .container {
    width: 100%;
  }
}

워우워우… 갑자기 처음보는 표현들이 좀 나왔죠? 당황하지 마세요, 설명해드리겠습니다.

#{ } 표현은 특정 문자열을 따로 처리하지않고 그대로 출력 할 때 사용됩니다.

@content directive 를 사용하면 나중에 @include 하였을 때, 그 선택자 내부의 내용들이 @conent 부분에 나타나게됩니다.


8. Function (함수)

Built-in Function 과는 달리 이부분은 임의 함수입니다.

Function은 위에서 소개한 mixin 과도 사뭇 비슷한데요, 차이점은 mixin 은 style markup 을 반환하지만,  function 은 @return directive 를 통하여 을 반환합니다.

Function을 선언 할 때는,  예상하셨겠지만! @function directive 를 사용합니다.

Sass

@function calc-percent($target, $container) {
  @return ($target / $container) * 100%;
}

@function cp($target, $container) {
  @return calc-percent($target, $container);
}

.my-module {
  width: calc-percent(650px, 1000px);
}

CSS

.my-module {
  width: 65%;
}

꿀 팁: 자주 사용 할 것 같은 함수는 위와같이 단축함수를 만들어 사용하세요. 그런다고해서 결과물의 용량이 늘어나지는 않으니까요.


마치면서

여기까지 다 읽으셨다면 Sass 에 대해 어느정도 배운 것 같다.. 고 생각 하실 수 있지만, 그건 큰 오산입니다! Sass 의 기본적인 기능에 대하여 대부분 소개한건 사실 이지만 이 강좌에서 다룬건 그저 빙산의 일각에 불과합니다. 왜, 그렇잖아요. CSS 도 속성 하나하나만 따지면 그렇게 대단 한 것도 아닌데 여러가지 속성들이 합쳐지면 엄청나게 멋진 UI를 만드는 것 처럼요.

Sass 에 대하여 더 배우고 싶으신 분들께 다음 링크를 추천해드리겠습니다.

그럼, 즐거운 Sassing 되세요 🙂

Refrences

  1. “Sass Basics”. Sass.
  2. “Getting Started With Sass”. Scotch.io
  3. The Sass Ampersand”CSS-Tricks.
  4. “The Inception Rule”. The Sass Way.
  5. “Understanding placeholder selector”. The Sass Way.
  6. “Sass Basics: The Mixin Directive”. SitePoint
  7. “Pure Sass Functions”. The Sass Way.




출처 : http://devlsh.tistory.com/entry/Java-Naming-Convention


아주 오래전에 읽었봤었지만 그때는 중요성도 모르고 그저 그런가보다 하고 지나갔던 코딩컨벤션
특히 네이밍이 코딩에서 가장 어려운 일이라는 걸 느껴본 사람이라면 다시 한번 보시길...

http://geosoft.no/development/javastyle.html

가장 중요한 말은 이 모든 규칙들은 가독성을 위해서라면 위반되어도 된다는 말.

  1. 필드는 ‘_’ 접미사를 사용한다.
  2. 변수의 길이는 영역과 비례한다.
  3. 객체명의 의미를 메소드명에 넣지마라.?line.getLength(); // NOT: line.getLineLength
  4. compute, find, initialize 사용
  5. 컬렉션은 복수형으로
  6. 개수를 나타내는 변수는 ’n’ 접두사를 사용한다.
  7. 엔터티 번호에는 ‘i’ 접두사나 ‘No’ 접미사를 사용한다.
  8. 대응하는 단어를 사용한다.?get/set , add/remove , create/destroy , start/stop , insert/delete , increment/decrement , old/new , begin/end , first/last , up/down , min/max , next/previous , old/new , open/close , show/hide , suspend/resume
  9. 함수명은 ‘처리 후 무엇을 리턴하는지’, 프로시저명은 ‘무엇을 처리하는지’를 나타낸다.
  10. 인터페이스 디폴트 구현은 ‘Default’ 접두사를 사용한다.
  11. 팩토리 메소드의 이름은 ‘new’ 접두사에 반환하는 인스턴스의 클래스명으로 한다.?public Point newPoint(...)
  12. 메소드 선언 규칙은 <access> static abstract synchronized <unusual> final native 순서이다.
  13. do-while 사용 자제
  14. 조건이 복잡한 경우 임시 boolean으로 단순화 한다.
  15. 정상적인 경우를 if에 놓고 예외를 else에 둔다.
  16. 조건문과 한줄에 놓지 마라.?디버깅을 위해서
  17. 조건문 안에 실행문이 있어서는 안된다.
  18. 특정 의미를 갖는 숫자는 항상 의미를 나타내는 상수로 바꿔서 사용한다.
  19. 빈 for문은 ‘;’(세미콜론)을 새 줄에 놓는다.?for(<initialization>; <condition>; <update>)? ;
  20. 복잡한 메소드는 주석을 달지 말고 새로 만든다.(self-documenting)
  21. javadoc주석을 제외한 주석은 multi-line 주석이라고 해도 ‘//‘를 사용한다.?/* */주석은 디버깅용으로 언제든 제거해서 사용 할 수 있게 한다.
  22. 컬렉션은 포함하는 유형을 주석으로 뒤에 넣는다.?private Vector points_; // of Point
  23. 모든 public 클래스, 또 publics 클래스내의 public, protected 메소드는 javadoc을 만든다.


Java naming은 아니지만 참고할만한 http://msdn.microsoft.com/en-us/library/xzf533w0(v=VS.71).aspx


Java Naming Conventions

 Identifier Type

 Identifier Type

 Examples

 Packages

 유일 패키지명의 접두어는 항상 소문자로 된 ASCII 문자로 쓰며현재까지의 최상위 도메인명인 com, edu, gov, mil, net, org중에 하나이거나, ISO 표준 3166 (1981)에서 지정한 두글자로 된 영문 국가 코드 중에 하나여야 한다.

패키지명의 나머지 요소들은 조직의 내부 네이밍 규칙에 따라 바뀐다이러한 규칙들에 따르면 어떤 디렉토리명 요소에는 부서명프로젝트명기관명로그인 사용자명 등이 올 수 있다.

 com.sun.eng
 com.apple.quicktime.v2
 edu.cmu.cs.bovik.cheese

 

 Classes

 클래스명은 명사여야 하고각 단어의 첫글자는 대문자로 한다클래스명은 간단해야 하며그 클래스를 잘 설명할 수 있어야 한다. (만약 URL이나 HTML같은 단어처럼 축약형이 더 널리 사용되는 경우가 아니라면이니셜명이나 축약형은 피하고 전체 단어를 사용하라.

 class Raster;
 class ImageSprite;

Interfaces

 인터페이스명은 클래스명과 같은 대소문자 규칙을 적용한다.

 interface RasterDelegate;
 interface Storing;

 Methods

 메소드는 동사여야 하고 첫 글자는 소문자다음의 각 단어의 첫글자는 대문자를 사용한다.

  run();
 runFast();
 getBackground();

 Variables

 변수를 제외하고모든 인스턴스클래스클래스 상수는 첫 글자를 소문자로 시작하는 대소문자 혼합 형태이다내부 단어는 대문자로 시작해야 한다변수명으로 언더스코어("_")나 달러("$") 둘다 허용은 되지만이들 글자들로 시작할 수는 없다.

변수명은 짧지만 의미를 가져야 한다변수명은 기억하기 쉬워야 한다임의의 관찰자가 보더라도 그 사용의도를 알 수 있게 해야 한다임시적인 1회성(throwaway) 변수가 아니라면 한 글자로 된 변수명은 피해야 한다임시변수에 대한 일반적인 이름은 i, j, k, m 가 있고정수를 나타내는 n, 문자를 나타내는c, d, e가 있다.

 int i;
 char c;
 float myWidth;

 

 Constants

 클래스 상수로 선언된 변수명과 ANSI 상수명은 언더스코어("_")로 구분된 대문자 단어를 사용한다. (디버깅을 편하게 하려면 ANSI 상수는 피하는 것이 좋다.)

 static final int MIN_WIDTH = 4;
 static final int MAX_WIDTH = 999;
 static final int GET_THE_CPU = 1;

 




Naming Conventions


General Naming Conventions


1. 패키지 이름은 소문자로만 하세요.
mypackage, com.company.application.ui
패키지 이름은 반드시 소문자로 하세요. Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


2. 변수 이름은 소문자로 시작하시고, 명사로 지어주세요.
line, audioSystem
변수 이름은 반드시 소문자로 시작하세요. 단어가 바뀌는 부분은 대문자로 구분해주시면 됩니다. Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


3. 상수(final 변수) 이름은 대문자로만 쓰세요. 단어가 바뀔 때는 언더바(_)로 구분하시면 됩니다.
MAX_ITERATIONS, COLOR_RED
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.
대부분의 경우에는 상수보다는 메서드를 통해서 제공하는 편이 좀 더 좋은 선택입니다.
int getMaxIterations() // NOT : MAX_ITERATIONS = 25
{
    return 25;
}


4. 메서드 이름은 소문자로 시작하시고, 동사로 지어주세요.
getName(), computeTotalWidth()
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


5. 이름을 지을 때 되도록 약어(약자)를 모두 대문자로 하면 가독성이 떨어집니다. 첫 문자만 대문자로 하세요.
exportHtmlSource(); // NOT: exportHTMLSource();
openDvdPlayer(); // NOT: openDVDPlayer();
되도록 첫 문자만 대문자로 하는 편이 낫습니다.


6. 일반적인 변수들은 타입과 변수명을 같게 하세요.
void setTopic(Topic topic) // NOT: void setTopic(Topic value)
// NOT: void setTopic(Topic aTopic)
// NOT: void setTopic(Topic t)
void connect(Database database) // NOT: void connect(Database db)
// NOT: void connect(Database oracleDB)

일반적이지 않은 변수들은 다음과 같은 룰을 적용할 수 있습니다.
Point startingPoint, centerPoint;
Name loginName;


7. 사용 범위가 넓은 변수는 이름을 길게 짓고, 사용 범위가 짧은 변수는 이름을 짧게 지으세요.
루프문에 사용되는 변수 같이 사용 범위가 짧은 변수들은 짧은 이름을 쓰세요.
일반적으로 int형 변수는 i, j, k, m, n을 쓰고, char형 변수는 c, d를 씁니다.


8. object의 이름이 암시적으로 어떤 것을 표현하고 있다면 메서드 이름에 그 부분을 쓰지 마세요.
line.getLength(); // NOT: line.getLineLength();
의미가 중복되는 부분을 쓰지 마세요.



Specific Naming Conventions


1. get/set 메서드는 속성(변수)에 대해서 직접적인 접근을 해야할 때 쓰세요.
employee.getName();
employee.setName(name);
matrix.getElement(2, 4);
matrix.setElement(2, 4, value);
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


2. is 키워드는 boolean 타입의 변수나 boolean 타입을 리턴하는 메서드 앞에 붙이세요.
isSet, isVisible, isFinished, isFound, isOpen
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.
isStatus나 isFlag는 간결하지만 좋지 않은 이름입니다.
boolean 타입의 Setter 메서드는 반드시 다음과 같이 써야합니다. (이때는 get/set이 아니라 is/set으로 매칭이 됩니다.)
void setFound(boolean isFound);
경우에 따라서는 has, can, should 키워드를 쓸 수 있습니다.
boolean hasLicense();
boolean canEvaluate();
boolean shouldAbort = false;


3. 어떤 것을 계산하는 경우에는 compute 키워드를 메서드 앞에 붙일 수 있습니다.
valueSet.computeAverage();
matrix.computeInverse();
어떤 것을 계산할 때 씁니다. 계산 결과가 있을 경우 result라는 키워드를 계산 결과를 저장하는 변수에 쓸 수 있습니다.


4. 어떤 것을 찾을 경우에는 find 키워드를 메서드 앞에 붙일 수 있습니다.
vertex.findNearestVertex();
matrix.findSmallestElement();
node.findShortestPath(Node destinationNode);
어떤 것을 찾을 때 씁니다.


5. object나 어떤 확정적인 작업의 초기화를 할 경우에는 initialize 키워드를 메서드 앞에 붙일 수 있습니다.
printer.initializeFontSet();
절대 init 이라고 쓰지 마세요.


6. JFC(Swing) 변수들은 element 타입(component 타입)을 변수 뒤에 붙일 수 있습니다.
widthScale, nameTextField, leftScrollbar, mainPanel, fileToggle, minLabel, printerDialog
변수 이름이 길어지더라도 타입을 뒤에 적어두면 가독성이 좋아집니다.


7. collection이나 배열 타입의 변수 이름은 복수 형태로 이름을 지으세요.
Collection<Point> points;
int[] values;
collection 타입은 저장되는 object의 복수 형태로 지으시면 되고, 일반 배열 타입은 의미를 부여하며 복수 형태로 이름을 지으시면 됩니다.


8. object의 갯수를 나타낼 경우에는 n 키워드를 변수 앞에 붙일 수 있습니다.
nPoints, nLines
Sun사에서는 이러한 용도로 num 키워드를 사용하고 있습니다. numberOf의 약자로써 표현하였지만 실제로는 number라는 느낌이 강하기 때문에 num이라고 쓰지 마시길 바랍니다. n 키워드 또는 numberOf 키워드를 사용해서 나타내시는 것이 좀 더 좋습니다.


9. 엔티티의 번호를 나타낼 경우에는 No 키워드를 변수 뒤에 붙일 수 있습니다.
tableNo, employeeNo
엔티티 번호를 나타낼 때 사용합니다. 다른 방법으로는 i 키워드를 붙이는 것입니다. iTable, iEmployee 라고 해서 iterator의 역할로써 쓰는 것입니다.


10. Iterator 변수들은 i, j, k 등과 같은 이름을 사용하세요.
for (Iterator i = points.iterator(); i.hasNext(); ){
:
}
for (int i = 0; i < nTables; i++) {
:
}
주로 i를 쓰고, j, k 등은 중첩된 반복문일때 쓰세요.


11. 대응되는 단어를 사용해서 이름을 지으면 좋습니다.
get/set, add/remove, create/destroy, start/stop, insert/delete,
increment/decrement, old/new, begin/end, first/last, up/down, min/max,
next/previous, old/new, open/close, show/hide, suspend/resume, etc.
이렇게 하면 가독성이 좋아집니다.


12. 되도록 약자(축약형)를 쓰지 마세요.
computeAverage(); // NOT: compAvg();
ActionEvent event; // NOT: ActionEvent e;
catch (Exception exception) { // NOT: catch (Exception e) {
되도록 이러한 형태는 피하세요.
cmd instead of command
comp instead of compute
cp instead of copy
e instead of exception
init instead of initialize
pt instead of point
etc.
다음과 같은 많이 쓰이는 경우는 약자를 써도 됩니다.
HypertextMarkupLanguage instead of html
CentralProcessingUnit instead of cpu
PriceEarningRatio instead of pe
etc.


13. boolean 타입 변수 이름은 부정적인 의미로 쓰지 마세요.
bool isError; // NOT: isNoError
bool isFound; // NOT: isNotFound
부정적인 이름을 쓰면 가독성이 떨어집니다. 예를 들어, !isNoError 라고 표기를 하면 어떤 의미인지 파악하는 데 오래 걸립니다.


14. 서로 관련이 있는 상수들은 상수 앞에 공통되는 단어를 붙여주는 것이 좋다.
final int COLOR_RED = 1;
final int COLOR_GREEN = 2;
final int COLOR_BLUE = 3;
다음과 같이 나타낼 수도 있다.
interface Color {
    final int RED = 1;
    final int GREEN = 2;
    final int BLUE = 3;
}
스쿨쥐의 생각 :
JDK 1.5 버전 이상이라면 enum을 사용하기를 권장합니다. 하위 호환성을 위해 enum을 쓸 수 없다면 열거타입을 나타내는 패턴을 적용하기 바랍니다. 자세한 내용은 Effective Java를 참조하시기 바랍니다.


15. 예외 클래스는 클래스 뒤에 Exception 키워드를 붙이세요.
class AccessException extends Exception {
:
}
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


16. 디폴트 인터페이스는 인터페이스 앞에 Default 키워드를 붙이세요.
class DefaultTableCellRenderer
implements TableCellRenderer {
:
}
Sun사에서도 이러한 코딩 룰을 지키고 있습니다.


17. Singleton 패턴을 구현한 클래스에서 인스턴스를 리턴하는 메서드의 이름은 getInstance 라고 붙이세요.
class UnitManager {
    private final static UnitManager instance_ = new UnitManager();
    private UnitManager() {
        ...
    }
    public static UnitManager getInstance() { // NOT: get() or instance() or unitManager() etc.
        return instance_;
    }
}
Sun사의 JDK는 이러한 관행을 일관적으로 지원하지는 않지만 자바 커뮤니티에서는 공통적으로 사용하고 있고, 또한 패턴이 적용되었다는 것을 쉽게 알려줄 수 있습니다.


18. Factory 패턴을 구현한 클래스에서 인스턴스를 리턴하는 메서드 앞에 new 키워드를 쓸 수 있습니다.
class PointFactory {
    public Point newPoint(...) {
        ...
    }
}
Factory 패턴으로 인스턴스를 제공할 경우 "new클래스명" 형태로 Factory 메서드를 제공할 수 있습니다. new Point() 생성자를 재구성하여 메서드로써 인스턴스를 만들어 준다고 생각하시면 됩니다.


19. 리턴 타입이 void인 메서드(procedures)의 경우에는 "무엇을 처리하는 지"를 이름에 쓰는 것이 좋으며, object 타입이나 일반 자료형과 같이 리턴 타입이 있는 메서드(functions)의 경우에는 "처리 후 무엇을 리턴하는 지"를 이름에 쓰는 것이 좋습니다.
예제 없음
메서드가 무엇을 의도하는지 명확하게 알려주어 가독성을 높혀줍니다.



Files


1. 탭(TAB)이나 페이지 구분(page break) 문자와 같은 특수한 문자들은 사용하지 마세요.
예제 없음
혼자만 쓰면 괜찮지만 여러 사람이 공동 작업할 경우 글꼴이나 탭 설정에 따라서 정렬이 다르게 나와서 가독성을 떨어뜨릴 수 있습니다.
스쿨쥐의 생각 :
이클립스의 경우 영역 지정 후 단축키를 통해(기본 단축키는 ctrl + i) 자신의 설정에 맞게 정렬을 할 수 있다.


2. 여러 라인으로 나눈 문장은 정렬을 잘 하세요.
totalSum = a + b + c +
d + e;
method(param1, param2,
param3);
setText ("Long line split" +
"into two parts.");
for (int tableNo = 0; tableNo < nTables;
tableNo += tableStep) {
    ...
}
일반적으로
    콤마(,) 뒤에서 분리합니다.
    연산자 뒤에서 분리합니다.
    이전 라인의 표현식 시작 부분에 맞춰서 정렬합니다.


Statements


Package and Import Statements


1. package 문은 파일의 첫번째 라인에 적어야 하며, 모든 파일은 특정 패키지에 소속되어야 합니다.
예제 없음
package 문의 위치는 Java 언어 코딩 표준에서 권고하고 있는 것입니다. 모든 파일들을 실제 패키지(디폴트 패키지보다는 이름이 있는 패키지)에 두는 것은 Java 객체 지향 프로그래밍 기법에 도움을 줍니다.


2. import 문은 반드시 package 문 뒤에 나와야 합니다. 또한 기본 패키지부터 정렬해야 하며, 관련 패키지들은 그룹핑하고 빈 라인을 삽입하여 일목요연하게 정리합니다.
import java.io.IOException;
import java.net.URL;

import java.rmi.RmiServer;
import java.rmi.server.Server;

import javax.swing.JPanel;
import javax.swing.event.ActionEvent;

import org.linux.apache.server.SoapServer;
import 문의 위치는 Java 언어 코딩 표준에서 권고하고 있는 것입니다. 많은 import 문들을 정렬해두면 편리하게 import 문들을 검토할 수 있고, 이를 통하여 현재 이 패키지가 어떤 용도로 설계되었는지를 쉽게 파악할 수 있습니다. 또한 import 문을 그룹핑하면 관련된 정보들을 공통의 유닛으로 관리할 수 있기 때문에 복잡도를 줄일 수 있습니다.

스쿨쥐의 생각 :
이클립스에서는 단축키(기본 단축키는 ctrl + shift + o)를 통해 쉽게 할 수 있습니다.


3. import 문을 사용할 때는 와일드 카드 문자(*)를 쓰지 마세요.
import java.util.List; // NOT: import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
와일드 카드 문자를 사용하게 되면 성능상에도 약간 영향이 있으며, 같은 이름의 클래스가 서로 다른 패키지에 있을 경우 문제가 발생할 수 있습니다. 또한 import 문만 보고도 어떠한 작업을 할 것인지 가독성을 높이기 위해서라도 와일드 카드를 쓰지 않는 것이 좋습니다.

스쿨쥐의 생각 :
2번과 마찬가지로 쉽게 할 수 있습니다. (동일 단축키)



Classes and Interfaces

Class 와 Interface 의 선언은 다음과 같은 방식으로 조직화하여 사용합니다.
1. Class/Interface 문서(javadoc 주석)
2. class 나 interface 선언문
3. 클래스 변수(static으로 선언된)들을 public, protected, package (접근제한자가 없는), private 순서대로 나열합니다.
4. 인스턴스 변수들을 public, protected, package (접근제한자가 없는), private 순서대로 나열합니다.
5. 생성자
6. 메소드(메소드에는 특별한 순서가 없습니다)
예제 없음
각각의 클래스/인터페이스 구성요소들의 등장 위치를 지키게되면, 현재 코드 상에 어떤 요소들이 다음에 등장할 것인지 예측할 수 있게되어 가독성이 좋아집니다.



Methods


1. 메서드의 지시자는 다음과 같은 순서로 사용한다.
<access> static abstract synchronized <unusual> final native
public static double square(double a); // NOT: static public double square(double a);
<access> 지시자는 public, protected, private 중 하나이고, <unusual> 부분은 volatile 과 transient 중 하나가 지정됩니다. 여기서 가장 중요한 점은 접근(access) 지시자가 맨 처음에 나타나야 한다는 것입니다. 사용할 수 있는 다양한 지시자들이 있지만, 이는 매우 중요한 사항이기 때문에 반드시 메소드 선언문에 반영되어야 합니다. 기타 지시자들의 순서는 덜 중요하지만 일관된 관례를 따르는 것이 바람직합니다.



Types


1. 형변환은 반드시 명시적으로 해주세요.
floatValue = (int) intValue; // NOT: floatValue = intValue;
형변환을 할 때 데이터가 손실될 경우가 있습니다. 명시적으로 하지 않는다면 이러한 것이 의도한 것인지 아니면 실수로 빠뜨린 것인지 알 수 없습니다.


2. 배열 지시자([])는 변수 이름 뒤가 아니라 타입 뒤에 붙이세요.
int[] a = new int[20]; // NOT: int a[] = new int[20]
배열은 타입의 한 속성이지 변수의 속성이 아니기 때문입니다. 어떤 이유에서인지 Java 에서는 두 가지 모두 문법적으로 허용하고 있습니다.



Variables


1. 변수는 선언된 지점에서 초기화하며, 가능한 사용범위를 최소화하여 선언한다.
예제 없음
이 규칙은 어느 시점에서든 변수가 유효한 값을 가진다는 것을 보장해줍니다. 종종 선언하는 시점에 변수에 유효한 값을 초기화하는 것이 불가능한 경우가 있습니다만, 그러한 경우에도 초기화하지 않은 상태로 내버려두는 것보다는 임의의 값이라도 사용하여 초기화 해두는 것이 좋습니다.
스쿨쥐의 생각 :
보통 숫자 형은 0 또는 0.0, 레퍼런스 형은 null을 주는 것이 일반적이다.


2. 변수는 한가지의 의미가 가져야지 여러 의미로 해석되어서는 안됩니다.
예제 없음
일관되고 유일한 의미를 부여함으로써 가독성을 향상시키고 더불어 부작용까지 예방할 수 있습니다.


3. 클래스 변수(static 변수)는 public으로 지정하지 마세요.
예제 없음
public 변수들은 Java 의 정보은닉과 캡슐화 컨셉에 위배됩니다. 대신 변수를 private 으로 선언하시고 이 변수를 접근할 수 있는 메소드를 사용하게 하십시오. 한 가지 예외적인 상황은 클래스가 데이터 구조로만 사용될 때입니다. 이 경우 클래스는 어떠한 행위(메소드)도 갖지 않고 오로지 데이터를 보관하는, 즉 C++ 에서의 struct 와 동일한 형태로 사용됩니다. 이 경우에는 클래스의 인스턴스 변수들을 public 으로 선언할 수도 있습니다.


4. 배열은 반드시 타입 뒤에서 정의하세요.
double[] vertex; // NOT: double vertex[];
int[] count; // NOT: int count[];
public static void main(String[] arguments)
public double[] computeVertex()
이유는 앞에서 설명한 것과 같습니다.


5. 변수의 생존 기간(사용 범위)를 가능한한 짧게 하세요.
예제 없음
변수의 생존 기간을 짧게 하면 영향을 주거나 부작용이 일어나는 것에 대해서 통제하기가 쉬워집니다.



Loops


1. for() 구문 안에는 반복에 사용되는 문장만 넣으세요.
sum = 0; // NOT: for (i = 0, sum = 0; i < 100; i++)
for (i = 0; i < 100; i++) // sum += value[i];
sum += value[i];
관리하기가 편해지고 가독성을 향상시킬 수 있습니다. 무엇이 반복문을 제어하고 무엇이 반복문 내에서 사용되는지 분명하게 하세요.


2. 반복문에 사용되는 변수는 반복문 바로 앞에서 초기화 하세요.
isDone = false; // NOT : bool isDone = false;
while (!isDone) { // :
: // while (!isDone) {
} // :
// }
설명 없음


3. do-while 문은 되도록 쓰지 마세요.
예제 없음
do .... while 문을 사용한 모든 문장은 while 문을 사용하여 동일하게 바꾸어 작성할 수 있습니다. 그렇게 하면 가독성이 더욱 좋아집니다.


4. 반복문 내에서 continue나 break 문을 되도록 쓰지 마세요.
예제 없음
continue나 break는 꼭 필요할 때만 쓰세요. 너무 많이 쓰면 가독성이 떨어집니다.



Conditionals


1. 복잡한 조건식은 피하세요. 대신 임시로 boolean 변수를 사용하세요.
bool isFinished = (elementNo < 0) || (elementNo > maxElement);
bool isRepeatedEntry = (elementNo == lastElement);
if (isFinished || isRepeatedEntry) {
:
}
// NOT:
if ((elementNo < 0) || (elementNo > maxElement) || elementNo == lastElement) {
:
}
디버깅 할 때도 편해지며, 의미가 더 정확하게 전달되어 가독성이 좋아집니다.


2. if문에서 일반적인 상황은 if 부분에 위치시키고, 예외적인 상황은 else 부분에 위치시키세요.
boolean isOk = readFile(fileName);
if (isOk) {
:
} else {
:
}
일반적인 처리 흐름과 예외상황 처리 흐름을 불명확하지 않게 하십시오. 이 지침은 가독성과 성능 모두에 영향을 미치는 중요한 사항입니다.


3. 조건식에 실행문을 적지 마세요.
InputStream stream = File.open(fileName, "w");
if (stream != null) {
:
}
// NOT:
if (File.open(fileName, "w") != null)) {
:
}
조건식에 실행문을 사용하는 것은 간편하지만 읽기가 매우 어려워집니다. 이 지침은 Java 에 발을 처음으로 들여놓는 개발자들에게 특히 강조하고 싶은 지침입니다.



Miscellaneous


1. 코드 상에 매직 넘버를 쓰지 마세요. 0과 1 이외의 숫자는 상수로 정의해서 쓰는 것이 좋습니다.
private static final int TEAM_SIZE = 11;
:
Player[] players = new Player[TEAM_SIZE]; // NOT: Player[] players = new Player[11];
좀 더 의미를 명확하게 하게 할 수 있으며, 재사용성도 좋아집니다.


2. 실수값 상수는 항상 소수점과 최소 소수점 이하 한자리 숫자를 사용하여 지정해야 합니다.
double total = 0.0; // NOT: double total = 0;
double speed = 3.0e8; // NOT: double speed = 3e8;
double sum;
:
sum = (a + b) * 10.0;
특별한 경우에 정수와 실수가 동일한 값을 갖는다 하더라도 기본적으로 특성이 다르기 때문에 구별하는 것이 좋습니다.
또한 위 마지막 라인의 예제에서 살펴볼 수 있듯이, 값을 할당받은 변수(sum)는 다른 변수의 타입을 알 수 없다고 하더라도 명백하게 실수값을 계산해 낸다는 것을 보장할 수 있습니다.


3. 실수값 상수는 항상 정수부에 숫자를 사용하여 지정해야 합니다.
double total = 0.5; // NOT: double total = .5;
Java 에서 사용하는 숫자와 표현식은 수학식 표기법에서 차용하였으므로, 프로그래머는 가능한 수학적 표기법을 준수하는 것이 바람직합니다. 실제로 .5 (간편한 표기) 보다 0.5 (수학적 표기) 가 더 읽기에 쉽습니다. 이 수식에서 정수 5 가 함께 사용되는 경우에는, .5 와 정수 5 를 혼동하여 잘못된 연산을 초래할 가능성이 높아지게 됩니다.


4. static 변수나 메서드는 인스턴스 변수를 통해서 호출하지 말고, 클래스 이름을 통해서 접근해야 합니다.
Thread.sleep(1000); // NOT: thread.sleep(1000);
특정 인스턴스에 대해서 독립적이라는 것을 강조하기 위해서 사용합니다. 즉, static을 사용하고 있다는 것을 알려주어 가독성을 높여줍니다.




Layout and Comments


Layout


1. 블락 레이아웃은 다음 예제를 따르세요.
while (!done) {
    doSomething();
    done = moreToDo();
}
while (!done)
{
    doSomething();
    done = moreToDo();
}
첫번째나 두번째 방법 중 아무 것이나 써도 됩니다.


2. 클래스와 인터페이스 선언은 다음 예제를 따르세요.
class Rectangle extends Shape
implements Cloneable, Serializable {
...
}
extends 키워드는 클래스나 인터페이스 뒤에 붙이시고, implements 키워드는 다음 라인에 적으세요.


3. 메서드 선언은 다음 예제를 따르세요.
public void someMethod()
throws SomeException
{
...
}
throws 키워드는 다음 라인에 적으세요.


4. if문이나 반복문의 경우 한 줄만 있더라도 블락을 꼭 써주세요.
if(condition) {
    //statement;
}
// NOT:
if(condition)
//statement;
한 줄이라도 블락을 쓰는 쪽이 가독성이 좋습니다. 또한 짧은 구문이라면 한줄로 적으셔도 괜찮습니다.



White Space


1. 논리 단위로 빈 라인을 넣어주세요.
// Create a new identity matrix
Matrix4x4 matrix = new Matrix4x4();

// Precompute angles for efficiency
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);

// Specify matrix as a rotation transformation
matrix.setElement(1, 1, cosAngle);
matrix.setElement(1, 2, sinAngle);
matrix.setElement(2, 1, -sinAngle);
matrix.setElement(2, 2, cosAngle);

// Apply rotation
transformation.multiply(matrix);
마치 국어에서 문단을 나누듯이 논리 단위가 바뀔 때마다 빈 라인을 넣어주세요.


2. 변수와 데이터 타입을 구분해서 맞추세요.
TextFile file;
int nPoints;
double x, y;

이런 식으로 정렬하면 가독성이 좋아집니다.


3. 구문(statement)는 가독성이 좋게 정렬하세요.
if (a == lowValue) compueSomething();
else if (a == mediumValue) computeSomethingElse();
else if (a == highValue) computeSomethingElseYet();

value = (potential * oilDensity) / constant1 +
(depth * waterDensity) / constant2 +
(zCoordinateValue * gasDensity) / constant3;

minPosition = computeDistance(min, x, y, z);
averagePosition = computeDistance(average, x, y, z);

switch (phase) {
    case PHASE_OIL : text = "Oil"; break;
    case PHASE_WATER : text = "Water"; break;
    case PHASE_GAS : text = "Gas"; break;
}
가독성이 좋아진다면 어느 정도 코딩 룰을 바꾸어 적용해도 괜찮습니다.



Comments


1. 프로젝트 진행시 다음 주석 스타일을 따릅니다.
    package example;

    import java.util.ArrayList;
    import java.util.Collection;

    /**
    * JavaDoc 테스트용 클래스입니다.
    *
    * @author 최영목
    * @since 2008.04.03
    * @version 1.0
    * <pre>
    * 2008.04.03 : 최초 작성
    * 2008.04.04 : 컬렉션 추가
    * </pre>
    */
    public class DocExample {

        private Collection<String> userNames;

        public DocExample(String name) {
            userNames = new ArrayList<String>();
        }

        /**
        * 유저 이름을 삭제하는 메서드
        *
        * @param name 삭제할 유저 이름
        * @return 유저가 존재해서 삭제가 되면 true를 리턴하고, 유저가 존재하지 않으면 false를 리턴한다.
        * @throws Exception 그냥 테스트용으로 했음.
        */
        public boolean removeUserName(String name)
        throws Exception {
            return userNames.remove(name);
        }

        /**
        * 어노테이션과 함께 쓸 때를 위한 예제 메서드
        *
        * @return 그냥 텍스트가 출력됨
        */
        @Override
        public String toString() {
            return "테스트용입니다.";
        }
    }
이클립스의 기능에 의존하여 코드 가독성을 높이기 위해 평소에는 주석을 숨겨두고 필요할 때만 꺼내씁니다. 제너릭 타입은 반드시 명시를 해야합니다.


2. JavaDoc 생성시 package 설명을 위해 각 패키지에 package-info.java 파일을 만듭니다.
    /**
    * 설명입니다.
    */
    package example;
반드시 /** */ 주석이 먼저 와야하며 뒤에 패키지 선언이 와야 합니다. 또한 이 파일은 1.5에서부터 사용가능하며, 이전 버전은 doc 폴더 내의 각 패키지에 package.html 또는 package-info.html 파일을 만들어서 넣어야 합니다.



참고 : https://www.lesstif.com/pages/viewpage.action?pageId=30277941

Chocolatey  는 Mac OS X 의 Homebrew 나 Linux 의 yum, apt-get 같은 역할을 수행하는 NuGet 기반의 윈도우용 패키지 관리자이다.

 

설치

cmd.exe 를 열고 다음 명령어 실행

@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

또는 powershell 을 실행한 후에 파워쉘 프롬프트에서 설치 명령어 입력

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

 

다른 경로에 설치할 경우 ChocolateyInstall 환경 변수에 설치할 폴더를 지정하고 수동으로 폴더 생성

set ChocolateyInstall=d:\devel\choco

 

패키지 검색/목록 보기

https://chocolatey.org/packages 에서 패키지 검색하거나 cmd 에서 다음 명령어 입력

choco search nodejs

 

list

전체 패키지 목록

choco list

 

로컬에 설치된 패키지

choco list --local-only

 

info

패키지에 대한 자세한 정보를 보려면 search 에 아래 옵션 추가

choco search <pkgname> --exact --detailed

또는 위 명령의 축약어인 info 명령어 사용

choco info nodejs

 

설치

choco install nodejs

삭제

choco uninstall nodejs

 

Ref


출처 : http://forum.falinux.com/zbxe/index.php?document_srl=807633&mid=lecture_tip

참고 : http://kimseunghyun76.tistory.com/381

Java API : http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-


Java에서 어플리케이션을 종료 될때 뭔가를 작업 하고 싶을 경우에 addShutdownHook이란 걸 사용 할 수 있습니다.


addShutdownHook은 VM에서 사라지기 전에 마지막 유언을 할 수 있게 해줍니다.^^;


 Ctrl+C, 또는 kill명령으로 강제 종료가 될때도 실행이 됩니다. 위에서 말했듯 마지막 유언을 남기기 위해....


그럼 샘플 소스입니다.


[샘플 소스]

public class ShutdownHookDemo {

	static class ByeMessage extends Thread {

		public void run() {
			System.out.println("프로그램이 종료 되었습니다.!!!!");
		}
	}

	public static void main(String[] args) {

		// 자바가 종료 될때 실행 시킬 쓰레드를 등록 시킴.
        Runtime.getRuntime().addShutdownHook(new ByeMessage());
        
        try {
	        // 프로그램 시작 메세지
	        System.out.println("프로그램 시작!!!!");
	
	        // 3초간 대기 함.
	        System.out.println("대기 3초!!!");
	        Thread.sleep(3000);
	
	        // 프로그램 종료
	        System.out.println("프로그램 종료!!!");
	        
        } catch(Exception e) {
        	e.printStackTrace();
        }
	}
}


- 익명 (
anonymous) class 사용

public class ShutdownHookDemo {

	public static void main(String[] args) {

		// 자바가 종료 될때 실행 시킬 쓰레드를 등록 시킴.
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("프로그램이 종료 되었습니다.!!!!");
            }
        });
        
        try {
	        // 프로그램 시작 메세지
	        System.out.println("프로그램 시작!!!!");
	
	        // 3초간 대기 함.
	        System.out.println("대기 3초!!!");
	        Thread.sleep(3000);
	
	        // 프로그램 종료
	        System.out.println("프로그램 종료!!!");
	        
        } catch(Exception e) {
        	e.printStackTrace();
        }
	}
}




[실행]

shutdown_1.PNG 



addShutdownHook에는 쓰레드가 등록 됩니다.


샘플에는 대기를 3초로 하고 이클립스에서 실행 시켜서 정상적으로 종료 하도록 하였지만,


 커멘드창에서 프로그램을 실행 시킨후, 3초가 되기전에 Ctrl+C를 눌러 종료 시키면 


"프로그램이 종료 되었습니다.!!!!"라는 메세지가 뜨고 "프로그램 종료!!!!"라는 메세지는 뜨지 않습니다.




* addShutdownHook 사용 시 주의점

- Shutdown hooks의 개수 : 제한 없다.

- Shutdown hook을 붙여야 하는 시점은 언제든지 붙여도 된다. 
  단순한 이야기 이지만, 셧다운 되기 전에 어떤 인스턴스든지 붙여놔야 겠지.

- 같은 hook을 다시 붙이는 것은 할수 없다."Hook previously rfegisted"라는 IllegalArgumentException이 발생한답니다.

- De-register a Hook : Runtime.removeShutdownHook 메소드를 호출하는 것 만으로, 훅을 제거 할 수 있다. 

  하지만 익명 내부 클래스를 사용해서 셧다운을 대부분 등록하는데, 이 것을 사용할수 있는 어떤 참조도 가질수 없기 때문에, 우리는 익명 내부 클래스를 우리가 제거할지 모르는 훅들에 대해서는 사용하면 안된다. 

removeShutdownHook 메소드에 이 참조를 전달 해야하기 때문이랍니다.

- 동시성을 유지하는 것을 지켜요 : 앞서 말한대로.

- Shutdown Hook의 Reliability(신뢰도) : JVM은 최선을 다해 실행하겠지만, 모두 다 실행된다고 보장 할 수 없다고 한다. 

- Hook들에 의한 시간 소비를 유의해라 : 셧다운 할 때 시간 소비 하지 않는것이 중요하다. 



윈도우에서 cURL 설치 및 사용법


참고 : http://ilhee.tistory.com/25

Linux curl 참고 : http://tyboss.tistory.com/entry/Linux-curl-%EC%82%AC%EC%9A%A9%EB%B2%95


다운로드 : https://curl.haxx.se/download.html

목록 중 Win64 - Generic 항목에서 7zip으로 되어 있는 항목을 받는다.

압축을 해제하면 하위 경로에 curl.exe 파일이 있거나 하위 디렉토리 중 bin 디렉토리를 확인하면 있다.


cmd 창에서 해당 경로로 들어간 후 curl --help 로 확인가능하다.




Oracle 참고 : http://docs.oracle.com/cd/B28359_01/java.111/b31224/urls.htm#BEIDHCBA
                  https://docs.oracle.com/cd/B12037_01/network.101/b10776/tnsnames.htm


오라클 SID, Service Name 차이 | Oracle개념용어정리

--------------------------------------------------------------------


지금껏 오라클을 사용하면서도 SID와 Service Name은 거의 구분해서 사용하지 않았다.

덕분에 최근까지는 SID와 Service의 차이를 인식하지 못하고 사용해 왔다.

사실 일반적인 테스트 환경이나 소규모의 경우 한개의 DB서버에 한개의 인스턴스만 사용한다.

이런 환경에서는 SID와 Service Name을 구분할 필요가 없었던것.

단순히 구분짓자면 이렇게 말할수 있다.

SID = DB 하나의 인스턴스

Service Name = 여러개의 인스턴스를 모아 하나의 서버 혹은 시스템을 구성한것

쉽게 예를 들어보자.

서버 한대에 인스턴스를 여러개 생성하여 orcl1, orcl2 로 각각 생성했다고 하자.

각각의 인스턴스는 orcl1, orcl2 라는 SID를 갖게 된다.

해당 서버에서 두개의 인스턴스를 묶어 사용할경우, orcl 이라는 Service Name을 갖을수 있다.

이외에도 서버 두대에 설치하여 각각 미러링 처리하여 동일한 서버인것 처럼 활용할경우

각각의 서버는 서로다른 SID를 갖게 되지만 Service Name을 동일하게 하여 같은 서버 처럼 활용할수 있다

[출처] 오라클 SID와 Service Name의 차이|작성자 도토리


DBMS 서버를 기동하기 위해서는 DB서버가 기동하는 서버의 IP 그리고

DB서버가 접속을 받아들이기 위한 프로토콜에 대한 정의가 필요합니다.

오라클의 경우 인스턴스가 서버 역할을 하는 DBMS프로세스인데,

인스턴스가 기동할때 SID를 필요로 합니다.

즉 SID는 인스턴스의 이름인 셈이지요.

SID가 필요한 이유는 한 서버(H/W)에 여러개의 인스턴스가 기동될 수 있으므로

구별하는 태그가 필요하겠지요. 따라서 SID는 DB서버에서 필요한 정보입니다.

SID정보는 환경변수와, LISTENER.ORA라는 파일에서 정의 됩니다.

DB에 접속하는 클라이언트 프로그램의 경우 접속하고자 하는 오라클 인스턴스 정보를

필요로 합니다. 클라이언트 프로그램이 접속하는데 필요한 정보는 서버IP, 오라클SID, 접속프로토콜 
같은 정보가 필요하지요. 이러한 정보를 묶어서 서비스명으로 대표하고, 
이 서비스명으로 클라이언트 프로그램이 서버에 접속하는데 사용합니다.

이 정보는 클라이언트쪽의 TNSNAMES.ORA라는 파일에 정의 되어있습니다.

출처 : 네이버 지식 검색 : 정확히는 모름(?)


instance, instantiate ; 인스턴스, 인스턴스화

--------------------------------------------------------------------

인스턴스는 추상화 개념 또는 클래스 객체, 컴퓨터 프로세스 등과 같은 템플릿이 실제 구현된 것이다. 
인스턴스화는 클래스 내의 객체에 대해 특정한 변형을 정의하고, 이름을 붙인 다음, 그것을 물리적인 
어떤 장소에 위치시키는 등의 작업을 통해, 인스턴스를 만드는 것을 의미한다.

1. 몇몇 필자들은, 객체지향 프로그래밍에서 클래스를 인스턴스화 한다는 것이, 클래스의 구체적인 인스턴스, 
즉 객체를 만드는 것이라고 말한다. 그 객체는 컴퓨터 내에서 실행시킬 수 있는 실행 파일이다.

2. 객체지향 프로그램 언어인 자바에서는, 클래스로부터 인스턴스화된 객체를, 객체라는 말 대신에 
역시 클래스라고 부름으로써 많은 사용자들을 혼란스럽게 한다. 즉 자바에서는, 특정한 클래스를 
만들기 위해 클래스를 인스턴스화하며, 그것 역시 컴퓨터 내에서 동작하는 실행 파일이다.

3. 객체지향 프로그래밍 개념이 나오기 이전의 데이터 모델링이나 프로그래밍에서는, 인스턴스화라는 것이 
관계형 데이터베이스 테이블 내에 새로운 엔트리를 만듦으로써 추상화된 객체로부터 실재(데이터가 들어있는) 
객체를 만드는 것도, 한 가지 용례였다.



======================================================================


오라클(Oracle) SID 및 DB_NAME 확인 방법


출처 : http://pangate.com/665


jdbc 에서 thin 드라이버로 오라클에 접속할 때는 SID를 알아야 한다. 
최근에는 SID로 직접 기술하여 접근하는 것보다는 service name 이라는 것을 tnsname.ora 파일에 지정해 놓고 이것을 사용한다. 아무래도 SID가 공개되는 것이 문제가 될 수 있을 것이다.  

<tnsname.ora 의 작성 예> 

PRODDB = 
  (DESCRIPTION = 
    (ADDRESS_LIST = 
      (ADDRESS = (PROTOCOL = TCP)(HOST = 152.25.24.15)(PORT = 1521))
    )
    (CONNECT_DATA = 
      (SERVICE_NAME = ORCL)
    )
  )

PRODDB = 
  (DESCRIPTION = 
    (ADDRESS_LIST = 
      (ADDRESS = (PROTOCOL = TCP)(HOST = 152.25.24.15)(PORT = 1521))
    )
    (CONNECT_DATA = 
      (SID = ORCL)
    )
  )



서비스명과 인스턴스명과 데이타베이스명과 SID는 서로 비슷한 듯 하면서 약간 다르다. 

1. 오라클 데이타베이스명을 확인하는 방법

SELECT NAME, DB_UNIQUE_NAME FROM v$database;

2. 오라클 SID를 확인하는 방법

SELECT instance FROM v$thread;



일반적인 경우 데이타베이스가 하나만으로 구성 되어 있다면 데이타베이스명이 SID가 된다. 하지만 RAC 로 구성하여 데이타베이스 두개가 동시 가동되는 경우라면 이 SID 가 서로 다를 수 있기 때문에 중복 확인해야 한다.

JDBC 로 접속할 때 url 정보 작성 방법 : 
    url=jdbc:oracle:thin:@ip주소:포트:SID
   (url=jdbc:oracle:thin:@192.168.20.1:1521:ORCL)

아래의 예제에서 보면 RAC로 묶여 있는 경우 DATABASE NAME 과 실제 INSTANCE NAME 은 서로 다를 수 있다. 데이타베이스명은 ORCL 이지만 인스턴스명은 ORCL1 과 ORCL2 로 이름이 다름.  thin 드라이브 URL 에서는 이 인스턴스명을 사용해야 한다.  

사용자명 입력: system/manager@PRODDB

다음에 접속됨:
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
With the Real Application Clusters option

SQL> SELECT NAME, DB_UNIQUE_NAME FROM V$DATABASE;

NAME               DB_UNIQUE_NAME
------------------ ------------------------------------------------------------
ORCL               ORCL

SQL> SELECT INSTANCE FROM V$THREAD;

INSTANCE
--------------------------------------------------------------------------------
ORCL1
ORCL2

SQL>




======================================================================


SID
jdbc:oracle:thin:@서버IP:서버Port:SID
jdbc:oracle:thin:@//hostname:port:sid


Service Name
jdbc:oracle:thin:@서버IP:서버Port:ServiceName
jdbc:oracle:thin:@//hostname:port/serviceName


Thin 사용
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=서버IP)(PORT=서버Port)))(CONNECT_DATA=(SERVICE_NAME=ServiceName)))



출처 : http://gent.tistory.com/39


PL/SQL(Procedure, Package)을 사용하다 보면 동적으로 쿼리(Query)를 생성하거나 텍스트(text) 쿼리를 입력 받아서 실행해야하는 경우가 있다다음 두가지 방법을 적절히 사용하면 좋은 결과를 얻을수 있다.

 

EXECUTE IMMEDIATE : Inset, Update, Delete 구문을 실행하거나 Select 구문을 실행 시 INTO를 사용하여 단일 값을 리턴 받을 때 사용

 

OPEN-FOR : Select 구문을 실행 시 Cursor를 리턴 받을 때 사용

 

주의 바인드 변수(:) 사용 시 쿼리 내부에서 변수명은 의미가 없고 변수 순서, 개수가 USING의 변수 순서, 개수와 일치해야 한다. 바인드 변수가 없다면 USING는 생략가능.

 

1. EXECUTE IMMEDIATE (INSERT, UPDATE, DELETE  등 구문 실행)

 

CREATE OR REPLACE PROCEDURE

PC_SET_HOLIDAY ( in_hldy_dte in date

, in_hldy_nm in varchar2

, in_use_yn in varchar2)

IS

v_query varchar(1000);

d_sysdate date;

BEGIN

BEGIN

-- 단일 값을 리턴받을때

EXECUTE IMMEDIATE 'SELECT SYSDATE FROM DUAL' INTO d_sysdate;

END;

 

v_query := v_query || 'INSERT INTO HOLIDAY';

v_query := v_query || ' VALUES(:1,:2,:3,:4)';

 

BEGIN

-- INSERT, UPDATE, DELETE 구문 실행

EXECUTE IMMEDIATE v_query

USING in_hldy_dte, in_hldy_nm, in_use_yn, d_sysdate;

END;

END;

 

 

2. OPEN-FOR (CURSOR를 리턴 받을 때)

 

CREATE OR REPLACE PROCEDURE

PC_GET_HOLIDAY ( in_fromdate in varchar2

, in_todate in varchar2

, out_cursor out SYS_REFCURSOR)

IS

v_query varchar(1000);

BEGIN

v_query := v_query || 'SELECT HLDY_DTE, HLDY_NM';

v_query := v_query || ' FROM HOLIDAY';

v_query := v_query || ' WHERE HLDY_DTE BETWEEN :in_fromdate';

v_query := v_query || ' AND :in_todate';

 

BEGIN

-- CURSOR를 리턴 받을때

OPEN out_cursor FOR v_query

USING in_fromdate, in_todate;

END;

END;

 

 

 

 



-- SELECT 1건 샘플

DECLARE
    TABLE_NAME USER_TABLES.TABLE_NAME%TYPE;

BEGIN
    EXECUTE IMMEDIATE 'SELECT TABLE_NAME FROM USER_TABLES WHERE ROWNUM = 1' INTO TABLE_NAME;
    DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || TABLE_NAME);

END;
/


-- SELECT CURSOR 샘플

DECLARE
    V_QUERY VARCHAR2(4000);
    R USER_TABLES%ROWTYPE;
    C1 SYS_REFCURSOR;

BEGIN
    V_QUERY := V_QUERY || 'SELECT TABLE_NAME';
    V_QUERY := V_QUERY || '     , TABLESPACE_NAME';
    V_QUERY := V_QUERY || '  FROM USER_TABLES';
    V_QUERY := V_QUERY || ' WHERE ROWNUM < :ROW_CNT';

    OPEN C1 FOR V_QUERY USING 10;

    LOOP                                                            
        FETCH C1 INTO R.TABLE_NAME, R.TABLESPACE_NAME;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME || ', TABLESPACE NAME : ' || R.TABLESPACE_NAME);
    END LOOP;

    CLOSE C1;

END;
/




참고 : http://blog.kjslab.com/20


1. 커서의 내용을 미리 정의 해 놓고 사용하는 방법

DECLARE

  CURSOR C1 IS
    SELECT TABLE_NAME
         , TABLESPACE_NAME
         , STATUS
         , PCT_FREE
      FROM USER_TABLES;

BEGIN

  FOR R IN C1 LOOP
    DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME || ', TABLESPACE NAME : ' || R.TABLESPACE_NAME);
  END LOOP;END;


-- ROW 단위로 변수 정의

DECLARE
  R USER_TABLES%ROWTYPE;
  C1 SYS_REFCURSOR;

BEGIN
  OPEN C1 FOR
   SELECT *
      FROM USER_TABLES;

    LOOP
        FETCH C1 INTO R;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME);
    END LOOP;
   
    CLOSE C1;

END;
/


-- ROW 단위로 변수 정의 후 COLUMN 단위로 사용

DECLARE
    R USER_TABLES%ROWTYPE;
    C1 SYS_REFCURSOR;

BEGIN
  OPEN C1 FOR
   SELECT TABLE_NAME
        , TABLESPACE_NAME
      FROM USER_TABLES;

    LOOP
        FETCH C1 INTO R.TABLE_NAME, R.TABLESPACE_NAME;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME || ', TABLESPACE NAME : ' || R.TABLESPACE_NAME);
    END LOOP;
    
    CLOSE C1;

END;



-- COLUMN 단위로 변수 정의

DECLARE
  TABLE_NAME USER_TABLES.TABLE_NAME%TYPE;
  C1 SYS_REFCURSOR;
 
BEGIN
  OPEN C1 FOR
   SELECT TABLE_NAME
      FROM USER_TABLES;

     
    LOOP
        FETCH C1 INTO TABLE_NAME;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || TABLE_NAME);
    END LOOP;
    
    CLOSE C1;

END;


-- TYPE 정의

DECLARE
    TYPE V_TYPE IS RECORD (TABLE_NAME USER_TABLES.TABLE_NAME%TYPE, TABLESPACE_NAME USER_TABLES.TABLESPACE_NAME%TYPE);
    R V_TYPE;
    C1 SYS_REFCURSOR;


BEGIN
  OPEN C1 FOR
   SELECT TABLE_NAME
        , TABLESPACE_NAME
      FROM USER_TABLES;

    LOOP
        FETCH C1 INTO R;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME || ', TABLESPACE NAME : ' || R.TABLESPACE_NAME);
    END LOOP;

   
    CLOSE C1;

END;




2. 커서 변수를 미리 만들어 놓고 불러서 사용하는 방법

DECLARE
   R USER_TABLES%ROWTYPE;
   C1 SYS_REFCURSOR;

BEGIN
   OPEN C1 FOR
      SELECT *
        FROM USER_TABLES;

   LOOP                                                            
      FETCH C1 INTO R;
      EXIT WHEN C1%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || R.TABLE_NAME || ', TABLESPACE NAME : ' || R.TABLESPACE_NAME);
   END LOOP;

   CLOSE C1;
END;
/



3. 동적으로 커서를 생성해서 사용하는 방법

BEGIN
   FOR C1 IN (
    SELECT TABLE_NAME
         , TABLESPACE_NAME
      FROM USER_TABLES
   )
   LOOP
      DBMS_OUTPUT.PUT_LINE('TABLE NAME : ' || C1.TABLE_NAME || ', TABLESPACE NAME : ' || C1.TABLESPACE_NAME);
   END LOOP;
END;





+ Recent posts