반응형
반응형


정리가 잘되어있어서 가져와봤습니다.



출처 : http://ww.okjsp.pe.kr/seq/151426

출처 : http://blog.naver.com/overa4/110100006585

출처 : http://blog.naver.com/ballkiss/30025300601

출처 : http://blog.daum.net/gksdy2000/8006521

출처 : http://stophyun.tistory.com/62

MS-SQL 


 ** SQL문은 대소문자를 구분하지 않지만 데이타는 대문자와 소문자를 구분한다
    주석을 다는 방법은 /* 주석 */ 이거나 한줄만 주석 처리를 할 경우는 문장 맨앞에 --를 붙인다

 ** 각각의 데이타베이스의 SYSOBJECTS 테이블에 해당 데이타베이스의 모든 정보가 보관되어 있다
    SYSOBJECTS의 TYPE 칼럼으로 'U'=사용자 테이블, 'P'=저장 프로시저, 'K'=프라이머리 키, 'F'=포린 키,
    'V'=뷰, 'C'=체크 제약등 오브젝트 이름과 정보를 알 수 있다

 

 

 데이타 검색


  USE 데이타베이스명     /* USE 문을 사용한 데이타베이스 선택 */
  SELECT * FROM 데이블명     /* 모든 칼럼 불러오기 */
  SELECT TOP n * FROM 테이블명    /* 상위 n개의 데이타만 가져오기 */
  SELECT 칼럼1, 칼럼2, 칼럼3 FROM 테이블명  /* 특정 칼럼 가져오기 */
  SELECT 칼럼1 별명1, 칼럼2 AS 별명2 FROM 테이블명 /* 칼럼에 별명 붙이기 */
  SELECT 칼럼3 '별  명3' FROM 테이블명                    /* 칼럼 별명에 스페이스가 들어갈 경우는 작은따옴표 사용 */
  SELECT DISTINCT 칼럼 FROM 테이블명                      /* 중복되지 않는 데이타만 가져오기 */
   ** 데이타는 오름차순으로 재배열된다
      DISTINCT를 사용하면 재배열이 될때까지 데이타가 리턴되지 않으므로 수행 속도에 영향을 미친다 */
  SELECT * FROM 테이블명 WHERE 조건절                     /* 조건에 해당하는 데이타 가져오기 */
   ** 조건식에 사용하는 비교는 칼럼=값, 칼럼!=값, 칼럼>값, 칼럼>=값, 칼럼<값, 칼럼<=값이 있다
      문자열은 ''(작은따옴표)를 사용한다
      날짜 비교를 할때는 'yy-mm-dd' 형식의 문자열로 한다(날짜='1992-02-02', 날짜>'1992-02-02')
  SELECT * FROM 테이블명 WHERE 칼럼 BETWEEN x AND y       /* 칼럼이 x>=와 y<=사이의 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼 IN (a, b...)          /* 칼럼이 a이거나 b인 데이타 가져오기 */


  SELECT * FROM 테이블명 WHERE 칼럼 LIKE '패턴'           /* 칼럼이 패턴과 같은 데이타 가져오기 */
   ** 패턴에 사용되는 기호는 %, _가 있다
      'k%'(k로 시작되는), '%k%'(중간에 k가 있는), '%k'(k로 끝나는)
      'p_'(p로 시작하는 2자리), 'p___'(p로 시작하는 4자리), '__p'(3자리 데이타중 p로 끝나는)

Like 패턴 주의점

more..


  SELECT * FROM 테이블명 WHERE 칼럼 IS NULL               /* 칼럼이 NULL인 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼 NOT BETWEEN x AND y   /* 칼럼이 x와 y 사이가 아닌 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼 NOT IN (a, b...)      /* 칼럼이 a나 b가 아닌 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼 NOT LIKE '패턴'       /* 칼럼이 패턴과 같지 않은 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼 IS NOT NULL           /* 칼럼이 NULL이 아닌 데이타 가져오기 */
  SELECT * FROM 테이블명 WHERE 칼럼>=x AND 칼럼<=y        
  SELECT * FROM 테이블명 WHERE 칼럼=a or 칼럼=b
  SELECT * FROM 데이블명 WHERE 칼럼1>=x AND (칼럼2=a OR 칼럼2=b)
   ** 복수 조건을 연결하는 연산자는 AND와 OR가 있다
      AND와 OR의 우선순위는 AND가 OR보다 높은데 우선 순위를 바꾸고 싶다면 ()을 사용한다
  SELECT * FROM 테이블명 ORDER BY 칼럼                    /* 칼럼을 오름차순으로 재배열하기 */
  SELECT * FROM 테이블명 ORDER BY 칼럼 ASC                
  SELECT * FROM 테이블명 ORDER BY 칼럼 DESC               /* 칼럼을 내림차순으로 재배열하기 */
  SELECT * FROM 테이블명 ORDER BY 칼럼1 ASC, 칼럼2 DESC   /* 복수 칼럼 재배열하기 */
  SELECT * FROM 테이블명 ORDER BY 1 ASC, DESC 3           /* 칼럼 순서로 재배열하기 */ 
          ** 기본적으로 SELECT 문에서는 출력순서가 보증되지 않기 때문에
      데이타의 등록 상태나 서버의 부하 상태에 따라 출력되는 순서가 달라질 수 있다
      따라서 출력하는 경우 되도록이면 ORDER BY를 지정한다
   ** 칼럼 번호는 전체 칼럼에서의 번호가 아니라 SELECT문에서 선택한 칼럼의 번호이고 1부터 시작한다

 

 연산자
  ** 1순위는 수치 앞에 기술되는 + - 같은 단항 연산자
     2순위는 사칙 연산의 산술 연산자인  * / + -
     3순위는 = > 비교 연산자
     4순위는 AND OR 같은 논리 연산자
     ()을 붙이면 우선 순위를 바꿀수 있다

  1. SELECT 문의 연산 
     SELECT 칼럼1, 칼럼2, 칼럼3+칼럼4 AS '별명' FROM 테이블명 
  

 2. ORDER BY 구의 연산 
     SELECT 칼럼1, 칼럼2, 칼럼3+칼럼4 AS '별명' FROM 테이블명 ORDER BY 칼럼3+칼럼4 DESC
     SELECT 칼럼1, 칼럼2, 칼럼3+칼럼4 AS '별명' FROM 테이블명 ORDER BY 3 DESC

  3. WHERE 구의 연산 
     SELECT 칼럼1, 칼럼2, 칼럼3+칼럼4 AS '별명' FROM 테이블명 WHERE 칼럼2>=(칼럼3+칼럼4)

  4. NULL 연산 
     SELECT 칼럼1, 칼럼2, ISNULL(칼럼3, 0) + ISNULL(칼럼4, 0) AS '별명' FROM 테이블명
   ** 수치형 데이타와 NULL값과의 연산 결과는 항상 NULL이다
      만약 NULL 값을 원치 않으면 ISNULL(칼럼, 기준값) 함수를 사용해서 기준값을 변환시킨다 

  5. 날짜 연산  

     SELECT GETDATE()                                    /* 서버의 현재 날짜를 구한다 */

     SELECT 날짜칼럼, 날짜칼럼-7 FROM 테이블명
     SELECT 날짜칼럼, 날짜칼럼+30 FROM 테이블명
     SELECT 날짜칼럼, DATEDIFF(day, 날짜칼럼, GETDATE()) FROM 테이블명
   ** 날짜의 가산과 감산은 + -로 할 수 있다
      날짜와 날짜 사이의 계산은 DATEDIFF(돌려주는값, 시작날짜, 끝날짜) 함수를 사용한다

  6. 문자 연산
     SELECT 칼럼1 + 칼럼2 FROM 테이블명
     SELECT 칼럼 + '문자열'  FROM 테이블명
     SELECT 칼럼1 + '문자열' + 칼럼2 FROM 테이블명
   ** 기본 연결은 문자와 문자이고 문자와 숫자의 연결은 CONVERT 함수를 사용해야 한다

 

 함수
  1. 수치 함수
     ROUND(수치값, 반올림위치)            /* 반올림 및 자르기 */
     ABS(수치 데이타)                     /* 절대값 */   
     SIGN(수치 데이타)                    /* 부호 */
     SQRT(수치값)                         /* 제곱근 */
     POWER(수치값, n)                     /* n승 */
 

 2.  문자열 함수 정리

 

1)  Ascii() - 문자열의 제일 왼쪽 문자의 아스키 코드 값을 반환(Integer)

예) SELECT Ascii('abcd')

    >>  결과는 a의 아스키 코드값인 97 반환

 

2) Char() - 정수 아스키 코드를 문자로 반환(Char)

예) SELECT Char(97)

      >> 결과는 a 반환

 

3) Charindex() - 문자열에서 지정한 식의 위치를 반환

예)  SELECT Charindex('b','abcde')   >> 결과 : 2
      SELECT Charindex('b','abcde',2) >> 결과 : 2
      SELECT Charindex('b','abcde',3) >> 결과 : 0 

       -- 인수값이 3개일때 마지막은 abcde 에서의 문자열 검색 시작위치를 말하며

            2인경우는 bcde 라는 문자열에 대해서 검색

            3인 경우는 cde 라는 문자열에 대해서 검색 하게 된다.

 

4) Difference() - 두 문자식에 SUONDEX  값 간의 차이를 정수로 반환

예)  SELECT Difference('a','b')

 

5) Left() - 문자열에서 왼쪽에서부터 지정한 수만큼의 문자를 반환

예)  SELECT Left('abced',3)       결과 >> 3

 

6) Len() - 문자열의 길이 반환

예) SELECT Len('abced')         결과>>5

 

7) Lower() - 대문자를 소문자로 반환

예) SELECT Lower('ABCDE')    결과 >> abcde

 

8) Ltrim() - 문자열의 왼쪽 공백 제거

예)  SELECT Ltrim('   AB  CDE')    결과>> AB CDE

 

9)Nchar()  - 지정한 정수 코드의 유니코드 문자 반환

예)  SELECT Nchar(20)       결과  >> 

 

 

10) Replace -  문자열에서 바꾸고 싶은 문자 다른 문자로 변환

예) SELECT Replace('abcde','a','1')    결과>>1bcde

 

11) Replicate()  - 문자식을 지정한 횟수만큼 반복

예) SELECT Replicate('abc',3)              결과>> abcabcabc

 

12) Reverse() - 문자열을 역순으로 출력

예)   SELECT Reverse('abcde')             결과>> edcba

 

13) Right()  - 문자열의 오른쪽에서 부터 지정한 수 만큼 반환(Left() 와 비슷 )

예) SELECT Right('abcde',3)                 결과>> cde

 

14)Rtrim()  - 문자열의 오른쪽 공백 제거

예) SELECT Rtrim(' ab cde  ')               결과>>  ' ab cde'  <-- 공백구분을위해 ' 표시

 

15)  Space()  -  지정한 수만큼의 공백 문자 반환

예)  SELECT Space(10)                  결과 >>  '         '   -- 그냥 공백이 나옴

      확인을 위해서  SELECT 'S'+Space(10)+'E'   결과 >> S        E  

 

16) Substring()  -  문자,이진,텍스트 또는 이미지 식의 일부를 반환

예) SELECT Substring('abcde',2,3)      결과>>  bcd

 

17)Unicode() - 식에 있는 첫번째 문자의 유니코드 정수 값을 반환

예)SELECT Unicode('abcde')              결과 >> 97

 

18)Upper() - 소문자를 대문자로 반환

예) SELECT Upper('abcde')              결과>> ABCDE

 

※ 기타 함수 Tip

 

19) Isnumeric - 해당 문자열이 숫자형이면 1 아니면 0을 반환

>> 숫자 : 1  , 숫자X :0

예) SELECT Isnumeric('30')       결과 >> 1

     SELECT Isnumeric('3z')        결과 >> 0

 

20) Isdate()  - 해당 문자열이 Datetime이면 1 아니면 0
>> 날짜 : 1   , 날짜 X :0

예) SELECT Isdate('20071231')    결과 >> 1

     SELECT Isdate(getdate())      결과 >> 1
     SELECT Isdate('2007123')      결과 >> 0

     SELECT Isdate('aa')             결과 >> 0

 

 

※ 날짜및 시간함수 정리

 

getdate()  >> 오늘 날짜를 반환(datetime)

 

1> DateAdd()   - 지정한 날짜에 일정 간격을 + 새 일정을 반환

예) SELECT Dateadd(s,2000,getdate())

 

2> Datediff()  - 지정한 두 날짜의 간의 겹치는 날짜 및 시간 범위 반환

예)SELECT DateDiff(d,getdate(),(getdate()+31))

 

3> Datename() -지정한 날짜에 특정 날짜부분을 나타내는 문자열을 반환

예) SELECT Datename(d,getdate())

 

4> Datepart() -지정한 날짜에 특정 날짜부분을 나타내는 정수를  반환

예) SELECT Datepart(d,getdate())

 ** 돌려주는값(약어)
      Year-yy, Quarter-qq, Month-mm, DayofYear-dy, Day-dd, Week-wk, 
      Hour-hh, Minute-mi, Second-ss, Milisecond-ms
      SELECT DATEADD(dd, 7, 날짜칼럼)  

>> Datename , Datepart 은 결과 값은 같으나 반환 값의 타입이 틀림.

 

5> Day() -지정한 날짜에 일 부분을 나타내는 정수를  반환

예) SELECT Day(getdate())      -- 일 반환

     SELECT Month(getdate())   -- 월 반환

       SELECT Year(getdate())           --  년 반환     4. 형변환 함수
     CONVERT(데이타 타입, 칼럼)                 /* 칼럼을 원하는 데이타 타입으로 변환 */
     CONVERT(데이타 타입, 칼럼, 날짜형 스타일)  /* 원하는 날짜 스타일로 변환 */
     CAST(칼럼 AS 데이타 타입)                  /* 칼럼을 원하는 데이타 타입으로 변환 */ 
   ** 스타일
      1->mm/dd/yy, 2->yy.mm.dd, 3->dd/mm/yy, 4->dd.mm.yy, 5->dd-mm-yy,
      8->hh:mm:ss, 10->mm-dd-yy, 11->yy/mm/dd, 12->yymmdd
      SELECT CONVERT(varchar(10), 날짜칼럼, 2)

 

 그룹화  함수
   SELECT COUNT(*) FROM 테이블명               /* 전체 데이타의 갯수 가져오기 */
   SEELECT COUNT(칼럼) FROM 테이블명           /* NULL은 제외한 칼럼의 데이타 갯수 가져오기 */
   SELECT SUM(칼럼) FROM 테이블명              /* 칼럼의 합계 구하기 */
   SELECT MAX(칼럼) FROM 테이블명              /* 칼럼의 최대값 구하기 */
   SELECT MIN(칼럼) FROM 테이블명              /* 칼럼의 최소값 구하기 */
   SELECT AVG(칼럼) FROM 테이블명              /* 칼럼의 평균값 구하기 */
  GROUP BY문
   SELECT 칼럼 FROM 테이블명 GROUP BY 칼럼   
   SELECT 칼럼1, SUM(칼럼2) FROM 테이블명 GROUP BY 칼럼1
   SELECT 칼럼1, COUNT(*) FROM 테이블명 GROUP BY 칼럼1
   SELECT 칼럼1, 칼럼2, MAX(칼럼3) FROM 테이블명 GROUP BY 칼럼1, 칼럼2
    ** GROUP BY를 지정한 경우 SELECT 다음에는 반드시 GROUP BY에서 지정한 칼럼 또는
       그룹 함수만이 올 수 있다


  조건
   SELECT 칼럼1, SUM(칼럼2) FROM 테이블명 GROUP BY 칼럼1 HAVING SUM(칼럼2) < a
   SELECT 칼럼1, SUM(칼럼2) FROM 테이블명 ORDER BY 칼럼1 COMPUTE SUM(칼럼2)
    ** HAVING:        그룹 함수를 사용할 경우의 조건을 지정한다
       HAVING의 위치: GROUP BY의 뒤 ORDER BY의 앞에 지정한다
       COMPUTE:       각 그룹의 소계를 요약해서 보여준다
                      ORDER BY가 항상 선행해서 나와야 한다
  조건절의 서브 쿼리
   ** SELECT 또는 INSERTY, UPDATE, DELETE 같은 문의 조건절에서 SELECT문을 또 사용하는 것이다
      SELECT문 안에 또 다른 SELECT문이 포함되어 있다고 중첩 SELECT문(NESTED SELECT)이라고 한다
   ** 데이타베이스에는 여러명이 엑세스하고 있기 때문에 쿼리를 여러개 나누어서 사용하면 데이타의 값이
      달라질수 있기때문에 트랜잭션 처리를 하지 않는다면 복수의 쿼리를 하나의 쿼리로 만들어 사용해야 한다
    SELECT 칼럼1, 칼럼2 FROM 테이블명 WHERE 칼럼2 = (SELECT 칼럼2 FROM 테이블명 WHERE 조건)
    SELECT 칼럼1, 칼럼2 FROM 테이블명 WHERE 칼럼1 IN (SELECT 칼럼1 FROM 테이블명 WHERE 조건)
   ** 서브 쿼리에서는 다른 테이블을 포함할 수 있다
      두개의 테이블에서 읽어오는 서브쿼리의 경우 서브 쿼리쪽에 데이타가 적은 테이블을 주 쿼리쪽에 데이타가
      많은 테이블을 지정해야 처리 속도가 빨라진다
    SELECT 칼럼1, 칼럼2 FROM 테이블명 WHERE 칼럼1 IN (SELECT 칼럼2-1 FROM 테이블명2 WHERE 조건)
   ** FROM구에서 서브 쿼리를 사용할 수 있다
      사용시 반드시 별칭을 붙여야 하고 처리 속도가 빨라진다
    SELECT 칼럼1, 칼럼2 FROM 테이블명 WHERE 조건1 AND 조건2
    SEELCT 칼럼1, 칼럼2 FROM (SELECT 칼럼1, 칼럼2 FROM 테이블명 WHERE 조건1) 별칭 WHERE 조건2

 데이타 편집


  추가
   ** NULL 값을 허용하지도 않고 디폴트 값도 지정되어 있지 않은 칼럼에 값을 지정하지 않은채
      INSERT를 수행하면 에러가 발생한다
   ** 수치값은 그대로 문자값은 ''(작은따옴표)로 마무리 한다
   ** SELECT INTO는 칼럼과 데이타는 복사하지만 칼럼에 설정된 프라이머리, 포린 키등등의 제약 조건은
      복사되지 않기 때문에 복사가 끝난후 새로 설정해 주어야 한다

   INSERT INTO 테이블명 VALUES (값1, 값2, ...)     /* 모든 필드에 데이타를 넣을 때 */
   INSERT INTO 테이블명 (칼럼1, 칼럼2, ...) VALUES (값1, 값2, ...)   /* 특정 칼럼에만 데이타를 넣을 때 */
   INSERT INTO 테이블명 SELECT * FROM 테이블명2                      /* 이미 존재하는 테이블에 데이타 추가 */
   INSERT INTO 테이블명(칼럼1, 칼럼2, ...) SELECT 칼럼1, 칼럼2, ...) FROM 테이블명2
   SELECT * INTO 테이블명 FROM 테이블명2                             /* 새로 만든 테이블에 데이타 추가 */
   SELECT 칼럼1, 칼럼2, ... 테이블명 FROM 테이블명2
   
  갱신
   UPDATE 테이블명 SET 칼럼1=값1, 칼럼2=값2            /* 전체 데이타 갱신 */      
   UPDATE 테이블명 SET 칼럼1=값1, 칼럼2=값2 WHERE 조건               /* 조건에 해당되는 데이타 갱신 */

 

- UPDATE~SELECT

UPDATE A
SET A.cyberLectures = B.bizAddress
FROM OF_Member A, OF_Member B
WHERE A.no = B.no
   


  삭제
   DELETE FROM 테이블명                                              /* 전체 데이타 삭제 */
   DELETE FROM 테이블명 WHERE 조건       /* 조건에 해당되는 데이타 삭제 */

 

 오브젝트
  ** 데이타베이스는 아래 오브젝트들을 각각의 유저별로 관리를 하는데 Schema(스키마)는 각 유저별 소유 리스트이다

  1. Table(테이블)
   ** CREATE일때 프라이머리 키를 설정하지 않는다면 (칼럼 int IDENTITY(1, 1) NOT NULL) 자동 칼럼을 만든다
      데이타들의 입력 순서와 중복된 데이타를 구별하기 위해서 반드시 필요하다
   ** 테이블 정보 SP_HELP 테이블명, 제약 조건은 SP_HELPCONSTRAINT 테이블명 을 사용한다

   CREATE TABLE 데이타베이스이름.소유자이름.테이블이름 (칼럼 데이타형 제약, ...) /* 테이블 만들기 */
   DROP TABLE 테이블명                                                           /* 테이블 삭제 */
   ALTER TABLE 테이블명 ADD 칼럼 데이타형 제약, ...                              /* 칼럼 추가 */
   ALTER TABLE 테이블명 DROP COLUMN 칼럼                                         /* 칼럼 삭제 */ 
    ** DROP COLUMN으로 다음 칼럼은 삭제를 할 수 없다
       - 복제된 칼럼 
       - 인덱스로 사용하는 칼럼
       - PRIMARY KEY, FOREGIN KEY, UNIQUE, CHECK등의 제약 조건이 지정된 칼럼
       - DEFAULT 키워드로 정의된 기본값과 연결되거나 기본 개체에 바인딩된 칼럼
       - 규칙에 바인딩된 칼럼
   CREATE TABLE 테이블명 (칼럼 데이타형 DEFAULT 디폴트값, ...)                   /* 디폴트 지정 */
   CREATE TABLE 테이블명 (칼럼 데이타형 CONSTRAINT 이름 UNIQUE, ...)             /* 유니크 설정 */
    ** UNIQUE란 지정한 칼럼에 같은 값이 들어가는것을 금지하는 제약으로 기본 키와 비슷하지만
       NULL 값을 하용하는것이 다르다
   CREATE TABLE 테이블명 (칼럼 데이타형 CONSTRAINT 이름 NOT NULL, ...)           /* NOT NULL 설정 */
   CREATE TABLE 테이블명 (칼럼 데이타형 CONSTRAINT 이름 PRIMARY KEY, ...)        /* 기본 키 설정 */
    ** 기본 키는 유니크와 NOT NULL이 조합된 제약으로 색인이 자동적으로 지정되고 데이타를 
       유일하게 만들어 준다
    **  기본 키는 한 테이블에 한개의 칼럼만 가능하다
   CREATE TABLE 테이블명 (칼럼 데이타형 CONSTRAINT 이름 FOREIGN KEY REFERENCES 부모테이블이름(부모칼럼), ...)        
   CREATE TABLE 테이블명 (칼럼 데이타형 CONSTRAINT 이름 CHECK(조건), ...)        /* CHECK 설정 */
    ** CHECK는 조건을 임의로 정의할 수 있는 제약으로 설정되면 조건을 충족시키는 데이타만
       등록할 수 있고 SELECT의 WHERE구와 같은 조건을 지정한다
    ** CONSTRAINT와 제약 이름을 쓰지 않으면 데이타베이스가 알아서 이름을 붙이지만
       복잡한 이름이 되기 때문에 되도록이면 사용자가 지정하도록 한다
    ** CONSTRAINT는 칼럼과 데이타형을 모두 정의한 뒤에 맨 마지막에 설정할 수 있다
     CREATE TABLE 테이블명 (칼럼1 데이타형,
             칼럼2 데이타형, ...
             CONSTRAINT 이름 PRIMARY KEY(칼럼1)
                           CONSTRAINT 이름 CHECK(칼럼2 < a) ...)        
   ALTER TABLE 테이블명 ADD CONSTRAINT 이름 제약문                                /* 제약 추가 */
   ALTER TABLE 테이블명 DROP CONSTRAINT 제약명                                    /* 제약 삭제 */
   ALTER TABLE 테이블명 NOCHECK CONSTRAINT 제약명                                 /* 제약 효력 정지 */
   ALTER TABLE 테이블명 CHECK CONSTRAINT 제약명                                   /* 제약 효력 유효 */
    ** 제약명은 테이블을 만들때 사용자가 지정한 파일 이름을 말한다

 

  2. View(뷰)
   ** 자주 사용하는 SELECT문이 있을때 사용한다
      테이블에 존재하는 칼럼들중 특정 칼럼을 보이고 싶지 않을때 사용한다
      테이블간의 결합등으로 인해 복잡해진 SELECT문을 간단히 다루고 싶을때 사용한다
   ** 뷰를 만들때 COMPUTE, COMPUTE BY, SELECT INTO, ORDER BY는 사용할 수 없고
      #, ##으로 시작되는 임시 테이블도 뷰의 대상으로 사용할 수 없다
   ** 뷰의 내용을 보고 싶으면 SP_HELPTEXT 뷰명 을 사용한다
       
   CREATE VIEW 뷰명 AS SELECT문                            /* 뷰 만들기 */
   CREATE VIEW 뷰명 (별칭1, 별칭2, ...) AS SELECT문    /* 칼럼의 별칭 붙이기 */
   CREATE VIEW 뷰명 AS (SELECT 칼럼1 AS 별칭1, 칼럼2 AS 별칭2, ...)
   ALTER VIEW 뷰명 AS SELECT문                                       /* 뷰 수정 */
   DROP VIEW 뷰명                                                    /* 뷰 삭제 */
   CREATE VIEW 뷰명 WITH ENCRYPTION AS SELECT문                      /* 뷰 암호 */
    ** 한번 암호화된 뷰는 소스 코드를 볼 수 없으므로 뷰를 암호화하기전에
       뷰의 내용을 스크립트 파일로 저장하여 보관한다
   INSERT INTO 뷰명 (칼럼1, 칼럼2, ...) VALUES (값1, 값2, ...)
   UPDATE 뷰명 SET 칼럼=값 WHERE 조건
    ** 원래 테이블에 있는 반드시 값을 입력해야 하는 칼럼이 포함되어 있지 않거나
       원래 칼럼을 사용하지 않고 변형된 칼럼을 사용하는 뷰는 데이타를 추가하거나 
       갱신할 수 없다
    ** WHERE 조건을 지정한 뷰는 뷰를 만들었을때 WITH CHECK OPTION을 지정하지 않았다면
       조건에 맞지 않는 데이타를 추가할 수 있지만 뷰에서는 보이지 않는다
       또한 뷰를 통해서 가져온 조건을 만족하는 값도 뷰의 조건에 만족하지 않는 값으로도 
       갱신할 수 있다
   CREATE VIEW 뷰명 AS SELECT문 WITH CHECK OPTION
    ** 뷰의 조건에 맞지 않는 INSERT나 UPDATE를 막을려면 WITH CHECK OPTION을 설정한다

 

  3. Stored Procedure(저장 프로시저)
   ** 데이타베이스내에서 SQL 명령을 컴파일할때 캐시를 이용할 수 있으므로 처리가 매우 빠르다
      반복적으로 SQL 명령을 실행할 경우 매회 명령마다 네트워크를 경유할 필요가 없다
      어플리케이션마다 새로 만들 필요없이 이미 만들어진 프로시저를 반복 사용한다
      데이타베이스 로직을 수정시 프로시저는 서버측에 있으므로 어플리케이션을 다시 컴파일할 필요가 없다
   ** 저장 프로시저의 소스 코드를 보고 싶으면 SP_HELPTEXT 프로시저명 을 사용한다

   CREATE PROC 프로시저명 AS SQL문   /* 저장 프로시저 */
   CREATE PROC 프로시저명 변수선언 AS SQL문 /* 인수를 가지는 저장 프로시저 */
   CREATE PROC 프로시저명 WITH ENCRYPTION AS SQL문 /* 저장 프로시저 보안 설정 */
   CREATE PROC 프로시저명                          /* RETURN 값을 가지는 저장 프로시저 */
       인수1 데이타형, ... 인수2 데이타형 OUTPUT
   AS 
       SQL문
       RETURN 리턴값
   DROP PROCEDURE 프로시저명1, 프로시저명2, ...    /* 저장 프로시저 삭제 */
   
   명령어
    BEGIN ... END    /* 문장의 블록 지정 */
    DECLARE @변수명 데이타형  /* 변수 선언 */
    SET @변수명=값    /* 변수에 값 지정 */
    PRINT @변수명    /* 한개의 변수 출력 */
    SELECT @변수1, @변수2   /* 여러개의 변수 출력 */
    IF 조건     /* 조건 수행 */
        수행1 
    ELSE 
        수행2                
    WHILE 조건1    /* 반복 수행 */
        BEGIN 
            IF 조건2
         BREAK    - WHILE 루프를 빠져 나간다 
         CONTINUE - 수행을 처리하지 않고 조건1로 되돌아간다 
     수행
        END                
    EXEC 저장프로시저   /* SQL문을 실행 */
    EXEC @(변수로 지정된 SQL문) 
    GO     /* BATCH를 구분 지정 */

 

   에제
    1. 기본 저장 프로시저
     CREATE PROC pUpdateSalary AS UPDATE Employee SET salary=salary*2


    2. 인수를 가지는 저장 프로시저
     CREATE PROC pUpdateSalary 
         @mul float=2, @mul2 int 
     AS 
         UPDATE Employee SET salary=salary* @Mul* @mul2
     EXEC pUpdateSalary 0.5, 2       /* 모든 변수에 값을 대입 */ 
     EXEC pUpdateSalary @mul2=2      /* 원하는 변수에만 값을 대입 */


    3. 리턴값을 가지는 저장 프로시저
     CREATE PROC pToday 
         @Today varchar(4) OUTPUT
     AS 
         SELECT @Today=CONVERT(varchar(2), DATEPART(dd, GETDATE()))
         RETURN @Today
     DECLARE @answer varchar(4)
     EXEC pToday @answer OUTPUT
     SELECT @answer AS 오늘날짜


    4. 변수 선언과 대입, 출력
     ** @는 사용자 변수이고 @@는 시스템에서 사용하는 변수이다

     DECLARE @EmpNum int, @t_name VARCHAR(20)
     SET @EmpNum=10

     SET @t_name = '강우정'
     SELECT @EmpNum

 

이런식으로 다중입력도 가능함.

SELECT  @no = no, @name = name, @level = level
FROM OF_Member
WHERE userId ='"

 

 

  4. Trigger(트리거)
   ** 한 테이블의 데이타가 편집(INSERT/UPDATE/DELETE)된 경우에 자동으로 다른 테이블의
      데이타를 삽입, 수정, 삭제한다
   ** 트리거 내용을 보고 싶으면 SP_HELPTRIGGER 트리거명 을 사용한다

   CREATE TRIGGER 트리거명 ON 테이블명 FOR INSERT AS SQL문         /* INSERT 작업이 수행될때 */
   CREATE TRIGGER 트리거명 ON 테이블명 AFTER UPDATE AS SQL문       /* UPDATE 작업이 수행되고 난 후 */
   CREATE TRIGGER 트리거명 ON 테이블명 INSTEAD OF DELETE AS SQL문  
   DROP TRIGGER 트리거명

 

  5. Cursor(커서)
   ** SELECT로 가져온 결과들을 하나씩 읽어들여 처리하고 싶을때 사용한다
   ** 커서의 사용방법은 OPEN, FETCH, CLOSE, DEALLOCATE등 4단계를 거친다
   ** FETCH에는 NEXT, PRIOR, FIRST, LAST, ABSOLUTE {n / @nvar}, RELATIVE {n / @nvar}가 있다

   SET NOCOUNT ON      /* SQL문의 영향을 받은 행수를 나타내는 메시지를 숨긴다 */
   DECLARE cStatus SCROLL CURSOR    /* 앞뒤로 움직이는 커서 선언 */
   FOR
       SELECT ID, Year, City FROM aPlane
   FOR READ ONLY
   OPEN cStatus      /* 커서를 연다 */
   DECLARE @ID varchar(50), @Year int, @City varchar(50), @Status char(1)
   FETCH FROM cStatus INTO @ID, @Year, @City /* 커서에서 데이타를 하나씩 가져온다 */
   WHILE @@FETCH_STATUS=0                    /* 커서가 가르키는 결과의 끝까지 */
   BEGIN
       IF      @Year <= 5              SET @Status='A'
       ELSE IF @Year> 6 AND @Year <= 9 SET @Status='B'
       ELSE                            SET @Status='C'
       INSERT INTO aPlane(ID, City, Status) VALUES(@ID, @Year, @Status)
       FETCH FROM cStatus INTO @ID, @Year, @City /* 커서에서 데이타를 하나씩 가져온다 */
   END
   CLOSE cStaus                              /* 커서를 닫는다 */
   DEALLOCATE cStatus                        /* 커서를 해제한다 */

 

 보안과 사용자 권한
  ** 보안의 설정 방법은 크게 WINDOWS 보안과 SQL 보안으로 나뉘어 진다
  ** 사용자에게 역할을 부여하는데는 서버롤과 데이타베이스롤이 있다

  1. SA(System Administrator)
   ** 가장 상위의 권한으로 SQL 서버에 관한 전체 권한을 가지고 모든 오브젝트를 만들거나 
      수정, 삭제할 수 있다

  2. DBO(Database Owner)
   ** 해당 데이타베이스에 관한 모든 권한을 가지며 SA로 로그인해서 데이타베이스에서 테이블을
      만들어도 사용자는 DBO로 매핑된다
   ** 테이블이름의 구조는 서버이름.데이타베이스이름.DBO.테이블이름이다

  3. DBOO(Database Object Owner)
   ** 테이블, 인덱스, 뷰, 트리거, 함수, 스토어드 프로시저등의 오브젝트를 만드는 권한을 가지며
      SA나 DBO가 권한을 부여한다

  4. USER(일반 사용자)
   ** DBO나 DBOO가 해당 오브젝트에 대한 사용 권한을 부여한다

 

 

[SQL 서버 2005 실전 활용] ① 더 강력해진 T-SQL  : http://blog.naver.com/dbwpsl/60041936511

  •  MSSQL 2005 추가 쿼리
  •  

     

    -- ANY (OR 기능)

    WHERE 나이 >= (SELECT 나이 FROM .......)

     

    -- GROUP BY ALL (WHERE 절과 일치 하지 않는 내용은 NULL 로 표시)

    SELECT 주소, AVG(나이) AS 나이 FROM MEMBER

    WHERE 성별='남'

    GROUP  BY ALL 주소

    -- 모든 주소는 나오며 성별에 따라 나이 데이터는 NULL

     

    -- WITH ROLLUP

    SELECT 생일, 주소, SUM(나이) AS 나이

    FROM MEMBER

    GROUP BY 생일, 주소 WITH ROLLUP

    -- 생일 과 주소를 요약행이 만들어짐

     

    -- WITH CUBE (위의 예제를 기준으로, 주소에 대한 별도 그룹 요약데이터가 하단에 붙어나옴)

     

    -- GROUPING(컬럼명) ROLLUP 또는 CUBE 의 요약행인지 여부 판단(요약행이면 1 아니면 0)

    SELECT 생일, 주소, GROUPING(생일) AS 생일요약행여부

     

    -- COMPUTE (GROUP BY 와 상관없이 별도의 테이블로 요약정보 생성)

    SELECT 생일, 나이

    FROM MEMBER

    COMPUTE SUM(나이), AVG(나이)

     

    -- PIVOT (세로 컬럼을 가로 변경)

    EX)

    학년/ 반 / 학생수

     1     1     40

     1     2     45

     2     1     30

     2     2     40

     3     1     10

     3     2     10

    위와 같이 SCHOOL 테이블이 있다면

     

    SELECT 그룹할컬럼명, [열로변환시킬 행]

    FROM 테이블

       PIVOT(

          SUM(검색할열)

          FOR 옆으로만들 컬럼명

             IN([열로변환시킬 행])

             ) AS 별칭

     

    --실제 쿼리는

    SELECT 학년, [1반], [2반]

    FROM SCHOOL

       PIVOT(

          SUM(학생수)

          FOR 반

             IN([1반], [2반])

             ) AS PVT

     

    -- UNPIVOT (가로 컬럼을 세로로)

     

    SELECT 학년, 반, 학생수

    FROM SCHOOL

      UNPIVOT(

        FOR 반

          IN( [1반], [2반] )

        ) AS UNPVT

     

    -- RANK (순위)

    SELECT 컬럼명, RANK() OVER( ORDER BY 순위 기준 컬럼명) AS 순위

    FROM 테이블

     

    -- PARTITION BY (그룹별로 순위 생성)

    SELECT 컬럼명, RANK() OVER( PARTITION BY 그룹기준컬러명 ORDER BY 순위기준컬럼명) AS 순위

    FROM 테이블

     

    -- FULL OUTER JOIN (LEFT 조인과 RIGHT 조인을 합한것)

    양쪽 어느 하나라도 데이가 있으면 나옴

     

     

    -- ROW_NUMBER (순차번호 생성)

    SELECT ROW_NUMBER() OVER( ORDER BY 기준열) AS 번호, 컬럼명

    FROM 테이블

     

    자료형 (데이터타입)

    MSSQL 서버에서 사용하는 데이터 타입(자료형)은 두가지가 있다.

     

    1. 시스템에서 제공하는 System data type

     

     

     

     


    성능향상을 위해서라면 가능한 작은 자료형을 사용하도록 하자.

    불필요하게 int를 쓰는 경우가 흔한데, 사용될 데이터의 범위를 생각해 본 후, 가장 작은 범위의 자료형을 사용하도록 하자.

     

     

    2. 사용자가 정의 하는  User data type

     

    사용자 정의 자료형이 왜 필요한가?

    C언어를 비로한 몇 가지 언어에서 나타나는 사용자 정의 데이터 유형과 같다.

    프로젝트에 참가하는 사람들이 동일한 데이터 타입을 사용하고자 원하거나,

    한 컬럼에 대한 데이터 유형을 더 쉽게 사용하려고 할 때 적용시킬 수 있다.

     

    사용 방법

    sp_addtype  [새로운 타입 이름], '[SQL 데이터 타입]'

     

    sp_addtype empID, 'CHAR(10)'

    sp_addtype empNO, 'CHAR(12)'

     

     

     

    * 참고로 자료형을 바꾸는 함수로는 CONVERT() 가 있다.

     

    사용방법

    SELECT CONVERT(CHAR(30), title) FROM BOOKS

    --> title 라는 컬럼을 CHAR(30) 으로 변환하여 가져오는 것이다.

     

    SELECT CONVERT(VARCHAR(10), 35)

    --> 35 라는 숫자를 VARCHAR(10) 으로 변환한다. 

     

     

    흐름 제어문의 종류

     

    흐름 제어문이란 언어의 처리 순서를 변경하거나 변수를 선언하는 등의 문장을 말한다.

     

    ○ GOTO 라벨

      - GOTO 를 만나면 라벨 부분으로 무조건 건너뛴다. 라벨은 라벨: 으로 정의한다.

    예)

    DECLARE...

    SET...

    table_label1:

    .

    .

    IF .... GOTO table_label1

    .

    --> GOTO table_label1 을 만나면 table_label1: 부분으로 건너 뛴다.

     

    ○ RETURN

      - RETURN 은 무조건 수행을 중지 하고 원래 호출된 곳으로 돌아간다.

     

    ○ IF / ELSE

      - 이름만 들어도 알만한 문법이다. 주의 할 점은  조건문 안의 SQL문장이 둘 이상이라면 BEGIN / END 로 묶어 준다.

    예)

    IF @begin > @end

        BEGIN

            SELECT * FROM 테이블1 WHERE 조건

            RETURN

        END

    ELSE

        SELECT * FROM.........

     

    ○ WHILE / BREAK / CONTINUE

      - WHILE 다음에 조건으로 반복을 하게 되고,

        BREAK  를 만나면 무조건 WHILE 을 벗어나고,

        CONTINUE 를 만나면 무조건 WHILE 로 돌아간다.

    예)

    WHILE  조건

    BEGIN

             반복하는 동안 실행할 문장들...

             IF 조건

                   BREAK

             IF 조건

                   CONTINUE

    END

     

    ○ EXEC[UTE]

      - EXEC 와 EXECUTE 는 같은 의미이다.

      - 두가지 용도로 사용되는데,

      - 첫 번째, 스토어드 프로시저를 실행할 때 사용한다.

    예)

    EXEC stored_procedure

     

      - 두 번재, SQL 문장을 동적으로 변화시키며 수행할 수 있다.

    예)

    DECLARE  @sql  VARCHAR(255)

    SET  @sql  = 'SELECT COUNT(*) FROM '

    SET  @sql  =  @sql + 'titles '

    EXEC(@sql)

    --> 실제 수행되는 문장은 SELECT COUNT(*) FROM titles 가 된다.

     

    ○ CASE

      - 단순 CASE

    예)

    SELECT

        CASE type

            WHEN 'a'  THEN  'Apple'

            WHEN 'b'  THEN  'Banana'

            ELSE  'No Data'

        END AS  과일

    , price

    FROM titles

     

      - 검색된 CASE

    예)

    SELECT  title_id

    , qty AS '수량'

    , CASE

           WHEN  qty >= 50  THEN  'A'

           WHEN  qty >= 30  THEN  'B'

           ELSE  'C'

      END  AS  '등급'

    FROM  titles

     

     NULLIF : 표현식 1과, 2를 비교

    >> 표현식 1과, 2를 비교 두 표현식이 같으면 NULL 을 리턴,  같지 않으면 표현식 1을 리턴
    SELECT NULLIF(2,3) -- 2 리턴
    SELECT NULLIF(3,3) -- NULL 리턴
     사용예 : 양쪽필드에서 수량이 같으면 NULL을 리턴하고 하니면 첫 필드의 값을 리턴할때

     

     

     COALESCE : 뒤에 오는 표현식중에 처음으로 오는 NULL 이 아닌 값을 리턴

     

    SELECT COALESCE(NULL, 3, 4) -- 3 리턴
    SELECT COALESCE(1,NULL,) -- 1 리턴
    SELECT COALESCE(NULL,NULL,4) -- 4 리턴

    SELECT COALESCE(NULL,NULL, NULL)--문법오류

     사용예 : 하나만 값을 가지고 있는 컬럼에서 비교해서 값을 가져올때 매우 좋다

     

     

    SET : 세성 옵션 (한번설정하면 세션이 끊어 질때까지 유용)

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

    SET nocount OFF
      : 몇개 행이 처리 되었는지 결과보여주는 것을 설정한다 '

    SET rowcount [n]

    ex) SET rowcount 4
    SELECT title_id FROM titles ORDER BY TITLE

    SET rowcount 0

      : 보여줄 목록의 행수를 선택한다. 목록의 정렬의 임의로 설정되므로 필요한 순서가 있다면 ORDER BY 를 사용해야 한다.
    사용후엔 반드시     SET ROWCOUNT 0 을 이용해서 원위치 시켜놓아야 한다 '

     

     

    ============================== 유니크 키 넣기  ==============================
    ALTER TABLE 테이블명 ADD UNIQUE(컬럼1, 컬럼2) 
    ALTER TABLE 테이블명 DROP CONSTRAINT 유니크명

    반응형
    반응형

    일단 조금이라도 부수입을 위해 만든 블로그이고

    개인공부를위해 포스팅을 계속 할 예정이라

    에드센스로 광고를 하는방법을 찾아보았다

    기본적으로 검색된 이슈들은 다음과 같다


    1.게시물수는 25개이상 게시물단 글자는 1000자이상이어야 승인이난다


    2.티스토리 주소로 가입하는데 에러가난다,도메인이 필요하다


    3.가입후에 스크립트를 head에 넣는데 승인이 안나는 문제



    이 3개를 하는 방법에대해 설명해본다

    1게시물수는 25개이상 게시물단 글자는 1000자이상이어야 승인이난다


    해당 루머는 거짓인걸로 확인한것이 글이 9개인 유저도 승인이 낫다고한다 

    어떠한 환경설정이나 이런부분에서 승인이 안났을 가능성이 큰것같다

    블로그의 글이 명확해야하고

    카테고리도 정리가 되어있어야 한다니 대충 권한을 얻어볼 생각은 버려야할것같다



     2.티스토리 주소로 가입하는데 에러가난다,도메인이 필요하다


    PC 브라우저로 에드센스 가입 중에 일어난 일이다


    티스토리 url이계속 거부를 당하는것이다 (사진은 주소를 가렸다)

    이경우에서 막혀서 도메인주소를 추가해서 가입을 한다는 사람도 있을정도로 심각한 문제였다

    나도 이대로 등록을 못하고 포기할까 하다가 구글 로그인이 되어있는

    모바일 크롬브라우저로 접속을 하니 바로 가입이 되었다

    솔직히 좀 황당한게 구글은 외국회사라서 이런 경우가 좀있던것같다

    이전에 구글에서 개인정보가 검색되는 문제때문에 삭제 요청하는데도 수일이 걸렸던 경험이있어서 그러려니 하고 넘어갔다



     3.가입후에 스크립트를 head에 넣는데 승인이 안나는 문제

    이경우는 애초에 스크립트를 받았는데 어디에 넣는지도 몰랐었다

    광고형식이니까 글을 등록할때 넣는것인가 생각해봤다가

    한번 찾아보니 기본적으로 모든 글 상위에 들어갈 html과 css를 적용해주는 페이지가 존재했다


    위치는

    블로그관리 > 꾸미기 > HTML/CSS 편집에서 수정이 가능하다


    해당 네모 박스에 넣으면 되고

    반드시 meta 태그 아래에 넣어야한다

    혹시나 찾아보시는 분들이 도움이 되었으면한다

    스크립트 형식은 참고바란다



    1
    2
    3
    4
    5
    6
    7
    <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
        <script>
        (adsbygoogle = window.adsbygoogle || []).push({
        google_ad_client: "ca-pub-1234567891011",
        enable_page_level_ads: true
        });
    </script>
    cs






    구글 애드센스의 심사가 완료되면 내 gmail 계정으로 허용여부에 대한 메일이 도착하게 됩니다.


    내 메일 내에 [지금 시작하기] 버튼 클릭 시 광고 설정 페이지로 이동하실 수 있습니다.


    페이지 이동 후 내 광고 > 콘텐츠 > 광고 단위 > 새 광고 단위를 클릭해주세요.


    광고의 이름 및 크기, 광고 유형, 등을 선택하시고 코드 생성을 클릭하시면 블로그에 위젯 형태로 적용할 수 있는 코드가 생성됩니다. 
    (* 각 블로그의 스킨마다 사이드 영역의 크기가 다를 수 있습니다. 회원님께서 적용하신 스킨 중 사이드 영역의 크기를 확인하시어 그와 알맞는 사이즈로 설정해주시기 바랍니다)

    내이글루에 적당한 광고 사이즈 결정

    구글 애드센스 콘텐츠용 광고는 아래과 같이 다양한 사이즈로 제공됩니다.
    수평형의 경우 가로사이즈가 넓은 광고이기 때문에 본문 영역의 아래 또는 위에 붙이기에 적당합니다. 수평형을 이용하시려면 새스킨만들기 하실 때 반드시 아래의 썸네일과 같이 본문 상/하단에 광고영역이 있는 레이아웃을 선택하셔야 합니다. (레이아웃 관련 도움말은 '새 스킨 만들기 - 레이아웃' 을 참고하시기 바랍니다.)
     
    수직형은 사이드바 어디든 적당합니다. 단, 광고의 사이즈가 길어서 사이드바의 많은 부분을 차지하게 됩니다. 이 점 유의하세요.

    마지막으로 사각형 역시 사이드바에 붙이기 적당한 사이즈 입니다. 단, 내이글루의 사이드바 가로 사이즈를 확인하고 적당한 사이즈를 선택하시기 바랍니다. 이글루스의 대부분의 스킨은 사이드바 사이즈가 180~220 정도입니다. 스킨을 수정하지 않으셨다면 '200x200 작은 사각형' 또는 '180x150 소형 직사각형 박스' 가 적당할 것입니다.


    해당 소스를 복사 하신 후 이글루 관리 > 디자인 > 위젯 의 html/script 위젯을 클릭해주세요.

    모든 설정 완료 후 내 블로그에 적용하시면 구글 애드센스를 직접 관리하실 수 있습니다.
    * 사이트에 광고 코드를 추가한다고 해도 실제 광고가 바로 게재되지 않습니다. 신청이 완전히 승인될 때까지 실제 광고 대신 '빈 칸 광고'가 임시로 게재됩니다. 빈 칸 광고는 페이지의 배경과 섞여서 표시되기 때문에 사용자에게는 보이지 않으며 사용자의 이용 경험에 영향을 주지 않습니다. 이 기간에는 수익이 발생하지 않으며 계정에 로그인하면 계정이 검토 중이라는 빨간색 알림 배너가 표시됩니다. Google은 이 검토 기간에 웹사이트를 크롤링하고 색인에 추가하여 최종 승인되는 즉시 광고를 게재합니다.

    광고 코드를 구현하고 사이트에 대한 검토가 완료되면 신청에 대한 최종 결정이 내려집니다. 이 과정을 완료할 때까지 최대 며칠이 걸릴 수 있으므로 필요한 모든 심사가 완료될 때까지 기다려 주시기 바랍니다. 결정이 내려지면 이메일이 발송됩니다. 승인되면 실제 광고가 사이트에 추가한 광고 단위에 자동으로 게재되기 시작합니다.


    반응형
    반응형

    개발을하다보면 ajax 방식의

    동기 처리가 필요할 때가있다

    동기 비동기에 대해서 간단히 짚고 넘어가자면

    동기방식은 간단하게 생각하자면 JAVA 코드처럼 수행방식이 

    위에서 아래로 순서적으로 코드 한줄 한줄을 읽어 나가는 방식이다

    예시를 들 필요가 없는게 비동기방식이 예시때문에 헷갈린적이있었다

    비동기 방식은 수행방식이 한줄 한줄 읽어 가는것은 맞지만 시간이 걸리는 코드는 기다려주지않고 

    건너 뛰어서 다음 코드를 하나씩 수행하게된다

    동기와 비동기의 중간에 3초가 걸리는 test() 함수가 하나있다고 생각해보면


    -동기방식은 3초 test함수를 실행한 뒤에 다음 코드를 수행하지만


    -비동기방식은 3초 test함수를 기다리지않고 다음코드를 계속 실행하게된다


    스크립트 예시를 들어보면


    - <img> 태그를 name 순서로 만들어주는 함수 A()

    - 이미지 태그안에 링크를 붙여주는 함수 B()

    가 있다고 가정해보자

    코드 순서는

    A();

    B();

    로 했다고 보면

    자바스크립트에선 A() 함수가 시간이 걸린다면 건너뛰어버리고 간헐적으로

    B() 함수가 먼저 실행되어 이미지가 깨져버리거나 에러가 발생한다



    서버단의 로직을 태워오는 ajax 가 이런 문제가 종종 발생하게되는데

    이걸 방지할수있는 promise 코드가 있다 

    패턴 예제가 다양하지만 직접 사용해 보았던 패턴만 확인해볼 예정이다


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //ajax + promise 예제
        var jsonData = {"STATUS":"A","MATRL":"A0000001","main":['a','b','c','d'],"stringObj":"{\"이름\":\"덩치\",\"거주지\":\"서울\"}"};
        
        var promise = $.ajax({  
            type: "POST",
            url: "/test/go",
            dataType: "json",    
            traditional: true,//배열 객체 보낼때
            data: jsonData });
        
        promise.done(successFunction);//프로미스 패턴 => 해당 ajax를 태운다음에 동작하는 function(동기방식)
        promise.fail(failFunction);
        
        function successFunction(data){
            if(data.result ==='success')
                var a = "함수호출 success";    
            
            return alert(a);
        }
        
        function failFunction(data){
            if(data.result !='success')
                var a = "함수호출 fail";    
            return alert(a);
        }
    cs


    successFunction 에 다음 작업을 넣어주면 임시적으로 동기처리를 할수있게된다


    when 이라는 함수도 사용할수있다

    여러가지 함수를 실행시킬수있는 방법으로 done 전에 실행된다 


    1
    2
    3
    $.when(A(), B()).done(function(result1, result2) {
      console.log(result1, result2);
    });
    cs



    구글링을 해보면 나오는 async: false 옵션을 주는 방법은

    jquery 1.8 버전부터 막혀서 권장되지않는 방법이다.




    기존에 promise 패턴이 아닌 callback 방식의 경우에는 아래와 같이 코딩을 하였습니다.

    $.ajax({
      url: "/ServerResource.txt",
      success: successFunction,
      error: errorFunction
    });


    대부분 함수의 파라미터 객체에 function 을 설정하여 결과에 대한 처리를 했습니다. 이러한 경우 callback 이 중첩되어 소스의 가독성도 떨어질 뿐더러 관리가 안되는 단점이 있었습니다.



    jQuery 1.5 버전 이후부터는 아래와 같이 done()fail()always() 를 이용하여 결과에 대한 처리를 지정합니다.

    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
      
    promise.done(successFunction);
    promise.fail(errorFunction);
    promise.always(alwaysFunction);


    jQuery.ajax() 는 jQuery XMLhttpRequest(jqXHR) 을 반환하기 때문에 아래와 같은 방식으로도 구현이 가능합니다.

    $.ajax( "example.php" )    
        .done(function() { alert("success"); })    
        .fail(function() { alert("error"); })    
        .always(function() { alert("complete"); }); 


    체인 방식이 아니더라도 jqXHR 객체에 직접 지정도 가능합니다.

    var jqxhr = $.ajax( "example.php" )    
        .done(function() { alert("success"); })    
        .fail(function() { alert("error"); })    
        .always(function() { alert("complete"); }); 
         
        // perform some work here ... 
         
        // Set another completion function for the request above
        jqxhr.always(function() { alert("another complete"); });



    jQuery 1.8 버전 이후부터는 then() 함수를 사용하여 Promise 패턴을 적용할 수 있습니다.

    then() 의 첫번째 인자는 성공에 대한 액션, 두번째 인자에는 실패에 대한 액션을 지정할 수 있습니다.

    $.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3], 
                                              [errorFunction1, errorFunction2]);
     
    //same as
     
    var jqxhr = $.ajax({
      url: "/ServerResource.txt"
    });
      
    jqxhr.done(successFunction1);
    jqxhr.done(successFunction2);
    jqxhr.done(successFunction3);
    jqxhr.fail(errorFunction1);
    jqxhr.fail(errorFunction2);
    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
      
    promise.then(successFunction, errorFunction);
    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
     
    promise.then(successFunction); //no handler for the fail() event




    Deferred 객체를 직접 만들어서 사용할 수 있는데, 그 방법은 아래와 같습니다.


    var timer;
    $('#result').html('waiting…');
      
    var promise = process();
    promise.done(function() {
      $('#result').html('done.');
    });
    promise.progress(function() {
      $('#result').html($('#result').html() + '.');
    });
     
    function process() {
      var deferred = $.Deferred();
     
      timer = setInterval(function() {
        deferred.notify();
      }, 1000);
       
      setTimeout(function() {
         clearInterval(timer);
         deferred.resolve();
      }, 10000);
       
      return deferred.promise();
    }




    Promise 에 등록된 callback 들을 Deferred 가 각 상황에 맞게 호출해주는 방식입니다.


    then() 함수를 이용하면 아래와 같이 구현할 수 있습니다.

    var timer;
     
    (function process() {
      $('#result').html('waiting…');
      var deferred = $.Deferred();
         
      timer = setInterval(function() {
        deferred.notify();
      }, 1000);
       
      setTimeout(function() {
         clearInterval(timer);
         deferred.resolve();
      }, 10000);
       
      return deferred.promise();
    })().then(function() { $('#result').html('done.'); },
              null,
              function() { $('#result').html($('#result').html() + '.'); });



    References

    http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html

    https://api.jquery.com/category/deferred-object/



    출처: http://uwostudy.tistory.com/54 [UWO스터디]

    반응형

    'IT > Javascript|Jquery' 카테고리의 다른 글

    javascript 셀렉트박스(SelectBox) 바로실행  (2) 2018.01.04
    ajax 로딩시 새로고침 문제  (6) 2018.01.03
    ajax 배열전송  (0) 2018.01.02
    모바일/PC 코딩하기  (0) 2018.01.02
    Jquery 셀렉터(Selector) 사용하기  (0) 2018.01.02
    반응형

    ajax 에서 배열을넘겨 JAVA 에서 확인할수있다
    traditional 옵션을 넣어주면 간단하게 되는거지만
    대부분 삽질을 하게된다


    1.javascript


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var arr = ['aa''bb''cc'];
     
    $.ajax({
        method      : 'POST',
        url         : 'test.do',
        traditional : true,
        data        : {
            'main' : arr
        },
        success     : function(data) {
            alert(data);        
        },
        error       : function(request, status, error) {
            alert(error);
        }
     
    });
    cs



    2.JAVA


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
        @RequestMapping(value = "/test.do", method = {RequestMethod.GET, RequestMethod.POST})    
        public ModelAndView test(
               HttpServletRequest request,
               String[] main//배열 받기 traditional: true
               ) {
               
               view.setViewName("jsonView");
            try {
     
                System.out.println(main[0]+"===============");//aa
                System.out.println(main[1]+"===============");//bb
                System.out.println(main[2]+"===============");//cc
                System.out.println(main[3]+"===============");//errer
                //throw new Exception();
                            
                view.addObject("result""success");
                
            }catch(Exception ex){
                ex.printStackTrace();
            }        
            
            return view;
        }
     
    cs



    Ajax를 이용하면 웹 어플리케이션과 비동기적으로 데이터를 주고 받은후 클라이언트에서 해당 데이터에 대한 처리를 할 수 있다. 쉽게 이야기하면 Ajax를 이용할 경우 별도의 웹 페이지를 호출하지 않더라도, 클라이언트 화면을 유지한채 다른 페이지를 호출할 수 있다.

    Ajax에 대한 설명은 위키백과를 참고하기 바란다. - http://ko.wikipedia.org/wiki/Ajax


    이러한 Ajax를 jQuery를 이용하면 정말 손쉽게 사용할 수 있는데, 기본적인 설정값만 넣어주면 바로 사용이 가능하다. 

    다음 예제는 웹페이지가 로딩된 후 ajax를 이용하여 ajaxData.jsp를 호출하는 예제이다. 
    ajaxData.jsp는 텍스트 형식의 값을 리턴하며 리턴된 값을 alert창과 div에 출력한다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Ajax 간단 테스트</title>
     
     
    <script type="text/javascript" language="javascript">
     
        $(document).ready(function(){
             
             
            $.ajax({
                 
                type : "GET",
                url : "ajaxData.jsp?type=1",
                dataType : "text",
                error : function(){
                    alert('통신실패!!');
                },
                success : function(data){
                    alert("통신데이터 값 : " + data) ;
                    $("#dataArea").html(data) ;
                }
                 
            });
             
     
        });
     
    </script>
     
    </head>
    <body>
     
        <div id="dataArea"></div>
     
    </body>
    </html>



    위의 예제는 ajax 통신을 할때 가장 기본이 되는 항목만 사용하였다. 적어도 위의 설정값 정도는 최소한으로 넣어주는게 좋다.



    속성

    설명

     type

     http 전송 method를 지정한다. GET, POST

     url

     호출 URL. GET 방식일경우 URL 뒤에 파라미터를 붙여서 사용해도 된다.

     dataType

     Ajax를 통해 호출한 페이지의 Return 형식이다. 형식에 따라 xml, json, html, text 등을 사용하면 된다.

     error

     에러났을때의 처리 부분이다.

     success

     성공했을때의 처리 부분이다. 보통 해당 부분에서 데이터 핸들링을 하면 된다.




     

    - 각 Ajax 방식을 호출하는 방법

    1. // 버튼 클릭시 ajax 실행  
    2. $("#btnOK").click(function(){  
    3.       
    4.     var url="test.aspx";  
    5.     var params="param1="+param1+"¶m2="+param1;  
    6.   
    7.     $.ajax({      
    8.         type:"POST",  
    9.         url:url,      
    10.         data:params,      
    11.         success:function(args){   
    12.             $("#result").html(args);      
    13.         },   
    14.         beforeSend:showRequest,  
    15.         error:function(e){  
    16.             alert(e.responseText);  
    17.         }  
    18.     });  
    19.       
    20. });  

     

     

    1. $.post() 방식

     

    - 서버에 데이터를 HTTP POST 방식으로 전송한 후 서버측 응답 받을 때 사용

     

    [형식]

    jQuery.post( url [, data] [, success(data, textStatus, jqXHR)] [, dataType] )

     

    - url : 요청 Url

    - data : 요청과 함께 서버에 보내는 string 또는 map

    - success(data,textStatus,jqXHR) : 요청이 성공일때 실행되는 callback 함수

    - dataType : 서버에서 내려온 data 형식. ( default : xml,json,script,text,html )

     

     

    [$.ajax 로 표현]

    1. $.ajax({  
    2.   type: 'POST',  
    3.   url: url,  
    4.   data: data,  
    5.   success: success,  
    6.   dataType: dataType  
    7. });  

     

     

    [사용예]

    1. // 요청 Url 만 , 리턴 결과값 무시  
    2. $.post("http://web/test/");  
    3.   
    4. // 요청 Url + 추가적으로 보내는 Json Data, 리턴 결과값 무시  
    5. $.post("http://web/test/", { name: "John", time: "2pm" } );  
    6.   
    7. // 요청 Url + 추가적으로 보내는 Array Data, 리턴 결과값 무시  
    8. $.post("http://web/test/", { 'choices[]': ["Jon""Susan"] });  
    9.   
    10. // 요청 Url + 폼데이터, 리턴 결과값 무시  
    11. $.post("http://web/test/", $("#testform").serialize());  
    12.   
    13. // 요청 Url, xml(또는 html)리턴 결과값  
    14. $.post("http://web/test/",   
    15.       function(data) {    alert("Data Loaded: " + data);  });  
    16.   
    17. // 요청 Url + 추가적으로 보내는 Json Data, 리턴결과값, 결과값 형식  
    18. $.post("http://web/test/", { name: "John", time: "2pm" },    
    19.       function(data) {    process(data);  },   "xml" );  
    20.   
    21. // 요청 Url + 추가적으로 보내는 Json Data, 리턴결과값(json 다루는 형식), 결과값 형식  
    22. $.post("http://web/test/", { "func""getNameAndTime" },    
    23.       function(data){      
    24.                      console.log(data.name); // John      
    25.                      console.log(data.time); //  2pm    
    26.       }, "json");  

     

     

     

     

    2. $.get() 방식

     

    - 서버에 데이터를 HTTP GET 방식으로 전송한 후 서버측 응답 받을 때 사용

     

    [형식]

    jQuery.get(  url [, data] [, success(data, textStatus, jqXHR)] [, dataType] )

     

    - url : 요청 Url

    - data : 요청과 함께 서버에 보내는 string 또는 map

    - success(data,textStatus,jqXHR) : 요청이 성공일때 실행되는 callback 함수

    - dataType : 서버에서 내려온 data 형식. ( default : xml,json,script,text,html )

     

     

    [$.ajax 로 표현]

    1. $.ajax({  
    2.   url: url,  
    3.   data: data,  
    4.   success: success,  
    5.   dataType: dataType  
    6. });  

     

     

    [사용예]

    1. // 요청 Url 만 , 리턴 결과값 무시  
    2. $.get("http://web/test/");  
    3.   
    4. // 요청 Url + 추가적으로 보내는 Json Data, 리턴 결과값 무시  
    5. $.get("http://web/test/", { name: "John", time: "2pm" } );  
    6.   
    7. // 요청 Url + 추가적으로 보내는 Array Data, 리턴 결과값 무시  
    8. $.get("http://web/test/", { 'choices[]': ["Jon""Susan"] });  
    9.   
    10. // 요청 Url, xml(또는 html)리턴 결과값  
    11. $.get("http://web/test/"function(data) {    alert("Data Loaded: " + data);  });  
    12.   
    13. // 요청 Url + 추가적으로 보내는 Json Data, 리턴결과값, 결과값 형식  
    14. $.get("http://web/test/", { name: "John", time: "2pm" },  function(data) {    process(data);  },   "xml" );  
    15.   
    16. // 요청 Url + 추가적으로 보내는 Json Data, 리턴결과값(json 다루는 형식), 결과값 형식  
    17. $.get("http://web/test/", { "func""getNameAndTime" },  function(data){    console.log(data.name); // John    console.log(data.time); //  2pm  }, "json");  

     

     

     

     

    3. $.getJSON() 방식

     

    - 서버에 데이터를 HTTP GET 방식으로 전송한 후 서버측 응답을 JSON 형식으로 받을때 사용 

     

    [형식]

    jQuery.getJSON( url [, data] [, success(data, textStatus, jqXHR)] )

     

    - url : 요청 Url

    - data : 요청과 함께 서버에 보내는 string 또는 map

    - success(data,textStatus,jqXHR) : 요청이 성공일때 실행되는 callback 함수

     

     

    [$.ajax 로 표현]

    1. $.ajax({  
    2.   url: url,  
    3.   dataType: 'json',  
    4.   data: data,  
    5.   success: callback  
    6. });  

     

     

    [사용예]

    1. <script>   
    2.     $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",   
    3.     {   
    4.         tags: "mount rainier",   
    5.         tagmode: "any",   
    6.         format: "json"   
    7.       },   
    8.       function(data) {   
    9.         $.each(data.items, function(i,item){   
    10.           $("<img/>").attr("src", item.media.m).appendTo("#images");   
    11.           if ( i == 3 ) return false;   
    12.         });   
    13.     });  
    14.   </script>  

     

     

     

     

    4. $.ajax() 방식

     

    - 서버에 데이터를 HTTP POST,GET,JSON 모든 방식 전송 가능한 통합적인 함수

    - 다양한 Parameter 존재

     

    [형식]

    jQuery.ajax( url [, settings] ) [ 1.5 이상버젼 ] ,jQuery.ajax( settings ) [ 1.0 이상버젼 ]

     

    - url : 요청 Url

    - settings : key/value 쌍으로 된 Ajax 요청 Set ( optional )

     

     

    [사용예]

    1. // 요청 Url + 추가적 데이터, 완료된 후 리턴 메시지를 받음  
    2. $.ajax({   
    3.       type: "POST",   
    4.       url: "http://web/test/",   
    5.       data: { name: "John", location: "Boston" }   
    6. }).done(function( msg ) {   
    7.       alert( "Data Saved: " + msg );   
    8. });  
    9.   
    10. // 최종 버전 리턴 Html 가져오기  
    11. $.ajax({   
    12.       url: "http://web/test/",   
    13.       cache: false   
    14. }).done(function( html ) {   
    15.       $("#results").append(html);   
    16. });  
    17.   
    18. // 서버에 데이터를 보낸 후 저장처리, 그리고 사용자에게 리턴 완료 메시지 반환  
    19. var menuId = $("ul.nav").first().attr("id");   
    20. var request = $.ajax({   
    21.     url: "http://web/test/",   
    22.     type: "POST",   
    23.     data: {id : menuId},   
    24.     dataType: "html"   
    25. });   
    26.    
    27. request.done(function(msg) {   
    28.     $("#log").html( msg );   
    29. });   
    30.    
    31. request.fail(function(jqXHR, textStatus) {   
    32.     alert( "Request failed: " + textStatus );   
    33. });  
    34.   
    35.   
    36. // 자바 스크립트 로딩 및 실  
    37. $.ajax({   
    38.     type: "GET",   
    39.     url: "test.js",   
    40.     dataType: "script"   
    41. });  

     

     

     

    4.1 $.ajaxSetup()

     

    - 공통적인 기본 ajax 요청을 미리 설정함

     

    [형식]

    jQuery.ajaxSetup( options )

     

    - optional : default Ajax 요청의 설정값 ( key/value )

     

     

    [사용예]

    1. // 미리 ajaxSetup에 기본사항들을 설정한 후 ajax 로 각각 호출  
    2. $.ajaxSetup({  
    3.     url: 'http://web/test/',  
    4.     global: false,   
    5.     type: "POST"   
    6.   
    7. });  
    8. $.ajax({  
    9.       // url not set here; uses 'http://web/test/'  
    10.       data: {'name''Dan'}  
    11. });  
    12. $.ajax({  
    13.       // url not set here; uses 'http://web/test/'  
    14.       data: {'name''John'}  
    15. });  

     

     

     

     

    5. $.load() 방식

    - 외부 컨텐츠 가져올때 사용

     

    [형식]

    .load( url [, data] [, complete(responseText, textStatus, XMLHttpRequest)] )

     

    - url : 요청 Url

    - data : 요청과 함께 서버에 보내는 string 또는 map

    - complete(responseText, textStatus, XMLHttpRequest) : 요청이 완료될때 실행되는 callback 함수

     

     

    [사용예]

    1. //  Html Content 로딩  
    2. $('#result').load('ajax/test.html');  
    3.   
    4. //  Html Content 로딩 후 메시지  
    5. $('#result').load('ajax/test.html'function() {  
    6.   alert('Load was performed.');  
    7. });  
    8.   
    9. //  Html Content #container Target 로딩  
    10. $('#result').load('ajax/test.html #container');  
    11.   
    12. //  array parameter 전달 후 Html Content 로딩  
    13. $("#objectID").load("test.asp", { 'choices[]': ["Jon""Susan"] } );  



    출처: http://killsia.tistory.com/entry/jquery-ajax-방법 [One Day One Line]

    반응형

    'IT > Javascript|Jquery' 카테고리의 다른 글

    javascript 셀렉트박스(SelectBox) 바로실행  (2) 2018.01.04
    ajax 로딩시 새로고침 문제  (6) 2018.01.03
    promise 패턴 예제  (0) 2018.01.02
    모바일/PC 코딩하기  (0) 2018.01.02
    Jquery 셀렉터(Selector) 사용하기  (0) 2018.01.02
    반응형

    출처: https://okky.kr/article/405295

    팁게시판에 좋은글이 있길래 퍼왔습니다


    암호화의 필요성, 전자서명, 인증서와 SSL에 대해서 알아봅니다. 또한 무료 인증서(Let's Encrypt)를 발급 받는 과정을 안내합니다.


    SSL (Secure Sockets Layer)
    Packet Sniffing

    Packet Sniffing

    TCP/IP(또는 TCP 위의 HTTP 같은 응용프로토콜) 패킷이 유선이나 무선 환경을 통해 전송되는 순간을 생각해봅시다. 발신자와 수신자 사이의 네트워크엔 수 많은 라우터나 다른 노드들이 존재하고 있습니다. 이때 이 사이에 위치한 해커는 손쉽게 인터넷을 흐르는 패킷들을 감청(Packet Sniffing) 할 수 있습니다. 즉, 여러분이 로그인을 하기 위해 전송한 아이디나 패스워드가 손쉽게 해커의 손에 들어갈 수 있다는 문제가 있습니다.

    DNS Spoofing

    DNS Spoofing

    또 해커는 피해자에 머신에 DNS Spoofing을 통해 자기 머신의 주소가 서버의 주소인 것처럼 속일 수 있습니다. 이땐 피해자와 서버 사이의 패킷을 중계하면서 정보를 가로채거나 변조 할 수 있습니다.

    TCP - SSL/TLS - Application

    TCP - SSL/TLS - Application

    이러한 문제는 웹 뿐 아니라, TCP/IP를 이용하는 모든 응용프로그램의 보안에 위협이 됩니다. 패킷을 해커가 읽거나 변조 할 수 없도록 암호화하기 위해서 네트워크의 TCP/IP - Application계층 사이에 SSL(Secure Sockets Layer)라는 계층을 고안하였습니다. (TLS; Transport Layer Security; 전송 계층 보안이라고 부르기도 함) 물론 이 때 TCP/IP 위에 SSL을 입히는 것은 응용프로토콜 개발자의 선택사항입니다.

    SSL의 목적

    1. 패킷의 감청 방지
    2. 패킷의 변조 방지
    3. 서버의 신원 인증

    암호화 (Encryption)

    SSL의 구체적인 메커니즘을 살펴보기 전에, 암호화에 대해서 알아보겠습니다. 먼저 헷갈릴 수 있는 용어들과 비교해봅니다.

    인코딩 (Encoding)

    인코딩은 정보의 형태나 형식을 변환하는 처리를 말한다.

    Base64는 바이너리 데이터를 6bit 포맷(26개의 문자로)의 문자열로 변환한다. (간단한 연산으로 복원 가능)

    Base64("The quick brown fox jumps over the lazy dog") = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
    Base64("The quick brown fox jumps over the lazy dog.") = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4="
    Base64("") = ""

    해싱 (Hashing)

    해싱은 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 처리를 말한다.

    SHA-1 해시 함수는 최대 264비트의 메시지로부터 160비트의 해시값을 생성한다. (복원 불가)

    SHA1("The quick brown fox jumps over the lazy dog") = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
    SHA1("The quick brown fox jumps over the lazy dog.") = "408d94384216f890ff7a0c3528e8bed1e0b01621"
    SHA1("") = "da39a3ee5e6b4b0d3255bfef95601890afd80709"

    암호화 (Encryption)

    암호화는 임의의 키를 통해 평문을 암호화하여 암호문으로 만드는 처리를 말한다. 반대로 키를 통해 암호문을 평문으로 만드는 처리는 복화화라고 한다.

    RSA 공개키 암호화 알고리즘은 큰 수를 소인수분해하기 어렵다는 점을 이용한 암호화 알고리즘으로 두개의 큰 소수를 기반으로 두개의 키를 생성하고, 이를 이용해 메세지를 암호화/복호화한다. (키가 있어야 복원 가능)

    두 소수 p=163, q=167을 기반으로 생성한 암호키 e=847, d=127를 선택
    평문 = hello
    평문을 숫자로 표현 = 104 101 108 108 111
    위 숫자를 e를 통해 암호화 = 16078 6642 1822 1822 13509
    암호문을 d를 통해 복호화 = hello
    

    이제 인코딩, 해싱, 암호화를 구분 할 수 있다면, 암호화의 두가지 방식에 대해서 알아보겠습니다.

    대칭키 암호화

    먼저 기원전부터 쓰인 대칭키 암호화 방식의 원리는 발신자와 수신자가 동일한 알고리즘과 그 열쇠를 공유하는 방식입니다. 쉽게는 알파벳을 1칸 앞으로(secret key) 옮기는 방식의 암호 알고리즘을 이용하면 hello는 ifmmp로 암호화 될 수 있으며, 마찬가지로 암호 키를 알고 있다면 역으로 복호화 할 수도 있습니다. 근대의 대칭키 암호화 역시 근본적으로 위와 같은 원리를 사용합니다.

    대칭키 방식은 속도가 빠르고 연산량이 적지만, 키가 유실되면 보안 체계가 그대로 무너지기 때문에 키의 분배가 힘들다는 단점을 갖습니다.


    비대칭키 암호화

    대칭키의 키 분배 문제를 해결한 비대칭키 암호화 방식은 비대칭키와 달리 공개키(Public Key), 개인키(Private Key)라고 불리는 두개의 키를 생성합니다. 이 때 공개키로 암호화한 암호문은 개인키로만 복호화가 가능하며, 개인키로 암호화한 암호문은 공개키로만 복호화가 가능합니다.

    이를 통해 발신자는 사전에 입수한 수신자의 공개키로 메세지를 암호화하고, 수신자는 전달 받은 암호문을 개인키로 복호화 할 수 있습니다.

    비대칭키 방식은 서버-클라이언트와 같은 일대다 구조에서 키의 분배 문제를 해결할 수 있지만, 속도가 느리고 연산량이 많은 단점이 있습니다.

    전자서명 (Digital Signature)

    대표적인 비대칭키 알고리즘인 RSA는 대표적으로 전자서명에 많이 이용되고 있습니다. 전자서명은 말그대로 데이터의 작성자를 증빙하기 위해 데이터에 전자적인 서명을 첨부하는 것을 뜻합니다. 물론 전자서명은 수기서명과 동일한 효력을 지니고 있습니다.

    Digital Signature with RSA

    Digital Signature with RSA

    전자서명의 메커니즘은 비대칭키 암호화에 그 기반을 둡니다. 우선 원본 데이터를 공개된 방법으로 해싱하여 특정 길이의 문자열로 만듭니다. 그 해시값을 작성자의 개인키로 암호화한 전자서명을 생성하여 원본 데이터에 첨부하고, 수신자에게 발송합니다. 이후에 수신자는 받은 전자서명을 작성자의 공개키로 복호화하고 이를 받은 데이터를 해싱한 해시값과 비교합니다. 이때 두 해시값이 동일한지 비교하여 데이터의 작성자와, 데이터가 변조되지 않았음을 검증할 수 있습니다.

    인증서 (Certificate)

    자, 데이터를 안전하게 암호화하고 또 전자서명하여 교환하는데 성공했습니다. 하지만 한가지 더 문제가 남아있습니다. 단순히 전자서명만으로는 데이터 생성자, 즉 공개키 소유자의 실제(오프라인) 신원을 증빙할 수 없다는 문제입니다.

    여기서 공개키/개인키 키 쌍의 소유자의 신원을 보증하기 위해서 인증서(Certificate)라는 개념이 등장합니다. 사용자들은 암호화나 전자서명에 이용할 키 쌍을 정부기관이나 은행 등 공인된 기관에서 개인정보를 인증하며 발급 받을 수 있습니다. 이 때 발급자는 기관으로부터 생성된 개인키와 그에 대한 인증서를 받게 됩니다. 이 때 그 인증서에는 일반적으로 아래와 같은 정보가 포함됩니다.

    공인인증서

    공인인증서

    • 발급자의 신원 정보
    • 발급자의 공개키
    • 인증 유효기간
    • 인증기관 정보
    • 위 모든 내용에 대한 인증기관의 전자서명

    즉, 인증서란 공개키와 그에 대한 인증기관의 보증으로 볼 수 있습니다. 다시말해서 본인의 인증서를 제공한다는 의미는, 본인의 공개키와 그 보증을 전달하는 것과 같습니다. 인증서와 그에 포함된 공개키를 통해 전자서명이나 암호화시에 데이터의 무결성을 검증 할 수 있습니다. (물론 인증서 발급 기관을 신뢰 할 수 있을 때)

    물론 인증기관의 서명 대신에 자신의 전자서명을 첨부하여 (Self-Signed) Root 인증서를 만들 수도 있습니다.

    인증기관 (CA; Certification Authority)

    비대칭키 암호화의 속성을 이용하면, 데이터를 암호화하고, 데이터에 전자서명을 첨부하고, 인증서를 통해서 데이터 생성자의 신원을 보증 할 수 있습니다. 이처럼 공개키 및 인증서를 활용하는 소프트웨어, 플랫폼, 정책, 제도 등을 통틀어 공개키 기반 구조 (PKI; Public Key Infrastructure)라고 합니다. HTTPS, SFTP, SSH, SCP 등 SSL 위에서 작동하는 프로토콜, 또는 공인 인증서를 이용한 금융거래까지 모두 PKI에 속한다고 볼 수 있겠습니다.

    X.509 구조

    X.509 구조

    앞서 다룬바처럼 PKI에서 본인의 신원(공개키)을 인증서로 인증 할 필요가 있는 경우엔 공인된 인증서가 필요합니다. 이러다보니 PKI와 그 인증기관에 따라서 인증서의 포맷이 제각각일 수 있습니다. 이러한 상황에서 인증서의 범용성을 높히고, 웹(https) 같은 범국제적인 PKI를 위해서 X.509라는 인증서의 국제적인 표준 규격이 자리잡았습니다.

    연쇄적인 인증 구조

    연쇄적인 인증 구조

    X.509에서 인증서는 기본적으로 최상위 인증기관(CA; Certification Authority)의 루트 인증서를 시작으로 하위 인증기관들의 인증서를 타고 내려가 일반 사용자들의 인증서까지 연쇄적으로 상위 기관이 하위 기관을 인증하는 트리 구조를 띄고 있습니다. 따라서 사용자가 Root CA의 인증서(최상위 인증서는 자가서명되어 있음)를 신뢰 한다면, 그 하위의 모든 인증서를 신뢰 할 수 있는 구조가 됩니다.

    한국의 공인인증서 및 개인키 역시 파일 양식 자체는 국제표준을 따르고 있지만, 그 파일들이 보관, 저장되는 위치와 방법이 독특하여 웹브라우저로는 사용이 불가능하다. 그 결과, 한국의 공인인증서를 이용하려면 이용자가 추가프로그램을 반드시 설치해야만 한다. 인증서는 원래 금융거래에만 사용되는 것이 아니라, 모든 전자적 거래(금전적이건 비금전적이건)에서 당사자의 신원을 확인하거나, 전자서명을 하는 용도로 사용될 수 있고, 한국의 공인인증서도 물론 그런 다양한 용도로 사용될 수 있다. 그러나 현실적으로 공인인증서는 전자금융거래에서 주로 사용되고 있다. 금융위원회는 전자금융거래에 "공인인증서 등"을 사용하도록 강제하고 있다가 의무사용 폐지됐다. ... (위키백과)

    SSL HandShake

    SSL의 목적

    1. 패킷의 감청 방지
    2. 패킷의 변조 방지
    3. 서버의 신원 인증

    다시 본래의 주제 SSL로 돌아와서, SSL의 목적을 생각해보면, 이제 그 해답지가 보입니다. 비대칭키를 이용해 TCP 패킷들을 암호화(패킷의 감청 방지)하고, 패킷에 전자서명을 첨부하며(패킷의 변조 방지), 서버 측에서 공개키에 대한 인증서를 제공(서버의 신원 인증)한다면 모든 목적을 달성 할 수 있겠습니다. 
    (하지만 SSL이라고 완벽하진 않습니다. 중간자 공격 등, 지속적인 보안 취약점이 발생하고 있습니다.)

    SSL Session Flow

    SSL Session Flow

    SSL 연결 과정 (SSL HandShake)

    1. 서버는 클라이언트에게 인증서(+공개키)를 전달
    2. 이때 클라이언트는 서버의 인증서를 본인이 미리 알고있는 CA 목록을 통해 검증해서, 신뢰할 수 없는 서버의 경우에 유저에게 경고 할 수 있음
    3. 클라이언트는 대칭키 하나를 생성해 서버의 공개키로 암호화하여 서버에 전달
    4. 이후 양측간에 주고 받는 데이터는 대칭키로 암호화

    SSL에서는 비대칭키를 통해서 최초로 연결을 맺지만, 실제 통신에서는 서버측의 연산량을 절감하기 위해서 대칭키를 사용합니다. (비대칭키의 복호화 연산량은 대칭키 보다 약 1,000배 크다고 함)

    HTTPS (HTTP over SSL)
    HTTPS (Verified)

    HTTPS (Verified)

    여기까지 인터넷 암호화 및 전자서명에 대한 기본적인 배경지식을 습득했습니다. 이제 본연의 웹으로 돌아가서, 웹서버에 SSL을 적용한 HTTPS를 구현해보도록 하겠습니다.

    HTTPS (Not verified)

    HTTPS (Not verified)

    본인 스스로 서명한 인증서(Root Certificate)를 생성해서 HTTPS 웹서버를 구축 할 수도 있습니다. 하지만 위처럼 공인된 인증서가 아니기 때문에 클라이언트의 신뢰를 얻기 힘듭니다. 따라서 공인 인증서를 발급하게 되는데, 이때 일반적으로 인증서는 유료로 발급 받을 수 있습니다.

    왜냐면 CA은 발급자에게 서비스를 제공해야하며, 인증서 발급자의 도메인 소유 정보를 확인해야하고, 발급자들의 인증 정보를 갱신하며, 웹브라우저들에게 본 기관의 Root Certificate를 내장하도록 부탁해야 하는 등, CA의 역할을 맡는데 여러 비용이 수반되기 때문입니다. 대표적인 국제 공인 CA 중에는 Comodo, Symantec (Verisign), GoDaddy 등이 있습니다.

    국내에서는 한국인터넷진흥원(KISA)을 Root CA로 두는 국가 공개키 기반 구조 (NPKI; National Public Key Infrastructure)라고 불리는 PKI가 자리잡고 있습니다. 하지만 KISA에서 아직까지 국제 Root CA 검증 감사를 받지 않아서, 국내 CA에서 발급 받은 인증서는 특정 웹 브라우저들에게 신뢰받지 못 할 수도 있습니다.

    Let's Encrypt

    Let's Encrypt

    그러던 와중 2016년도에 Mozilla, Sisco, Akamai 등의 기업들이 Let's Encrypt라는 비영리 CA를 설립하고, HTTPS의 보급을 위해서 무료로 인증서를 발급해주고 있습니다.https://letsencrypt.org 에서 기부 및 안내를 볼 수 있고, https://certbot.eff.org 에서 인증서를 발급 받는 방법을 설명 받을 수 있습니다.

    위의 certbot 웹사이트로 접속하면 운영중인 웹서버 종류 및 서버 OS를 선택 할 수 있습니다. 이후에 certbot 이라는 인증서 발급 및 갱신 프로그램을 설치하고, 실제로 발급 받는 방법에 대한 안내를 받을 수 있습니다. 여기서는 AWS 리눅스 환경에서 Node.js(Express) 웹서버에 SSL을 적용하는 과정을 적어보겠습니다.

    1. certbot 설치 및 인증서 발급

    # ssh로 도메인이 연결된 서버에 접속합니다.
    dehypnosis-mac:keys dehypnosis$ ssh ec2-user@benzen.io
    
    # wget은 주어진 URL에서 파일을 다운로드하는 프로그램입니다.
    [ec2-user@benzen ~]$ wget https://dl.eff.org/certbot-auto
    
    # 실행 권한을 주고
    [ec2-user@benzen ~]$ chmod a+x certbot-auto
    
    # 관리자 권한으로 실행하면, 이메일 주소 입력, 약관 동의, 이메일 공개(옵션)의 과정을 거칩니다.
    # 이후에 certbot 프로그램이 자동으로 도메인 소유권을 인증하고, 인증서 및 개인키를 생성합니다.
    # 서버 머신에 이미 Apache나 다른 웹서버가 설치되어 있따면, [1]이나 [3]의 옵션을 사용 할 수 있습니다.
    # 그 외의 경우에는 단순히 [2]를 선택하면 certbot이 임시로 80 또는 443 포트에 웹서버를 가동하여 도메인 소유권을 확인합니다.
    [ec2-user@benzen ~]$ ./certbot-auto certonly
    FATAL: Amazon Linux support is very experimental at present...
    if you would like to work on improving it, please ensure you have backups
    and then run this script again with the --debug flag!
    Alternatively, you can install OS dependencies yourself and run this script
    again with --no-bootstrap.
    [ec2-user@benzen ~]$ sudo ./certbot-auto certonly
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    
    How would you like to authenticate with the ACME CA?
    -------------------------------------------------------------------------------
    1: Apache Web Server plugin - Beta (apache)
    2: Spin up a temporary webserver (standalone)
    3: Place files in webroot directory (webroot)
    -------------------------------------------------------------------------------
    Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 2
    Enter email address (used for urgent renewal and security notices) (Enter 'c' to
    cancel):kim@benzen.io
    
    -------------------------------------------------------------------------------
    Please read the Terms of Service at
    https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
    in order to register with the ACME server at
    https://acme-v01.api.letsencrypt.org/directory
    -------------------------------------------------------------------------------
    (A)gree/(C)ancel: a
    
    -------------------------------------------------------------------------------
    Would you be willing to share your email address with the Electronic Frontier
    Foundation, a founding partner of the Let's Encrypt project and the non-profit
    organization that develops Certbot? We'd like to send you email about EFF and
    our work to encrypt the web, protect its users and defend digital rights.
    -------------------------------------------------------------------------------
    (Y)es/(N)o: y
    Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
    to cancel):workshop.benzen.io
    Obtaining a new certificate
    Performing the following challenges:
    tls-sni-01 challenge for workshop.benzen.io
    Waiting for verification...
    Cleaning up challenges
    
    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at
       /etc/letsencrypt/live/workshop.benzen.io/fullchain.pem. Your cert
       will expire on 2017-08-27. To obtain a new or tweaked version of
       this certificate in the future, simply run certbot-auto again. To
       non-interactively renew *all* of your certificates, run
       "certbot-auto renew"
     - Your account credentials have been saved in your Certbot
       configuration directory at /etc/letsencrypt. You should make a
       secure backup of this folder now. This configuration directory will
       also contain certificates and private keys obtained by Certbot so
       making regular backups of this folder is ideal.
     - If you like Certbot, please consider supporting our work by:
    
       Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
       Donating to EFF:                    https://eff.org/donate-le
    
    2. 인증서 및 개인키 확인

    # 인증서 및 개인키(실제 파일의 바로가기 파일; 또는 symbolic link)는 다음 경로에 생성되어 있습니다.
    [ec2-user@benzen ~]$ sudo ls /etc/letsencrypt/live/workshop.benzen.io
    README  cert.pem  chain.pem  fullchain.pem  privkey.pem
    
    # privkey.pem: 개인키를 Base64로 인코딩한 텍스트 파일입니다.
    # fullchain.pem: 서버의 인증서와 상위 기관의 인증서를 Base64로 인코딩한 텍스트 파일입니다.
    # cert.pem, chain.pem: cert.pem + chain.pem = fullchain.pem (일반적으로 fullchain.pem이 필요)
    
    [ec2-user@benzen ~]$ sudo cat /etc/letsencrypt/live/workshop.benzen.io/README
    This directory contains your keys and certificates.
    
    `privkey.pem`  : the private key for your certificate.
    `fullchain.pem`: the certificate file used in most server software.
    `chain.pem`    : used for OCSP stapling in Nginx >=1.3.7.
    `cert.pem`     : will break many server configurations, and should not be used
                     without reading further documentation (see link below).
    
    We recommend not moving these files. For more information, see the Certbot
    User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.
    

    Let's Encrypt, certbot을 떠나서, 인증서 발급 과정에서 기억 할 점은, CA가 도메인 소유권을 인증하고, 인증서 및 개인키를 생성해준다는 점입니다.
    CA에 따라서 인증서 발급 과정이 웹 UI상에서 이루어질 수도 있고, Let's Encrypt처럼 셸 프로그램을 제공 할 수도 있습니다.

    3. 서버에 HTTPS 적용

    // Express.js의 경우엔 아래처럼 443 포트에 https 서버를 실행시킬 수 있습니다.
    // http의 기본 포트가 80인 것처럼, https의 기본 포트는 443입니다.
    const path = require('path');
    const fs = require('fs');
    const https = require('https');
    const app = express();
    
    // ... 서버 로직
    
    const sserver = https.createServer({
      key: fs.readFileSync('./ssl/privkey.pem'),
      cert: fs.readFileSync('./ssl/fullchain.pem'),
    }, app).listen(443);
    console.log('Secure server running at port 443');
    
    // 같은 로직의 http 서버를 동시에 운영 할 수 도 있습니다.
    const server = https.createServer(app).listen(80);
    console.log('Non-Secure server running at port 80');
    

    Apache, Nginx, Tomcat, IIS 등, 기타 상용 서버를 사용하는 경우에는 플랫폼에서 제공하는 방법에 따라서 개인키와 인증서를 연결하고 특정 포트에 https 서버를 실행 할 수 있습니다. 주의사항은 Let's Encrypt의 인증서의 유효기간은 90일이기 때문에, 만료일이 다가올 때마다 certbot을 이용해서(ex; sudo ./certbot-auto renew) 갱신하거나, Cron 등의 운영체제 서비스에 스크립트를 등록하여 이 과정을 자동화 할 필요가 있습니다.

    (심화) SSH vs SSL/TLS에 대해서

    이전에 공부했던 SSH 또한 SSL/TLS처럼 핸드쉐이킹에 비대칭키를, 패킷 통신에는 대칭키를 이용합니다. 또한 응용 프로세스를 위해서 TCP 패킷을 암호화하는 것도 동일합니다.

    그렇다면 두 암호화 프로토콜이 어떻게 다르게 쓰이는 지 고민해볼 수 있겠습니다. 이 부분은 심화적인 내용이므로 사전에 설명하지 않은 용어들이 나올 수 있습니다. 네트워크, 암호화 및 SSH 프로토콜에 관심이 있는 분들이 읽어 보시길 바랍니다.


    SSH는 일반적으로 엔드유저를 위한 ssh 클라이언트 프로그램을 의미하지만, 응용 프로토콜 하위의 하나의 암호화 프로토콜로도 볼 수 있겠습니다.

    SSL/TLS는 인증서 포맷으로 X.509을, SSH는 독자적 포맷(ssh-keygen 프로그램을 통해서 생성)을 쓴다는 점을 제외하면, 모든 SSL과 SSH 응용은 대체가 가능합니다. FTPS(FTP over SSL)와 SFTP(Secure FTP), HTTPS와 SHTTP는 모두 비대칭키와 대칭키 암호화를 이용하므로 보안에 있어서 원리적인 차이가 없습니다.

    둘은 비슷한 역할을 수행하지만, 그 응용 방식에서는 큰 차이가 납니다. SSH는 서버에서 sshd를 22포트에 열고 ssh 클라이언트와 암호화된 패킷을 주고 받으면서 포트 포워딩; 프로세스 간에 패킷을 중계하는 방식으로 응용됩니다. 실제로 sftp, scp, ssh 클라이언트의 트래픽은 모두 sshd의 22포트로 들어갑니다.

    SSH 터널링을 통해 패킷을 암호화하고 방화벽을 우회

    SSH 터널링을 통해 패킷을 암호화하고 방화벽을 우회

    이처럼 SSH를 응용하는 프로그램은 항상 SSH 터널링(터널은 ssh 클라이언트로 쉽게 생성 할 수 있음)을 응용합니다. 또한 이러한 특성으로 SSH는 방화벽 우회 및 프록시 구축, 또는 외부에서 기존 프로그램의 패킷을 암호화하는 등에 많이 쓰이고 있습니다.

    이처럼 SSH는 여러 서버 호스트와의 연결 및 응용에 쓰이는 프로토콜 내지는 활용도가 높은 프로그램입니다. 이렇게 ssh 클라이언트가 다용도로 쓰이기 때문에, ssh 클라이언트는 핸드쉐이크 과정에서 (기본적으로) 로컬의 공개키를 무더기로 보냅니다.

    반면에 SSL/TLS는 포트포워딩 방식보다는 각 응용 프로토콜마다 개별 포트를 바인딩하고, 서버 프로세스 자체에서 인증서를 갖고 핸드쉐이킹 과정을 처리하고 패킷을 주고 받습니다. 따라서 SSL/TLS를 응용하기 위해서는 프로그램에서 내부적으로 프로토콜 수준부터 구현해야 하겠습니다.

    위 내용을 정리하자면 SSH나 SSL/TLS는 모두 암호화를 위한 프로토콜로 볼 수 있고, SSH는 SSL/TLS에 비해 더 이식성있게 응용 할 수 있다는 생각입니다.


    반응형

    'IT > Etc' 카테고리의 다른 글

    시도해볼만한 프로그래밍언어 8종  (0) 2018.01.24
    네트워크 관리사 족보/네트워크 관리사 2급  (0) 2018.01.12
    구글 검색유입 추가시키기  (1) 2018.01.08
    SVN Ignore 사용하기  (2) 2018.01.08
    애드센스 적용해보기  (0) 2018.01.02
    반응형

    참고 : http://doolyit.tistory.com/15




    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //모바일/PC 스크립트 인식 구분
     
    var filter = "win16|win32|win64|mac|macintel";
     
            
     
    if (filter.indexOf(navigator.platform.toLowerCase()) < 0) {
     
    //MOBILE                  
     
    }else {
     
    //PC                                                                       
     
    }
    cs



    웹 사이트에서 PC 환경에서 접속했는지

    모바일에서 접속했는지 확인하기위해 적는 코드로 주로

    반응형웹일때 모바일로 들어왔을때 스크립트 나 css 조작을 다르게 해야할때 사용했던것같다


    최근 개발 중 PC, MOBILE 을 구분하여 처리하는 로직에서 오류가 발생하였습니다.

    결제 모듈을 호출하는 부분에서 PC 모듈을 호출해야 하지만 MOBILE 모듈을 호출하여 발생한 문제였습니다.

    지금까지 잘 되던게 왜 갑자기 안될까?

    의문을 갖고 PC, MOBILE 구분 함수를 찾아보았습니다.

    함수는 아래와 같이 코딩되어 있었습니다.

    (인터넷에서 많이 볼 수 있는 코드죠..)


    -- JavaScript

    var filter = "win16|win32|win64|mac";

    var vWebType = "";


    if (navigator.platform ) {

    if (filter.indexOf(navigator.platform.toLowerCase()) < 0) {

    vWebType = "MOBILE";

    } else {

    vWebType = "PC";

    }

    }


    -- 사용자 User-Agent 는 아래와 같았습니다.

    mozilla/5.0 (macintosh; intel mac os x 10_12_3) applewebkit/537.36 (khtml, like gecko) chrome/56.0.2924.87 safari/537.36


    예전에는 User-Agent 로 MOBILE 인지 아닌 지 체크를 많이 했었는데 (아닌가요..? -.-;;) 모바일 디바이스의 종류가 매우 방대해짐에 따라 

    PC, MOBILE 체크 시에 MOBILE 인지 아닌지 보다는 PC 인지 아닌지 여부로 체크를 하는 게 보편화된 것 같습니다.

    아무튼 지금까지는 위 처럼 사용되는 로직에 문제가 없다가 왜 갑자기 발생된 걸까요?

    찾아보니 PC 종류 하나가 빠져있었습니다.

    Javascript Navigator 의 Platform 정보로 조회 되는 PC 기기는 아래 5가지 종류입니다.


    Win16 : 16비트 윈도위기반 컴퓨터

    Win32 : 32비트 윈도위기반 컴퓨터

    Win64 : 64비트 윈도위기반 컴퓨터

    MacIntel  :  인텔CPU 를 가진 매킨토시 컴퓨터

    Mac : 매킨토시컴퓨터


    위의 5가지의 디바이스 정도가 PC 로 접속 시 조회 가능한 Navigator Platform 의 값입니다.

    이 외의 것은 모바일로 봐도 될 거라고 합니다.

    이렇게 찾아보니 하나가 빠졌더군요. 


    MacIntel  :  인텔CPU 를 가진 매킨토시 컴퓨터


    .... 매킨토시는 매킨토신데 CPU 가 인텔 꺼랍니다..


    var filter = "win16|win32|win64|mac|macintel";


    로 변경하여 처리 완료되었네요.


    참고로 Navigator Object 의 Properties 관련 내용 메모해 보겠습니다.


    콘솔이나 알럿으로 확인 가능하겠습니다.

    ex: console.log(navigator.userAgent);


    navigator.appCodeName : 웹브라우저 코드이름

    navigator.appName : 웹브라우저 이름

    navigator.appVersion : 웹브라우저 버전

    navigator.cookieEnabled : 웹브라우저 쿠키 사용 가능 유무

    navigator.language : 웹브라우저 언어

    navigator.onLine : 사용자 온라인 상태 여부

    navigator.platform : 플랫폼

    navigator.userAgent : 브라우저 구분값(웹브라우저 이름 전체)


    출처: http://thingsthis.tistory.com/162 [여행과 일상]




    PC에서 모바일 페이지로 이동하기 입니다.


    보통 PC와 모바일 버전이 따로 있는 경우 ( 레이아웃 반응형이 아닌 별도의 페이지의 있는 경우) 에는 모바일 페이지 URL을 따로 사용한다.


    m.url.com 이라던지 url.com/m/main.do 등의 컨셉을 사용할 때 적용하는 방법!


    모바일 디바이스를 확인하는 소스는 매우 흔한듯..


    다음과 같이 적용하면 매우 쉽게! 적용 가능~


    메인 JSP 파일이나, JAVA에서 적용하면 될 듯 쉽다..(JSP에서만 해봄..)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    String ua=request.getHeader("User-Agent").toLowerCase();
     
    if (ua.matches(".*(android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino).*")||ua.substring(0,4).matches("1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|e\\-|e\\/|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\\-|2|g)|yas\\-|your|zeto|zte\\-")){
     
          response.getWriter().println("<script type=\"text/javascript\">");
     
          response.getWriter().println("if ( confirm('모바일 전용 페이지로 이동하시겠습니까?') ) {");
     
          response.getWriter().println("location.href='MOBILE URL' } else { location.href='PC URL' }");
     
          response.getWriter().println("</script>");
     
    }else {
     
        response.sendRedirect("index.action");  
     
    }
    cs



    출처: http://devofhwb.tistory.com/50 [이든의 생활코딩]

    반응형

    'IT > Javascript|Jquery' 카테고리의 다른 글

    javascript 셀렉트박스(SelectBox) 바로실행  (2) 2018.01.04
    ajax 로딩시 새로고침 문제  (6) 2018.01.03
    promise 패턴 예제  (0) 2018.01.02
    ajax 배열전송  (0) 2018.01.02
    Jquery 셀렉터(Selector) 사용하기  (0) 2018.01.02
    반응형

    Jquery 셀렉터로 특정 단어로 시작해서 특정 단어로 끝나는

    (ex: a-xxxx-b)

    값을 지정할수있다


    예제


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    <!DOCTYPE html>
     
    <html>
     
    <head>
     
    <style>
     
    .siblings * { 
     
        display: block;
     
        border: 2px solid lightgrey;
     
        color: lightgrey;
     
        padding: 5px;
     
        margin: 15px;
     
    }
     
    </style>
     
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
     
    <script>
     
    $(document).ready(function(){
     
       
     
        $( "li[id^='start-'][id$='-end']" ).css({"color""red""border""2px solid red"});
     
    });
     
    </script>
     
    </head>
     
    <body>
     
     
     
    <div style="width:500px;" class="siblings">
     
      <ul>ul (parent)  
     
        <li>li (sibling)</li>
     
        <li>li (sibling)</li>
     
        <li id="start-test-end">li (sibling with class name "start")</li>
     
        <li>li (the next sibling of li with class name "start")</li>
     
        <li>li (the next sibling of li with class name "start")</li>
     
        <li id="start-test2-end">li (the next sibling of li with class name "start")</li>
     
        <li id="start-test2-endd">li (sibling with class name "stop")</li>
     
      </ul>   
     
    </div>
     
     
     
    <p>In this example, we return all next sibling elements between the 
    li element with class name "start" and the li element with class name "stop".</p>
     
     
     
    </body>
     
    </html>
    cs



    추가로 자주 사용하는 셀렉터를 정리해 보았다


    1
    2
    3
    4
    5
    6
    $("div[id!='a']")// div 에 id가 a가 아닌 태그들 선택
    $("div[id^='a']")// div 에 id가 a로 시작하는 태그들 선택
    $("div[id$='a']")// div 에 id가 a로 끝나는 태그들 선택
    $("div[id*='a']")// div 에 id가 a가 포함된 태그들 선택
     
     
    cs


    1
    2
    3
    4
     $( "li[id^='start-'][id$='-end']" ) //and 개념
     $( "li[id^='start-'],li[id$='-end']" ) //or 개념
     
     
    cs


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

    안녕하세요. 문학청년입니다. 정말 오랜만에 이렇게 글을 쓰는 것 같네요. 스터디 준비하랴.. 대회 준비하랴.. 요세 조금 바빠서 글 쓰는 것에 너무 소홀해버렸네요. 그럼 앞으로 다시 분발하여 열심히 쓰도록 하겠습니다.

    잡설이 너무 길었네요. 오늘은 다름이 아니라 제가 처음이 연재 기획했던 것과는 달리 오늘은 기본 내용을 간략하게 정리해볼까 합니다. 물론 정리된 내용만 보면 재미가 없겠지요. 그래서 여러분들을 위해서 간단하게 할 수 있는 셀렉터 예제를 만들어봤습니다. 이 예제는 jQuery 오프라인 스터디에서도 사용을 했었는데요. 반응이 좋아서 이렇게 연재 강좌에도 예제로 사용해봤습니다.

    한가지 팁을 드리자면 아래 정리된 내용을 출력하여 필요할 때마다 보는 것도 좋을 것 같구요.
    아래 정리된 내용들을 살펴 본 뒤에 예제 페이지로 가서 직접 실습해보시면 이해하시는데 도움이 될 것입니다.

    예제 페이지 이동하기



    (1) Javascript 문법 스타일

    기존의 프로그래밍 언어의 엄격한 문법 스타일에 적용되어 있는 사용자라면 분명히 자바스크립트의 자유 분방한 문법 스타일을 보고 적지않게 당황한적이 있을 것이다. 이러한 스타일은 단점이 될 수도 있으나 매우 유연하기 때문에 때에 따라서 매우 강력한 기능을 발휘한다. 그렇다면 가장 많이 사용되는 자바스크립트의 함수와 관련된 문법 스타일에 대해서 알아보도록 하자.

    1. 함수를 변수에 설정할 수 있다.
    1
    2
    3
    var func = function() {
         alert("안녕");
    };


    2. 변수에 설정한 함수를 매개 변수로 사용하여 호출 할 수 있다.
    1
    showAlert(func);


    3. 위와 같이 변수에 담지 않고 바로 함수를 매개 변수로 바로 설정 할 수 있다.
    1
    2
    3
    4
    5
    6
    showAlert(function() {
         alert("안녕");
    });

    // 아래와 같이 한 줄로 사용하는 경우도 있다.
    showAlert(function() { alert("안녕"); });


    3번의 경우 조금 어렵게 생각할 수도 있는데 자세히 보면 그냥 함수 파라메터 값에 변수가 아닌 함수 그 자체가 들어가 있다고 간단하게 생각하면 된다. 이러한 표현식은 jQuery에서 상당히 많이 쓰이기 때문에 이러한 문법 스타일에 최대한 빨리 익숙해져야 한다.


    (2) 셀렉터 요약 정리

    셀렉터는 jQuery의 가장 강력한 기능이다. 간단하게 설명을 하자면, HTML 문서 안에는 다양한 엘리먼트들이 포함되어 있는데, 이를 컨트롤하기란 결코 간단한 일이 아니다. 일반적으로 자바스크립트에서 엘리먼트를 얻기 위해 많이 쓰이는 방법은document.getElementById("엘리먼트 ID 속성 값") 함수를 사용하면 되지만, 일단 소스 코드가 길어지고 얻을 수 있는 엘리먼트들도 매우 한정적이다.

    하지만 jQuery에서는 $("셀렉터 문법") 함수를 사용하여 매우 간단하고 다양한 스타일의 엘리먼트들을 쉽게 얻을 수 있다. 셀렉터로 얻은 엘리먼트들을 확장 집합이라 하는데, 특수한 배열 형태의 객체로 반환이 된다. 이렇게 반환된 객체들은 jQuery가 지원하는 매우 다양한 함수들을 사용할 수 있다.

    아래 표에 나와 있는 자식/에트리뷰트/컨테이너 셀렉터는 가장 많이 사용되는 셀렉터 문법이다.

    셀렉터 문법
    문법 설명
    *
    모든 엘리먼트
    E
    태그 명이 E인 모든 엘리먼트
    E F
    E의 자손이면서 태그명이 F인 모든 엘리먼트
    E>F
    E의 바로 아래 자식이면서 태그 명이 F인 모든 엘리먼트
    E+F
    E의 형제 엘리먼트로 바로 다음에 오는 엘리먼트 F
    E~F
    E의 형제 엘리먼트로 다음에 나오는 모든 엘리먼트 F
    E:has(F)
    태그 명이 F인 자손을 하나 이상 가지는 태그 명이 E인 모든 엘리먼트
    E.C
    클래스 명 C를 가지는 태그 명이 E인 모든 엘리먼트. E의 생략은 *.C와 동일함
    E#I
    아이디가 I인 태그 명이 E인 엘리먼트. E의 생략은 *#I와 동일
    E[A=V]
    값이 V인 에트리뷰트 A를 가지는 태그 명이 E인 엘리먼트
    E[A=V]
    값이 V로 시작하는 에트리뷰트 A를 가지는 태그 명이 E인 엘리먼트
    E[A$=V]
    값이 V로 끝나는 에트리뷰트 A를 가지는 태그 명이 E인 엘리먼트
    E[A*=V]
    값이 V를 포함하는 에트리뷰트 A를 가지는 태그 명이 E인 엘리먼트
    E[A]
    에트리뷰트 A를 가지는 태그 명이 E인 모든 엘리먼트
    [자식/에트리뷰트/컨테이너 셀렉터]

    아래 표는 jQuery가 지원하는 고급 위치 기반 셀렉터이며, DOM에서 위치를 기반으로 엘리먼트를 선택하며 첫 번째 링크나 홀수 번째, 짝수 번째와 같이 엘리먼트의 위치나 다른 엘리먼트와 관계를 기반으로 엘리먼트를 선택해야 하는 경우에 사용하면 된다.

    셀렉터 문법
    문법 설명
    E:first
    모든 엘리먼트 E 중에서 첫 번째인 엘리먼트
    E:last
    모든 엘리먼트 E 중에서 마지막인 엘리먼트
    E:first-child
    엘리먼트 E의 자식 엘리먼트 중에서 첫 번째인 엘리먼트
    E:last-child
    엘리먼트 E의 자식 엘리먼트 중에서 마지막인 엘리먼트
    E:only-child
    엘리먼트 E의 자식 엘리먼트 중에서 형제가 없는 엘리먼트
    E:nth-child(n)
    엘리먼트 E의 n번째 자식 엘리먼트
    E:nth-child(even or odd)
    엘리먼트 E의 홀수 or 짝수 자식 엘리먼트
    E:even or E:odd
    페이지 전체의 짝수 or 홀수 엘리먼트
    E:eq(n)
    태그 값이 E인 모든 엘리먼트 중에서 n번째로 일치하는 엘리먼트
    E:gt(n)
    태그 값이 E인 모든 엘리먼트 중에서 n번째 엘리먼트(포함 X) 이후의 엘리먼트
    E:lt(n)
    태그 값이 E인 모든 엘리먼트 중에서 n번째 엘리먼트 이전의 엘리먼트
    [위치 셀렉터]

    CSS 명세만으로는 표현할 수 없는 특성이 있는 엘리먼트를 선택해야 하는 경우 아래 표에 나와 있는 셀렉터를 사용하면 된다.

    셀렉터 문법
    문법 설명
    :animated
    현재 애니매이션이 적용되고 있는 엘리먼트 선택
    :button
    모든 버튼 선택
    :checkbox
    체크 박스 엘리먼트만 선택 (input[type=checkbox])
    :checked
    선택된 체크 박스나 라디오 버튼만을 선택
    :contains(foo)
    텍스트 foo를 포함하는 엘리먼트만 선택
    :disabled
    인터페이스에서 비활성화 상태인 모든 폼 엘리먼트를 선택
    :enabled
    인터페이스에서 활성화 상태인 모든 폼 엘리먼트를 선택
    :file
    모든 파일 엘리먼트를 선택 (input[type=file])
    :header
    헤더 엘리먼트 선택 (<h1>~<h6>)
    :hidden
    감춰진 엘리먼트만 선택
    :image
    폼 이미지만 선택 (input[type=image])
    :input
    폼 엘리먼트만 선택 (input, select, textarea, button)
    :not(filter)
    필터의 값을 반대로 변경함.
    :parent
    빈 엘리먼트를 제외하고, 텍스트도 포함해서 자식 엘리먼트를 가지는 엘리먼트
    :password
    패스워드 엘리먼트 선택 (input[type=password])
    :radio
    라디오 엘리먼트 선택 (input[type=radio])
    :reset
    리셋 버튼을 선택 (input[type=reset] or button[type=reset])
    :selected
    선택된 엘리먼트만 선택
    :submit
    전송 버튼을 선택 (input[type=submit] or button[type=submit])
    :text
    텍스트 엘리먼트만 선택 (input[type=text])
    :visible
    보이는 엘리먼트만 선택 
    [jquery 정의 셀렉터]



    (3) 자주 사용되는 함수 정리

    $.유틸리티 함수, Event 관련 함수, Ajax 관련 함수는 이번 장에서 다루지 않을 것이다.


     
    함수 명
    함수 설명
    엘리먼트 조작
    each(Function)
    선택된 엘리먼트가 다수일 경우에 each 함수를 사용하여 차례대로 엘리먼트를 선택한다.
    에트리뷰트 조작
    attr(name, value)
    선택된 엘리먼트의 name 에트리뷰트의 값을 value로 설정
     
    attr(name)
    선택된 엘리먼트의 name 에트리뷰트의 값을 얻어옴.
     
    attr(Attributes)
    선택된 엘리먼트를 프로퍼티(json)형태로 설정할 수 있음
     
    val()
    엘리먼트의 value 에트리뷰트 값을 얻어옴. attr("value")와 동일함.
     
    val(content)
    엘리먼트의 value 에트리뷰트 값을 content로 설정함.
    에트리뷰트 제거
    removeAttr(name)
    해당 어트리뷰트의 값이 초기화 된다.
    스타일 변경
    addClass(names)
    선택된 엘리먼트에 CSS Class를 적용함. 만약에 다수의 Class를 적용하려면 공백으로 구분하여 할당하면 됨.
     
    removeClass(names)
    선택된 엘리먼트들을 제거함.
     
    toggleClass(names)
    특정 Class를 적용하지 않은 상태면 적용하고, 적용한 상태면 제거함.
    스타일 얻고 설정
    css(name, value)
    선택된 엘리먼트의 name 에트리뷰트 값을 value로 설정함.
     
    css(properties)
    {"name1:" value1", "name2": "value2", } 와 같은 형태로 설정함.
     
    css(name)
    특정 name의 프로퍼티의 스타일 값을 얻을 수 있음.
     
    width(value)
    선택된 엘리먼트의 width 값을 설정함.
     
    height(value)
    선택된 엘리먼트의 height 값을 설정함.
     
    width()
    선택된 엘리먼트의 width 값을 얻어옴.
     
    height()
    선택된 엘리먼트의 height 값을 얻어옴.
     
    offset()
    선택된 엘리먼트의 left 값과 top 값을 E.offset().left, E.offset().top과 같은 방법으로 얻을 수 있음.
    엘리먼트 내용 설정
    html()
    선택된 엘리먼트 태그 내용을 얻을 수 있음.
     
    html(content)
    선택된 엘리먼트의 태그 내용을 content로 설정함.
     
    text()
    선택된 엘리먼트의 태그 내용 중 텍스트 값만 얻을 수 있음.
     
    text(content)
    선택된 엘리먼트의 태그 내용을 content로 설정함.
    엘리먼트 복사&이동
    append(content)
    선택된 엘리먼트의 내용 마지막에 새로운 content를 추가함.
     
    appendTo(target)
    선택된 엘리먼트가 단일이면 target으로 이동시키고 다수라면 복사됨.
     
    prepend(content)
    append와 달리 앞으로 추가함
     
    prependTo(target)
    appendTo와 달리 앞으로 복사 또는 이동함
     
    before(),
    insertBefore()
    엘리먼트를 대상의 첫 번째 자식으로 삽입하는 대신에 대상의 바로 앞 형제로 추가함.
     
    after(),
    insertAfter()
    엘리먼트를 대상의 마지막 자식으로 삽입하는 대신에 대상의 바로 뒤 형제로 추가함
    엘리먼트 감싸기
    wrap(wrapper)
    매개 변수로는 String과 엘리먼트 타입이 올 수 있으며, "<div class='hello'></div>" 형태로 매개 변수 값을 넘기면 됨.
     
    wrapAll(wrapper)
    선택된 모든 엘리먼트를 wrapper로 감쌈
    엘리먼트 제거
    remove()
    페이지 DOM에서 확장 집합의 모든 엘리먼트를 삭제함.
     
    empty()
    일치하는 집합의 모든 엘리먼트의 Content를 제거함.
    엘리먼트 복사
    clone(copyHandlers)
    일반적으로 엘리먼트를 복사한 확장 집합을 만들면 이들은 DOM 어딘가에 덧붙일 수 있음
    [함수 정리 (1)]


    (4) 그 밖에 함수 정리

    아래 표에 정리된 함수들은 확장된 엘리먼트 집합을 관리하는 함수들이다.

     
    함수 명
    함수 설명
    확장 집합 크기 얻기
    size()
    해당 엘리먼트의 개수를 반환한다.
    확장 집합에서 특정 엘리먼트 얻기
    get(index)
    확장 집합에서 index번째의 엘리먼트를 가져온다. (배열과 유사함)
     
    get()
    모든 확장 엘리먼트를 일반 자바스크립트 배열로 얻는다.
     
    index(element)
    확장 집합에서 특정 엘리먼트의 index 값을 가져온다.
    확장 집합 재편성 하기
    add(element)
    기존의 확장 집합에 다른 엘리먼트를 추가한다.
     
    not(expression)
    기존의 확장 집합에서 expression와 일치하는 엘리먼트를 제외시킨다.
     
    filter(expression)
    기존의 확장 집합에서 expression와 일치하는 엘리먼트만 가져온다.
    확장 집합의 부분 집합 얻기
    slice(begin, end)
    기존의 확장 집합에서 begin번째부터 end번째까지의 엘리먼트만 가져온다.
    확장 집합 관련 그 밖에 함수들
    find(selector)
    기존의 확장 집합에서 selector와 일치하는 엘리먼트들로 새로운 확장 집합을 생성한다.
     
    is(selector)
    기존의 확장 집합에서 selector와 일치하는 엘리먼트가 있다면 true, 없다면 false를 반환한다.
    jQuery 체인 관리하기
    end()
    이전 확장 집합을 반환한다.
     
    andSelf()
    커맨드 체인에서 이전 확장 집합 두 개를 하나로 합친다
    관계를 이용하여 확장 집합 얻기
     
    아래 표 참조.
    [함수 정리 (2)]

    함수 명
    설명
    children()
    확장 엘리먼트의 고유한 자식으로 구성된 확장 집합 반환한다.
    contents()
    엘리먼트의 콘텐츠로 구성된 확장 집합을 반환한다.
    next()
    확장 집합 내의 각 확장 엘리먼트 바로 다음에 나오는 형제로 구성된 확장 집합을 반환한다.
    nextAll()
    확장 집합 내의 각 확장 엘리먼트 바로 다음에 나오는 모든 형제로 구성된 확장 집합을 반환한다.
    parent()
    바로 위 부모로 구성된 확장 집합을 반환한다.
    parents()
    바로 위 부모와 모든 조상이 포함하는 확장 집합을 반환한다.
    prev()
    바로 이전에 나오는 형제로 구성된 확장 집합을 반환한다.
    prevAll()
    이전에 나오는 모든 형제로 구성된 확장 집합을 반환한다.
    siblings()
    확장 엘리먼트 내에 모든 형제를 포함한 확장 집합을 반환한다.
    [관계를 이용하여 확장 집합 얻기와 관련된 함수 정리]

     

     


    Event 관련 함수 및 프로퍼티와 $.유틸리티 함수 역시 이번 편과 비슷한 형식으로 정리를 해볼까 합니다. jQuery는 꼭 필요한 기능들만 구현이 되어 있기 때문에 따지고 보면 별로 정리할 내용이 없기 때문에 이를 간단하게 요약하면 jQuery를 사용하실 때, 참고하신다면 분명히 도움이 되리라 생각됩니다.

    그럼 이상으로 글을 마치겠습니다.


    출처 : http://blog.naver.com/seogi1004/ 




    반응형

    'IT > Javascript|Jquery' 카테고리의 다른 글

    javascript 셀렉트박스(SelectBox) 바로실행  (2) 2018.01.04
    ajax 로딩시 새로고침 문제  (6) 2018.01.03
    promise 패턴 예제  (0) 2018.01.02
    ajax 배열전송  (0) 2018.01.02
    모바일/PC 코딩하기  (0) 2018.01.02
    반응형
    1.Contoller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @RequestMapping(value = "/", method = RequestMethod.GET)
        public String home(Locale locale, Model model) {
            logger.info("Welcome home! The client locale is {}.", locale);
            LinkedList<String> link = new LinkedList<String>(); 
            link.addLast("a"); 
            link.addLast("b"); 
            link.addLast("c");    
            
            model.addAttribute("link", link);
            return "home";
    }
     
    cs



    2.JSP


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ page session="false"%>
    <%@ page contentType="text/html; charset=utf-8" %>
    <%@page import="java.util.*" %>
    <%
        //LinkedList 받기 예제
        LinkedList<String> linkedList = (LinkedList<String>)request.getAttribute("link");
        System.out.println(linkedList);
    %>
     
    <%=linkedList %>
    <html>
     
    .........
    cs


    이외에도 맵 리스트등의 데이터도

    getAttribute로 객체형태로 받아서 캐스팅만 잘해주면 손쉽게 받을수있었다



    아래는 링크드 리스트를 만드는 방법에 대해 설명한다

    출처: https://blog.perfectacle.com/2017/08/06/linked-list-making/

    List는 데이터를 순차적으로 저장하므로 선형 구조(한 줄로 계속 되며, 데이터가 끊어지지 않음)이다.
    또한 여기서 말하는 노드는 하나의 데이터 덩어리라고 보면 될 것 같다.

    LinkedList란…?

    LinkedList는 스택의 다음과 같은 단점을 극복하고자 만들어졌다.

    • 노드의 끝 부분을 제외한 곳에 데이터 삽입
      스택은 끝 부분에만 데이터를 삽입할 수 있으므로 중간에 데이터를 삽입할 방법이 존재하지 않았다.
      LinkedList는 배열의 이러한 단점을 노드(배열의 각 요소)가 다음 주소지를 알게 함으로써 그 단점을 극복하였다.

    하지만 신은 공평하듯, 이 LinkedList에도 다음과 같은 장/단점이 있다.

    • 데이터의 접근 속도가 느리다.
      LinkedList는 다음 노드에 대한 참조만을 가지고 있다.
      따라서 255 번째 노드의 데이터를 불러오려면 처음부터 순차적으로 255 번째 노드까지 접근해야한다.
      배열에 비해 이러한 접근 속도가 매우 느리다.
    • 다음 노드에 대한 참조만 있을 뿐, 이전 노드에 대한 데이터는 없다.
      따라서 이전 노드의 값을 가져올 수는 없다.
      이는 Doubly Linked List라는 이중 링크드 리스트라는 자료구조를 만들어 해결하였다.
    • 처음 노드에서 마지막 노드로, 혹은 마지막 노드에서 처음 노드로 가려면 시간이 오래 걸린다.
      Doubly Linked List를 이용해도 순차적인 접근 밖에 되지 않기 때문에 어쨌든 계속해서 노드들을 타고 타고 끝이나 처음으로 이동해야 한다.
      이러한 단점을 극복하기 위해 처음 노드에 대한 이전 참조를 마지막 노드로, 마지막 노드에 대한 다음 참조를 처음 노드로 이어줘 원형 구조로 만든 Doubly Circular Linked List가 있다.

    따라서 이 LinkedList를 잘 살리려면 중간에 삽입/삭제가 빈번하며 검색을 자주 하지 않는 자료를 담을 때 사용해야한다.

    만들어보자!

    먼저 기본적인 Node부터 만들어보았다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    class Node {
    private Object value;
    private Node next;
    Node(Object o) {
    this.value = o;
    }
    public Object getValue() {
    return value;
    }
    public void setValue(Object o) {
    this.value = o;
    }
    public Node getNext() {
    return next;
    }
    public void setNext(Node next) {
    this.next = next;
    }
    boolean isLast() { // 마지막 노드인지
    return this.next == null;
    }
    public boolean equals(Node node) { // 내용물과 참조하는 애가 같은지
    return value.equals(node.getValue()) && next == node.getNext();
    }
    }
    class NodeTest {
    public static void main(String[] args) {
    Node n = new Node(2);
    Node n2 = new Node(2);
    Node n3 = new Node(2);
    Node n4 = new Node(3);
    n.setNext(n4); // n 다음에 n4
    n2.setNext(n4); // n2 다음에 n4
    n3.setNext(n); // n3 다음에 n
    System.out.println(n.equals(n2)); // true
    System.out.println(n.equals(n3)); // false
    System.out.println(n.isLast()); // false
    System.out.println(n4.isLast()); // true
    // 지금 구조(List)는 n3(2) 다음에 n(2) 다음에 n4(3) 순으로 연결(Linked)돼있다.
    // 초기 노드를 지정해주고, 계속해서 다음 노드를 참조하는 걸 증감식에 적어줌,
    for(Node node = n3; true; node = node.getNext()) { // 탈출 조건이 있는 무한 반복문
    // 마지막 노드여도 출력까지는 해줘야함.
    System.out.println(node.getValue()); // 2 2 3
    if(node.isLast()) break;
    }
    }
    }

    그 다음엔 LinkedList를 만들어보았다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    class LinkedList {
    private Node[] nodes;
    private int idx; // 현재 리스트의 몇 번째 요소까지 노드가 들어왔는지 확인하는 변수
    LinkedList() {
    this(10); // 기본적으로 10개를 만들어주자, 너무 작게 만들면 복사하는 처리 비용이 많이 들테니...
    }
    LinkedList(int size) {
    nodes = new Node[size];
    }
    void add(Object o) { // 맨 끝에 삽입하는 경우
    int size = size();
    Node node = new Node(o);
    // 꽉차지 않았다면
    if(idx != size) nodes[idx] = node; // 현재 인덱스에 노드 삽입.
    else { // 꽉 찼으면
    Node[] tmpNodes = new Node[size+10]; // 나중에 또 금방 복사하지 않게 적절하게 큰 배열을 만들자.
    for(int i=0; i<size; i++) tmpNodes[i] = nodes[i]; // 기존의 값들을 새로운 배열에 복사
    tmpNodes[idx] = node; // 새로운 값 삽입
    nodes = tmpNodes; // 복사한 배열을 원본 배열 변수로 갈아치우기
    }
    if(idx == 0) {
    idx++;
    return; // 하나만 넣은 거면 참조 관계를 수정할 필요가 없음.
    }
    nodes[idx-1].setNext(nodes[idx++]); // 이전 노드의 참조를 현재 노드로 변경
    }
    void add(int idx, Object o) { // 인덱스를 지정해 해당 지점에 삽입하려는 경우
    // List는 선형구조이므로 데이터를 삽입해야할 인덱스보다 더 뒤에 노드를 삽입하는 것은 불가능하다.
    // 당연히 배열의 인덱스를 벗어나는 음수도 불가능하다.
    if(this.idx < idx || idx < 0) throw new ArrayIndexOutOfBoundsException("올바른 인덱스를 입력해주세요!");
    // 배열의 중간에 노드를 삽입하는 게 아닌 경우
    if(idx == this.idx) this.add(o);
    else { // 배열의 중간에 노드를 삽입하는 경우
    int size = size();
    Node node = new Node(o);
    // 꽉 차지 않았다면 기존과 동일한 사이즈의 배열 생성, 아니라면 넉넉히 길이가 10 더 긴 배열 생성.
    Node[] tmpNodes = idx != size ? new Node[size] : new Node[size+10];
    // 복사할 배열을 직접 넘겨줘서 추가하기.
    for(int i=0; i<idx; i++) tmpNodes[i] = nodes[i]; // idx 이전까지는 그대로 복사
    for(int i=idx; i<this.idx; i++) { // last까지 복사
    tmpNodes[i+1] = nodes[i]; // idx 이후는 한 칸씩 밀어서 복사
    }
    tmpNodes[idx] = node; // 새로운 배열에 지금 들어온 노드 삽입
    nodes = tmpNodes; // 복사한 배열을 원본 배열 변수로 갈아치우기
    nodes[idx].setNext(nodes[idx-1].getNext()); // idx 노드는 중간에 끼어들었으므로 idx 노드 이전 노드의 참조를 가리켜야함.
    nodes[idx-1].setNext(nodes[idx]); // idx 이전 노드의 참조는 idx 노드를 가리키고 있어야함.
    this.idx++;
    }
    }
    void remove() {
    nodes[--idx] = null; // 마지막 노드 삭제 후 인덱스 1 낮춤.
    nodes[idx-1].setNext(null); // 이전 노드가 마지막 노드이므로 참조할 노드가 없음.
    }
    void remove(int idx) {
    Node[] tmpNodes = new Node[size()]; // 배열을 한 칸씩 땡겨야하므로 새롭게 배열 생성.
    Node node = getNode(idx).getNext(); // idx 번째 노드가 갖고 있는 참조 노드
    for(int i=0; i<idx; i++) tmpNodes[i] = nodes[i]; // idx 이전까지 복사
    for(int i=idx+1; i<this.idx; i++) tmpNodes[i-1] = nodes[i]; // idx 이후로 또 복사
    nodes = tmpNodes; // 복사한 배열을 원본 배열 변수로 갈아치우기
    nodes[idx-1].setNext(node);
    this.idx--;
    }
    Object get(int idx) {
    Node node = getNode(idx);
    return node == null ? null : node.getValue();
    }
    Node getNode(int idx) {
    Node node=nodes[0];
    // idx까지 계속 다음 참조 노드를 구함.
    for(int i=0; i<idx; i++, node=node.getNext());
    return node;
    }
    int size() {
    return nodes.length;
    }
    }
    class LinkdedListTest {
    public static void main(String[] args) {
    LinkedList l = new LinkedList();
    l.add(1);
    l.add("a");
    System.out.println(l.get(0)); // 1
    // 0번째 노드를 구하고 그 참조 노드를 구하고 값을 얻기
    System.out.println(l.getNode(0).getNext().getValue()); // a
    for(int i=0; i<10; i++) l.add(i); // 1 a 0 1 2 3 4 6 7 8 9
    System.out.println(l.get(11)); // 9
    l.add(11, 22);
    System.out.println(l.get(11)); // 22
    LinkedList l2 = new LinkedList();
    l2.add(1);
    l2.add(2);
    l2.add(3);
    l2.add(4);
    System.out.println(l2.get(3)); // 4
    l2.remove();
    System.out.println(l2.get(3)); // null
    System.out.println(l2.get(1)); // 2
    l2.remove(1);
    System.out.println(l2.get(1)); // 3
    }
    }

    틀린 게 많을지는 모르겠지만…
    일단은 구현을 했다는 것에 의의를 두고 나중에 다시 수정해야겠다.

    반응형
    반응형

    기본적으로 JSTL은 자바 코드를 다루기에 적합한 커스텀 태그 라이브러리이고

    Javascript는 웹 브라우저에서 사용되는 스크립트 프로그래밍 언어이고 

    내장객체에도 접근이 가능하다는 장점이있다

    웹개발을 하다보면 두가지를 같이 써야할상황도 있고 이부분에 헷갈려 하기 쉽다

    일단은 두가지를 같이 사용할수있는 예제가 있어서 가져와보았다


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    // java
     
    HashMap<Object, Object> map = new HashMap<Object, Object>();
     
    map.put("name", "홍길동");
     
    map.put("city", "서울");
     
    map.put("age", 30);
     
     
     
    ArrayList<Object> list = new ArrayList<Object>();
     
    list.add("hong@naver.com");
     
    list.add("gil@daum.net");
     
    list.add("dong@nate.com");
     
     
     
    ArrayList<HashMap<Object, Object>> arrayListMap = new ArrayList<HashMap<Object, Object>>();
     
    arrayListMap.add(map);
     
     
     
    HashMap<Object, ArrayList<Object>> lMultiData = new HashMap<Object, ArrayList<Object>>();
     
    lMultiData.put("email", list);
     
     
     
    mav.addObject("list_map", arrayListMap);
     
    mav.addObject("map_list", lMultiData);
     
     
     
     
     
    // javascript
     
    var list1 = new Array();
     
    <c:forEach items="${list_map}" var="item1">
     
    list1.push("${item1.name}");
     
    list1.push("${item1.city}");
     
    list1.push("${item1.age}");
     
    </c:forEach>
     
    for (var i = 0; i < list1.length; i++) {
        alert(list1[i]);
    }
    alert("${list_map[0].name}");
     
    var list2 = new Array();
    <c:forEach items="${map_list.email}" var="item2">
     
    list2.push("${item2}");
     
    </c:forEach>
     
    for (var i = 0; i < list2.length; i++) {
        alert(list2[i]);
    }
    cs


    출처: http://blog.naver.com/PostView.nhn?blogId=typeofb&logNo=191469973


    해당 방식으로 사용할수있는데

    기본적으로 자바스크립트와 JSTL의 작동 순서를 알고 코딩해야 에러를 줄일수있다



    서버가 작동할때

    JAVA>JSTL>HTML>Javscript 


    순서로 작동하기때문에 Javascript 에서는 Jstl나 el 태그의 값을 다루는데에 제한적일수밖에없다


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <c:forEach items="$("#list").val()" var="item1">
     
    list1.push("${item1.name}");
     
    list1.push("${item1.city}");
     
    list1.push("${item1.age}");
     
    </c:forEach>
     
    cs

    (X)


    이런식으로 Jquery 값을 jstl에서는 다룰수가없다 


    1
    2
    3
    var list = '<c:out value="${list}"/>';
     
     
    cs

    (O)


    다만 스크립트가 로드되기 전부터 존재하는 el값은 스크립트에서 조작이 가능하다




    다른 예제

    출처: http://wfreud.tistory.com/51 [wfreud 개인 라이브러리]


    XXXXcontroller.java 에서

    다음과 같이 getUserInfo에 값을 담아 보냈을 때

     

    1. getAttribute로 값 받기

    이 방법은 비추…

    해당 클래스를 매번 import해야되고, 나중에 소스 파악도 힘듦

     

     

    2. el표현언어 or jstl 이용  

    jstl 이용 시

    Value에 <c:out ~~> " 태그를 이용해서 써주면 된다

     

     

     

    3. [추가 20141008]자바스크립트에서 받고 싶다면????

    뷰(jsp)페이지에서 jstl 태그 이용하지 않고

    model에 담긴 List 를 자바스크립트에서 처리하고 싶다면????

     

    하나의 jsp 파일 내에 작성된 소스라도

    jstl,el 등은 서버에서 실행이되고, 자바스크립트는 브라우저에서 실행되기 때문에

    두 언어 간에 변수를 직접 주고 받을 수는 없다

     직접은 아니더라도 받을 수는 있음!!!!



    3. 자바스크립트 내에서 값 받기

    1) jstl을 이용해서 받기

    controller에서 List<ServerInfo>  형태로 값을 'serverinfo'에 담아 넘겨줬을 경우

     

     

    여기서는 json 배열을 만들고자 했다

     

    그래서,

    jstl 구문으로 값을 받고 ->받은 값을 json Object에 넣고 -> 배열에 다시 넣음

    그럼

    [[a:xxx,b:sss],[a:xxx,b:sss],[a:xxx,b:sss]] 형태의 값이 된다.

     

     

    여기서 object 선언을 jstl 바깥쪽에 넣으면 똑같은 값이 들어간다...

    object는 하나의 객체이기 때문에!!!!!

    추가될때마다 오브젝트를 만들어서 넣어주도록 해야함



    2) javascript 배열을 이용해서 받기


    Controller단에서 Model은 request 에 값을 가지고 있음..

    model에 있는 값을 받을려면 페이지 전환되어야 그 값을 받아올 수 있음



    ajax 요청 같은 경우 

    페이지 전환없이 같은페이지에서 받는 것이기 때문에 


    컨트롤러에서 model  값에 넣어서 넘겨주면 안돼고.. 

    return 값에 넣어 다음과 같이 클라이언트 단에 넘겨줘야함 


    받을때는 그냥 다음과 같이 받으면 됨


    여기서 .. 리턴 타입이 List<Beacon> 라면...

    자바의 List는 자바스크립트에서는 배열로 받음 

    Beacon은 object로 접근이 가능하다 




    반응형

    'IT > Jsp|JSTL' 카테고리의 다른 글

    jstl split,startsWith,endsWith 사용법  (0) 2018.01.26
    JSTL 과 Javascript 혼용 사용의 실제사례  (0) 2018.01.03
    JSP 에서 LinkedList 받기  (0) 2018.01.02
    반응형

    이클립스를 계속 쓰다보면 이런식으로



    변경사항이 없는데 'Initializing Java Tooling' has encountered a problem 오류가 뜰때가 있다

    딱히 해결방법을 몰랐었다가 검색으로 해결한 방법인데 공유하고자 한다


    1. 폴더로 이동


    workspace 가 있는 폴더로 이동한다 (이클립스 폴더 X)

    \workspace\.metadata\.plugins\org.eclipse.core.resources\.projects


    해당 경로에서 생성된 파일들을 모두 지워주자 (.project 하위폴더 전부삭제)


    그리고 이클립스를 재시작해보면

    아까와 다른 경고가 뜰것이다


    \Dev\workspace\.metadata\.plugins\org.eclipse.core.resources\.projects\RemoteSystemsTempFiles\.markers.snap 

    (지정된 경로를 찾을 수 없습니다)


    해당 경우는 해당 위치에 RemoteSystemsTempFiles,Server 폴더만 생성해주면

    해결이 된다





    참고 : http://hunit.tistory.com/193

            http://codedragon.tistory.com/5005



    + 2018/01/08 추가


    해당 방법을 사용하면 에러는 고쳐지지만

    기존에 설정했던 SVN과 GIT 설정등이 있을경우 전부 사라져 버리기때문에

    해당 방법 사용전 프로젝트들을 백업 시켜두고

    연동된 프로젝트가 있었다면 방법 사용후엔 연결이 끊겨있기때문에

     재연결이나 import를 시켜주어야한다





    이클립스의 설정은 윈도우 레지스트리에 보관되지 않습니다. 워크스페이스 폴더를 보면 .metadata 폴더가 있습니다. 여기에 이클립스에서 설정했던 내용들이 들어가 있습니다.

    .metadata

    .metadata


    이 얘기는 workspace를 바꾸면 설정을 다시해 줘야 한다는 뜻입니다.
    또한 이클립스를 업그레이드해도 이전에 쓰던 작업환경의 설정을 그대로 가져갈 수 있다는 뜻이기도 합니다.

    살짝 .metadata 폴더 내용을 보면 다음과 같습니다.

    .metadata 폴더

    .metadata 폴더


    이 중에 각각의 플러그인 설정값은 .plugins 아래 보관이 됩니다.
    .log 파일은 이클립스 내부에서 발생하는 오류들의 스택트레이스 로그가 보관됩니다. 플러그인 충돌이나 기타 이클립스가 오작동을 할 경우 이 안에 있는 내용을 토대로 구글링 해보면 운 좋게 해결법을 찾을 수 있습니다.

    이클립스가 종료된 상태에서 .metadata 를 지우면 설정은 다시하셔야 됩니다. 이클립스의 검색 인덱스 파일도 여기에 보관이 되기 때문에 혹시나 이클립스 워크스페이스가 무거워졌다고 느껴지면 한 번 지웠다가 다시 설정하는 것도 나쁘지는 않습니다.


    출처: http://okjsp.tistory.com/1165643079 [OK 괜찮아, fInD YoUr FuN, eNjOy iT!]



    이클립스(Eclipse)를 새 PC에 설치해서 구동하려고 했더니, 다음과 같은 오류 메시지가 떴습니다.

    이 오류 메시지가 뜨면 이클립스 실행 자체가 되지 않습니다.

     

    회사에서도 그렇고, 이전 PC에서도 그렇고, 별 문제 없이 잘 실행 되었던 것으로 기억하는데..(사실 잘 기억은 안나네요. 처음 설치하고 고생했는지는 너무 오래전 일이라. 보통 한 번 잘 세팅해놓고, 왠만해서는 변경하지 않으니... ㅎㅎㅎ)

     

     

     

    Java was started but returned exit code=13 로 시작하는 긴 오류 메시지가 떴습니다. 블라블라~

     

    보통 가장 빈번한 경우는 OS 비트와 이클립스의 지원 비트 버전이 다른 경우입니다.

    OS는 64비트인데, 이클립스는 32비트용을 다운로드 받아 설치한 경우이지요.

    이 때의 문제는 간단히 이클립스를 OS 버전에 맞는 것으로 다시 다운로드 받아 설치하면 됩니다.

     

     

    그리고 다른 케이스가 있는데, 이클립스가 실행하면 javaw.exe 파일(JDK 내에 있음)을 찾아 실행시키는데, 해당 파일을 찾지 못한 경우입니다. (제가 겪은 케이스입니다.)

    이 때에는 직접 설치한 JDK폴더의 javaw.exe 파일 경로를 eclipse.ini 파일에 지정해주면 됩니다.

     

    참고로 javaw.exe 파일은 java.exe 파일과 그 기능이나 동작은 동일하지만, 단지 Console Window 를 띄우지 않는 다는 차이점만 있습니다. (즉, Java.exe 와 동일하게 동작하지만, 어떠한 상태 정보등을 명령 프롬프트(콘솔 창)에 출력하지 않습니다. 단 오류가 발생하는 경우라면 오류 메시지 박스(대화 상자)를 띄워줍니다.)

    그리고 java.exe 파일은 자바 프로그램을 구동시키기 위한 자바 런타임 환경(Java Runtime Environment)을 제공 뿐만 아니라 웹 브라우저에서 Java 기반의 플러그인을 실행할 수 있도록 하기 위한 백그라운드 프로세스로 실행되는 프로그램입니다. 그렇기 때문에 Java 프로그래밍에는 필수 요소입니다.

     

    Eclipse가 설치된 폴더로 가서 eclipse.ini 파일을 메모장 등의 텍스트 편집 도구로 불러옵니다.

     

     

     

    그리고 아래와 같이 -vmargs 윗쪽에 javaw.exe 파일 경로를 입력하여 줍니다. 사용자마다 JDK 설치 폴더가 다를테니, 자신의 시스템에 설치된 경로를 확인하여 입력하시면 됩니다.

     

    -vm
    C:\Java\jdk1.7.0_45\bin\javaw.exe (javaw.exe 파일이 존재하는 경로)

     

    아래 -vmargs 는 -vm (Virtual Machine)으로 구동될 javaw.exe의 인자 정보들을 의미하므로 위의 -vm 코드는 반드시 -vmargs 보다 상단에 작성하여야 합니다.

     

    참고로 해당 포스팅은 Eclipse Juno 버전과 Kepler 버전에서 확인되었습니다.



    출처: http://ooz.co.kr/140 [이러쿵저러쿵]


    반응형
    반응형
    1···56789

    + Recent posts