반응형

오늘 불현듯...

User Define Cursor 에 대한 부분이 궁금해 졌다...

자바에서 오라클 패키지 호출하여 커서값을 반환하여 자유 스럽게 사용했는데

그 커서 값을 오라클에서 받아서 해볼까 하는...

사실 cursor is 구문이라던지 직접 사용했지

그동안 cursor 반환은 무관심 했었다..

방법은...

즉,  커서 out 값에  l_cursor에 받아와서

3개의 select 한 값을 return 하는데... 각 값들의 속성을 l_ename, l_empno, l_deptno 로 fetch 하여 받아가지고 옴...

참고용

SET SERVEROUTPUT ON SIZE 1000000
DECLARE
  TYPE REF_CUR IS REF CURSOR;
  l_cursor REF_CUR;
  l_ename   emp.ename%TYPE;
  l_empno   emp.empno%TYPE;
  l_deptno  emp.deptno%TYPE;
BEGIN
  get_emp_rs (p_deptno    => 30,
              p_recordset => l_cursor);
            
  LOOP 
    FETCH l_cursor
    INTO  l_ename, l_empno, l_deptno;
    EXIT WHEN v_cursor%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(l_ename || ' | ' || l_empno || ' | ' || l_deptno);
  END LOOP;
  CLOSE l_cursor;
END;
/


출처 :  http://www.oracle-base.com/articles/misc/UsingRefCursorsToReturnRecordsets.php 




Using Ref Cursors To Return Recordsets

Since Oracle 7.3 the REF CURSOR type has been available to allow recordsets to be returned from stored procedures and functions. Oracle 9i introduced the predefined SYS_REFCURSOR type, meaning we no longer have to define our own REF CURSOR types. The example below uses a ref cursor to return a subset of the records in the EMP table.

The following procedure opens a query using a SYS_REFCURSOR output parameter. Notice the cursor is not closed in the procedure. It is up to the calling code to manage the cursor once it has been opened.

CREATE OR REPLACE
PROCEDURE get_emp_rs (p_deptno    IN  emp.deptno%TYPE,
                      p_recordset OUT SYS_REFCURSOR) AS 
BEGIN 
  OPEN p_recordset FOR
    SELECT ename,
           empno,
           deptno
    FROM   emp
    WHERE  deptno = p_deptno
    ORDER BY ename;
END GetEmpRS;
/

The resulting cursor can be referenced from PL/SQL as follows.

SET SERVEROUTPUT ON SIZE 1000000
DECLARE
  l_cursor  SYS_REFCURSOR;
  l_ename   emp.ename%TYPE;
  l_empno   emp.empno%TYPE;
  l_deptno  emp.deptno%TYPE;
BEGIN
  get_emp_rs (p_deptno    => 30,
              p_recordset => l_cursor);
            
  LOOP 
    FETCH l_cursor
    INTO  l_ename, l_empno, l_deptno;
    EXIT WHEN v_cursor%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(l_ename || ' | ' || l_empno || ' | ' || l_deptno);
  END LOOP;
  CLOSE l_cursor;
END;
/

The cursor can be used as an ADO Recordset.

Dim conn, cmd, rs

Set conn = Server.CreateObject("adodb.connection")
conn.Open "DSN=TSH1;UID=scott;PWD=tiger"

Set cmd = Server.CreateObject ("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "get_emp_rs"
cmd.CommandType = 4 'adCmdStoredProc

Dim param1
Set param1 = cmd.CreateParameter ("deptno", adInteger, adParamInput)
cmd.Parameters.Append param1
param1.Value = 30

Set rs = cmd.Execute

Do Until rs.BOF Or rs.EOF
  -- Do something
  rs.MoveNext
Loop

rs.Close
conn.Close
Set rs     = nothing
Set param1 = nothing
Set cmd    = nothing
Set conn   = nothing

The cursor can also be referenced as a Java ResultSet.

import java.sql.*;
import oracle.jdbc.*;

public class TestResultSet  {
  public TestResultSet() {
    try {
      DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
      Connection conn = DriverManager.getConnection("jdbc:oracle:oci:@w2k1", "scott", "tiger");
      CallableStatement stmt = conn.prepareCall("BEGIN get_emp_rs(?, ?); END;");
      stmt.setInt(1, 30); // DEPTNO
      stmt.registerOutParameter(2, OracleTypes.CURSOR); //REF CURSOR
      stmt.execute();
      ResultSet rs = ((OracleCallableStatement)stmt).getCursor(2);
      while (rs.next()) {
        System.out.println(rs.getString("ename") + ":" + rs.getString("empno") + ":" + rs.getString("deptno")); 
      }
      rs.close();
      rs = null;
      stmt.close();
      stmt = null;
      conn.close();
      conn = null;
    }
    catch (SQLException e) {
      System.out.println(e.getLocalizedMessage());
    }
  }

  public static void main (String[] args) {
    new TestResultSet();
  }
}
If you are using a version of Oracle before 9i, then create the following package and replace any references to SYS_REFCURSOR with TYPES.cursor_type.
CREATE OR REPLACE PACKAGE types AS 
  TYPE cursor_type IS REF CURSOR;
END Types; 
/
Hope this helps. Regards Tim... 
반응형

'Database > ORACLE' 카테고리의 다른 글

Automatic SQL Tuning in Oracle Database 10g  (0) 2012.07.20
10G OCP 자격증 관련  (2) 2012.07.08
일정 시간 별로 쿼리 정보 조회  (0) 2012.02.20
오라클 병렬 인덱스 조회 및 수정하기  (0) 2012.01.27
AWR Report 정리본  (0) 2011.09.28
반응형


11버전 설치했는데...

아래와 같이 설치후

부트로더 화면에서 e 키를 눌러 직접 수정해 줘야 했다.. -_-

제길슨...

root 패스워드 변경

sudo passwd root

일케 함..-_-

패키지 설치는...

http://packages.ubuntu.com 

검색하여 설치가능함 ~

출처 :  http://blog.naver.com/PostView.nhn?blogId=hseok74&logNo=120108619514&viewDate=&currentPage=1&listtype=0 


삼성 매직스테이션 (DM-V75)에 우분투 설치하기

 

삼성 매직스테이션에 리눅스 설치만 하면 부팅이 되다가 입력이 모두 홀드되어 아무것도 할수 없는 상태가 된다.

이것을 해결하기 위해서 다음과 같은 작업을 진행했고, 아래 링크를 참조했다.

 

참조사이트 : http://onthebeginningway.blogspot.com/2009/09/ubuntu-install-on-samsung-desktopdm-v75.html

 

1. 9.10 우분투 CD를 삽입하고 전원을 켠다.

2. "하드디스크 변경없이 우분투 사용" 에 선택 바를 놓고, F6, F8키를 누른다.

3. 부트 옵션 맨 앞쪽에 다음과 같이 추가하고 엔터를 친다.

   'acpi=off noapic pnpbios=off irqpoll'
4. 우분트가 뜨고, 설치를 시작

5. 설치가 끝나면 "계속사용" or "리부팅" 에서 "계속 사용"을 선택한다.

6. 우분트가 설치된 "/" 파티션을 찾아서 마운트 한다.

7. 'sudo vi <ROOT_PARTITION>/boot/grub/grub.cfg'를 하고 아래와 같이 3번 사항을 추가 한다.

<중략>

 ### BEGIN /etc/grub.d/10_linux ###
menuentry "Ubuntu, Linux 2.6.31-14-generic" {
        recordfail=1
        if [ -n ${have_grubenv} ]; then save_env recordfail; fi
        set quiet=1
        insmod ext2
        set root=(hd0,5)
        search --no-floppy --fs-uuid --set 8fb53ee5-0550-436f-afca-842b73d31ab4
        linux   /boot/vmlinuz-2.6.31-14-generic root=UUID=8fb53ee5-0550-436f-afca-842b73d31ab4 ro acpi=off noapic pnpbios=off irqpoll  quiet splash
        initrd  /boot/initrd.img-2.6.31-14-generic
}
menuentry "Ubuntu, Linux 2.6.31-14-generic (recovery mode)" {
        recordfail=1
<중략>

8. 루트 파티션 언마운트 후에 재부팅한다.

9. 재 부팅후에 잘 사용한다.(끝)

 

위 4개의 옵션이 모두 필요한지 모르겠다.

몇시간을 삽질한 것인지... 쩝

반응형

'OS > Linux' 카테고리의 다른 글

CENTOS 7에 XRDP 설치하기  (0) 2017.08.26
리눅스 백업 및 복구  (0) 2013.01.25
rkhunter (리눅스 침입 탐지 사용하기)  (1) 2010.10.14
ps auxc 와 ps aux 결과 비교하기  (0) 2010.01.21
AWK & SED chunk_1  (0) 2010.01.21
반응형


오라클을 이관 후에는 컴파일을 일괄적으로 해야할 때가 존재한다...

1. 일괄 컴파일

 

Set heading off      
Set feedback off      
Set pages 1000      
 
 spool obj.sql
 select 'set termout on' from dual;
 select 'set echo on' from dual;      
      
 select 'alter trigger '||owner||'.'||object_name||' compile;'
 from dba_objects
 where status <> 'VALID'
 and object_type='TRIGGER';
     
 select 'alter package '||owner||'.'||object_name||' compile;'      
 from dba_objects      
 where status <> 'VALID'       
 and object_type='PACKAGE';      

 select 'alter package '||owner||'.'||object_name||' compile body;'     
 from dba_objects      
 where status <> 'VALID'       
 and object_type='PACKAGE BODY';

 select 'alter procedure '||owner||'.'||object_name||' compile;'       
 from dba_objects      
 where status <> 'VALID'       
 and object_type='PROCEDURE';      

 select 'alter function '||owner||'.'||object_name||' compile;'
 from dba_objects      
 where status <> 'VALID'
 and object_type='FUNCTION';

 select 'alter view '||owner||'.'||object_name||' compile;'       
 from dba_objects      
 where status <> 'VALID'       
 and object_type='VIEW';       
 
 spool off

[출처] [Oracle] 데이타베이스 한꺼번에 Compile하기|작성자 미친예언자




2. 일괄 컴파일

 host rm -rf comp1.sql comp2.sql
set pages 300
select count(1) as INVALID_OBJECT_COUNT from dba_objects where status !='VALID';
set pages 0
set line 1000
set echo off
set feedback off
set space 0
col compile for a1000
select systimestamp as start_time from dual;
spool comp1.sql
select 'prompt '||object_type||' '||object_name||' compiling'||'
prompt '||'
alter '||object_type||' '||owner||'.'||object_name||' compile;' as compile
from dba_objects
where status !='VALID'
and object_type !='PACKAGE BODY';
spool off
host ls -al comp1.sql
host echo "select systimestamp from dual;" >> comp1.sql
start comp1.sql
show error
spool comp2.sql
select 'prompt '||object_type||' '||object_name||' compiling'||'
prompt '||'
alter package '||owner||'.'||object_name||' compile body;' as compile
from dba_objects
where status !='VALID'
and object_type ='PACKAGE BODY';
spool off
host ls -al comp2.sql
host echo "select systimestamp from dual;" >> comp2.sql
start comp2.sql
show error
set echo on
set feedback on
set pages 3000
set space 1
col owner for a20
col object_name for a28
col object_type for a20
col status for a16
select owner,object_name,object_type,status from dba_objects
where status !='VALID';
select count(1) INVALID_OBJECT_COUNT from dba_objects where status !='VALID';
select systimestamp as end_time from dual;


3. 일괄 컴파일

 1. SQL> @?/rdbms/admin/utlrp.sql

2. utlrp를 parallel하게...
execute utl_recomp.recomp_parallel(4);

3. 만약 ERP라면...위의 두개로 해결이 안될때에는...
cd $AD_TOP/sql/adcompsc를 사용합니다.
adcompsc <== 이게 산타님 말씀하신것 처럼 alter문장을 생성하여 실행합니다.
참고하세요^^

반응형
반응형

No. 10707
DBMS_JOB PACKAGE의 사용 방법과 예제
===================================

Purpose
-------
DBMS_JOB package의 사용방법에 대해 알아보자.

Explanation
-----------
Unix의 cron과 같이 오라클에서도 일정한 시점, 또는 간격으로 반복해서
job을 수행시킬 수 있다.  DBMS_JOB package를 이용하여 수행시킬 수 있는
데, 이것을 위해서는 SNP background process가 start되어 있어야 한다.
 다음의 parameter를 init<SID>.ora file에 설정한 후 oracle을 startup하면
SNP0 혹은 J000 process가 뜨게된다.
    job_queue_processes = 1
      -> 이 파라미터는 snp process를 몇 개 띄울지를 결정한다. 
         default=0
    job_queue_interval = 60
      -> 이 파라미터는 snp process가 깨어나는 간격을 초로 설정한다.
 (Oracle9i부터는 job_queue_interval parameter가 없어졌으므로
  job_queue_processes 만 설정하면 된다.)

DBMS_JOB Package는 다음과 같은 procedure를 이용하여 사용한다.
DBMS_JOB.submit(job           out   binary_integer,
                what          in    varchar2,
    next_date     in    date defalut sysdate,
   interval      in    varchar2 default 'null',
  no_parse      in    boolean default false)
-> dbms_job.submit procedure는 job의 내용을 정의하고 oracle이 job을
 수행할 수 있도록 한다.

Example
-------
[ 예제 ] file jobcre.sql
begin
 dbms_job.submit(:jobno,             
--  job 의 번호
 'insert into scott.testdate values(1,  sysdate);',   
--  job의 내용 : ' '으로 감싸준다.
--  procedure를 실행하는 경우 ' username.procedure_name;' 만 쓰면 된다.
    sysdate,
--  job이 실행될 시간
 'sysdate + 5/24/60' ,
--  job이 실행되는 간격 , 위의 경우는 5분마다 실행하도록 했다.
--  ' '으로 감싸준다.
   FALSE );
end;
/
$ sqlplus scott/tiger
SQL>  variable jobno number;
SQL>  @jobcre
SQL>  print jobno    --  job 번호 확인 : 여기서는 166번
SQL>  exec dbms_job.run(166);
SQL>  commit;
    지금부터 interval에 따라 job이 실행된다.
    job 실행 여부를 알아보기 위해서 다음의 sql 문장을 수행한다.
SQL> col what format a20
SQL> select what, job, next_date, next_sec, failures, broken
     from user_jobs;
      그 외에
 
SQL> exec  dbms_job.run(jobno);
      - job의 강제 실행, job이 16번 fail되어 broken된 경우는
        위의 명령어로 강제로 run을 시켜서 실행되면 다시 interval마다
        실행된다.
SQL> exec  dbms_job.broken(jobno, TRUE);
      - job을 disable시킴
SQL> exec  dbms_job.remove(jobno);
      - job의 삭제 

참고1. snapshot과 job과의 관계
snapshot 도 job 으로 등록되어 실행된다.
즉, select job, what from dba_jobs; 를 조회하면,
what 부분에 snapshot 이 정의되어 있다.
따라서, snapshot 에 대한 disable 방법 등은 job 과 같은 방법으로
실행하면 된다.

참고2. interval 시간 지정 예제
1. 10분에 한번씩 실행하는 경우
 
   sysdate + 1/24/6       또는  sysdate + 1/144  
     -> 1/24 (1시간-60분) / 6  : 10분 단위
        1/144   :  24*6  으로 나누어도 같은 의미가 된다.
 
2. 1분에 한번으로 지정하는 경우
   sysdate + 1/24/60   또는   sysdate + 1/1440
3. 매일 새벽 2시로 지정하는 경우
   trunc(sysdate) + 1 + 2/24  ->  다음날 새벽 2시를 지정함.

4. 매일 밤 11시로  지정하는 경우
   trunc(sysdate) + 23/24     ->  오늘 밤 11시를 지정했음.

Reference Documents
-------------------
Oracle Developer's Guide and Oracle PL/SQL Guide
 
otn.oracle.co.kr
반응형

'Database > ORACLE' 카테고리의 다른 글

집합 함수  (0) 2009.03.08
ORACLE 10G PL/SQL USER GUIDE AND REFERENCE  (0) 2009.03.08
INVALID OBJECT 컴파일 하는 방법  (0) 2009.03.08
오라클 백업 방식과 백업 방법  (0) 2009.03.08
TAB 뷰 에 정보 생성하기  (0) 2009.03.08
반응형

** 질문

안녕하세요.

table 을 alter 하거나 하면 해당 table 을 사용하고 있는 procedure 가

invalid 가 되잖아요..

그래서 보통 alter 후에 toad 에서 compile invalid procedure 또는 compile all procedure

버튼을 눌러서 컴파일을 했는데

위의 두가지중에 아무거나 라도 혹시 pl/sql 에서 실행할수있는 쿼리좀 알수있을까요?

뒤져본다고 뒤져봤는데 도통 찾을수가 없어서요.

부탁드릴께요.

 

** 답변

set PageSize 100
SPOOL RECOM.sql
      SELECT distinct 'ALTER PACKAGE ' || OBJECT_NAME || ' COMPILE;'
        FROM USER_OBJECTS
       WHERE STATUS      = 'INVALID' and
             Object_Type in ( 'PACKAGE BODY' , 'PACKAGE')
union all
      SELECT  distinct 'ALTER ' || Object_Type || ' ' || OBJECT_NAME || ' COMPILE;'
        FROM USER_OBJECTS
       WHERE STATUS      = 'INVALID' and
             Object_Type in ( 'PROCEDURE', 'FUNCTION', 'VIEW');   
SPOOL OFF
@RECOM.sql

반응형

'Database > ORACLE' 카테고리의 다른 글

ORACLE 10G PL/SQL USER GUIDE AND REFERENCE  (0) 2009.03.08
DBMS_JOB PACKAGE의 사용 방법과 예제  (0) 2009.03.08
오라클 백업 방식과 백업 방법  (0) 2009.03.08
TAB 뷰 에 정보 생성하기  (0) 2009.03.08
SQL LOADER 사용예  (0) 2009.03.08
반응형

물론 난 백업 스크립트를 사용해서 백업하지만

윈도우 상에서 일괄적으로 백업 받을때

(낱개로는 TOAD등 툴을 통해 받을수 있지만...)

사용하면 좋은 프로그램...


프로시져백업.zip


반응형
반응형

### oracle run package (파일명 test.sh)
오라클 계정에 profile 파일의 기본 환경 path 변수들 복사

 

### oracle

sqlplus -SILENT 아이디/패스워드 <<-EOF
 WHENEVER SQLERROR EXIT 1
  WHENEVER OSERROR EXIT 1
   SET ECHO ON
   EXECUTE 호출패키지명();

   EXIT 0
   EOF

   EXITCODE=$?
   export EXITCODE

   if [ "$EXITCODE" -ne 0 ]
   then
     echo "ERROR: SQL*Plus exit code: $EXITCODE"
     echo ""
     echo "**** PROCEDURE RUN ABORTED at `date` !!! ****"
   fi
### end

 

클론 등록 방법 (클론은 root로 등록)

매일 아침 6시에 실행한다면

 

0 6 * * * su - oracle -c /home/test.sh

반응형
반응형

3. package와 import

   

3.1 패키지(package)


패키지란, 클래스의 묶음이다. 패키지에는 클래스 또는 인터페이스를 포함 시킬 수 있으며, 서로 관련된 클래스들끼리 그룹 단위로 나누어 놓음으로써 클래스를 효율적으로 관리할 수 있다.
또한 같은 이름의 클래스 일지라도 서로 다른 패키지에 존재하는 것이 가능하므로, 자신만의 패키지 체계를 유지함으로써 다른 개발자가 개발한 클래스 라이브러리의 클래스와 이름이 충돌하는 것을 피할 수 있다.
지금까지는 단순히 클래스명으로만 클래스를 구분 했지만 클래스의 실제 이름(full name)은 패키지명을 포함한 것이다. 예를 들면, String클래스의 패키지명을 포함한 이름은 java.lang.String이다. 즉, java.lang패키지에 속한 String클래스라는 의미이다. 그래서 같은 이름의 클래스일 지라도 서로 다른 패키지에 속하면 패키지명으로 구별이 가능하다.
클래스가 물리적으로 하나의 클래스파일(.class)인 것과 같이 패키지는 물리적으로 하나의 디렉토리이다. 그래서 어떤 패키지에 속한 클래스는 해당 디렉토리에 존재하는 클래스파일(.class)이어야 한다.

예를 들어, java.lang.String클래스는 물리적으로 디렉토리 java의 서브디렉토리인 lang에 속한 String.class파일이다. 그리고 우리가 자주 사용하는 System클래스 역시 java.lang패키지에 속하므로 lang디렉토리에 포함되어 있다.







String클래스는 rt.jar파일에 압축되어 있으며 아래의 그림은 압축을 풀기 전과 후의 그림이다. 클래스와 관련 파일들을 압축한 것이 jar파일(*.jar)이며, jar파일은 jar.exe이외에 알집이나 winzip으로 압축을 풀 수 있다.



디렉토리가 하위디렉토리를 가질 수 있는 것처럼, 패키지도 다른 패키지를 포함할 수 있으며 점(.)으로 구분한다. 예를 들면 java.lang패키지에서 lang패키지는 java패키지의 하위패키지이다.


- 하나의 소스파일에는 첫 번째 문장으로 단 한번의 패키지 선언을 허용한다.
- 모든 클래스는 반드시 하나의 패키지에 속해야한다.
- 패키지는 점(.)을 구분자로 하여 계층구조로 구성할 수 있다.
- 패키지는 물리적으로 클래스 파일(.class)을 포함하는 하나의 디렉토리이다.





3.2 패키지의 선언

패키지를 선언하는 것은 아주 간단하다. 클래스나 인터페이스의 소스파일(.java)에서 다음과 같이 한 줄만 적어주면 된다.


package 패키지명;



위와 같은 패키지 선언문은 반드시 소스파일에서 주석과 공백을 제외한 첫 번째 문장이어야 하며, 하나의 소스파일에 단 한번만 선언될 수 있다. 해당 소스파일에 포함된 모든 클래스나 인터페이스는 선언된 패키지에 속하게 된다.
패키지명은 대소문자를 모두 허용하지만, 클래스명과 쉽게 구분하기 하기위해서 소문자로 하는 것을 원칙으로 하고 있다.

모든 클래스는 반드시 하나의 패키지에 포함되어야 한다고 했다. 그럼에도 불구하고 지금까지 소스파일을 작성할 때 패키지를 선언하지 않고도 아무런 문제가 없었던 이유는 자바에서 기본적으로 제공하는 '이름없는 패키지(unnamed package)' 때문이다.

소스파일에 자신이 속할 패키지를 지정하지 않은 클래스는 자동적으로 '이름 없는 패키지'에 속하게 된다. 결국 패키지를 지정하지 않는 모든 클래스들은 같은 패키지에 속하는 셈이 된다.
간단한 프로그램이나 애플릿은 패키지를 지정하지 않아도 별 문제 없지만, 큰 프로젝트나 Java API와 같은 클래스 라이브러리를 작성하는 경우에는 미리 패키지를 구성하여 적용하도록 한다.

[예제7-9] PackageTest.java

package com.javachobo.book;

class PackageTest
{
      public static void main(String[] args)
      {
            System.out.println("Hello World!");
      }
}

위의 예제를 작성한 뒤 다음과 같이 '-d' 옵션을 추가하여 컴파일을 한다.


C:\j2sdk1.4.1\work>javac -d . PackageTest.java


'-d'옵션은 소스파일에 지정된 경로를 통해 패키지의 위치를 찾아서 클래스파일을 생성한다. 만일 지정된 패키지와 일치하는 디렉토리가 존재하지 않는다면 자동적으로 생성한다.
'-d'옵션 뒤에는 해당 패키지의 루트(root)디렉토리의 경로를 적어준다. 여기서는 현재디렉토리(.) 즉, 'C:\j2sdk1.4.1\work' 로 지정했기 때문에 컴파일을 수행하고 나면 다음과 같은 구조로 디렉토리가 생성된다.



기존에 디렉토리가 존재하지 않았으므로 컴파일러가 패키지의 계층구조에 맞게 새로 디렉토리를 생성하고 컴파일된 클래스파일(PackageTest.class)를 book디렉토리에 놓았다.

[참고] 만일 '-d'옵션을 사용하지 않으면, 프로그래머가 직접 패키지의 계층구조에 맞게 디렉토리를 생성해야한다.

이제는 패키지의 루트 디렉토리를 클래스패스(classpath)에 포함시켜야 한다. com.javachobo.book패키지의 루트 디렉토리는 디렉토리 'com'의 상위 디렉토리인 'C:\j2sdk1.4.1\work'이다. 이 디렉토리를 클래스패스에 포함시켜야만 실행 시 JVM이 PackageTest클래스를 찾을 수 있다.
[참고]클래스패스는 컴파일러(javac.exe)나 JVM 등이 클래스의 위치를 찾는데 사용되는 경로이다.

Windows 98이하에서는 autoexec.bat파일에 다음과 같은 명령을 한 줄 추가하면 된다.


SET CLASSPATH=.;C:\j2sdk1.4.1\work;


Windows 2000에서는 '시스템등록정보-고급-환경변수-새로만들기'를 통해 아래의 그림과 같이 설정해 준다.



';'를 구분자로 하여 여러 개의 경로를 클래스패스에 지정할 수 있으며, 맨 앞에 '.;'를 추가한 이유는 현재 디렉토리(.)를 클래스패스에 포함시키기 위해서이다.
클래스패스를 지정해 주지 않으면 기본적으로 현재 디렉토리(.)가 클래스패스로 지정되지만, 이처럼 클래스패스를 따로 지정해주는 경우에는 더 이상 현재 디렉토리가 자동적으로 클래스패스로 지정되지 않기 때문에 이처럼 별도로 추가를 해주어야 한다.
jar파일을 클래스패스에 추가하기 위해서는 경로와 파일명을 적어주어야 한다. 예를 들어 C:\j2sdk1.4.1\work\util.jar파일을 클래스패스에 포함시키려면 다음과 같이 한다.

SET CLASSPATH=.;C:\j2sdk1.4.1\work;C:\j2sdk1.4.1\work\util.jar;

이제 클래스패스가 바르게 설정되었는지 확인하기 위해 다음과 같은 명령어를 입력해보자.


C:\WINDOWS>echo %classpath%
.;C:\j2sdk1.4.1\work;


현재 디렉토리를 의미하는 '.'와 'C:\j2sdk1.4.1\work'가 클래스패스로 잘 지정되었음을 알 수 있다. 자, 이제 PackageTest예제를 실행시켜보자.

[실행결과]
C:\WINDOWS>java com.javachobo.book.PackageTest
Hello World!

실행 시에는 이와 같이 PackageTest클래스의 패키지명을 모두 적어주어야 한다.

J2SDK에 기본적으로 설정되어 있는 클래스패스를 이용하면 위의 예제에서와 같이 클래스패스를 따로 설정하지 않아도 된다. 새로 추가하고자 하는 클래스를 'J2SDK설치디렉토리\jre\classes'디렉토리에, jar파일인 경우에는 'J2SDK설치디렉토리\jre\lib\ext'디렉토리에 넣기만 하면 된다.

[참고] jre디렉토리 아래의 classes디렉토리는 J2SDK설치 시에 자동으로 생성되지 않으므로 사용자가 직접 생성해야한다.

또는 실행 시에 '-cp'옵션을 이용해서 일시적으로 클래스패스를 지정해 줄 수도 있다.

C:\WINDOWS>java -cp c:\j2sdk1.4.1\work com.javachobo.book.PackageTest



3.3 import문

소스코드를 작성할 때 다른 패키지의 클래스를 사용할 때는 패키지명이 포함된 이름을 사용해야한다. 하지만, 매번 패키지명을 붙여서 작성하기란 여간 불편한 일이 아닐 것이다.
클래스의 코드를 작성하기 전에 import문으로 사용하고자 하는 클래스의 패키지를 미리 명시해주면 소스코드에 사용되는 클래스이름에서 패키지명은 생략할 수 있다.

import문의 역할은 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다. 컴파일 시에 컴파일러는 import문을 통해 소스파일에 사용된 클래스들의 패키지를 알아 낸 다음, 모든 클래스이름 앞에 패키지명을 붙여 준다.

[참고] import문은 프로그램의 성능에 전혀 영향을 미치지 않는다. import문을 많이 사용하면 컴파일 시간이 아주 조금 더 걸릴 뿐이다.



3.4 import문의 선언

모든 소스파일(.java)에서 import문은 package문 다음에, 그리고 클래스 선언 문 이전에 위치해야한다. 그리고 import문은 package문과는 달리 한 소스파일에 여러 번 선언할 수 있다.


일반적인 소스파일의 구성은 'package문-import문-클래스선언'의 순서로 되어 있다.


import문을 선언하는 방법은 다음과 같다.


import 패키지명.클래스명;
또는
import 패키지명.*;


키워드import와 패키지명을 생략하고자 하는 클래스의 이름을 패키지명과 함께 써주면 된다. 같은 패키지에서 여러 개의 클래스가 사용될 때, import문을 여러 번 사용하는 대신 '패키지명.*'을 이용해서 지정된 패키지에 속하는 모든 클래스를 패키지명 없이 사용할 수 있다.
[참고] 클래스이름을 지정해주는 대신 '*'을 사용하면, 컴파일러는 해당 패키지에서 일치하는 클래스이름을 찾아야 하는 수고를 더 해야 할 것이다. 단지 그 뿐이다. 다른 차이는 없다.


import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;


이처럼 import문을 여러 번 사용하는 대신


import java.util.*;


위와 같이 한 문장으로 처리할 수 있다. 한 패키지에서 여러 클래스를 사용하는 경우 클래스의 이름을 일일이 지정해주는 것보다 '패키지명.*'과 같이 하는 것이 편리하다.

하지만, import하는 패키지의 수가 많을 때는 어느 클래스가 어느 패키지에 속하는지 구별하기 어렵다는 단점이 있다.
한가지 더 알아두어야 할 것은 import문에서 클래스의 이름 대신 '*'을 사용하는 것이 하위 패키지의 클래스까지 포함하는 것은 아니라는 것이다.


import java.util.*;
import java.text.*;


그래서, 위의 두 문장 대신 다음과 같이 할 수는 없다.


import java.*;


[예제7-10] ImportTest.java

import java.text.SimpleDateFormat;
import java.util.Date;

class ImportTest
{
      public static void main(String[] args)
      {
            Date today = new Date();
           
            SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
            SimpleDateFormat time = new SimpleDateFormat("hh:mm:ss a");

            System.out.println("오늘 날짜는 " + date.format(today));
            System.out.println("현재 시간은 " + time.format(today));
      }
}
[실행결과]
오늘 날짜는 2003/01/07
현재 시간은 01:59:53 오후

현재 날짜와 시간을 지정된 형식에 맞춰 출력하는 예제이다. SimpleDateFormat과 Date클래스는 다른 패키지에 속한 클래스이므로 import문으로 어느 패키지에 속하는 클래스인지 명시해 주었다. 그래서 소스에서 클래스이름 앞에 패키지명을 생략할 수 있었다.
만일 import문을 지정하지 않았다면 다음과 같이 클래스이름에 패키지명도 적어줘야 했을 것이다.


java.util.Date today = new java.util.Date();
           
java.text.SimpleDateFormat date = new java.text.SimpleDateFormat("yyyy/MM/dd");
java.text.SimpleDateFormat time = new java.text.SimpleDateFormat("hh:mm:ss a");


import문으로 패키지를 지정하지 않으면 위와 같이 '이름없는 패키지'에 속한 클래스를 제외한 모든 클래스이름 앞에 패키지명을 반드시 붙여야 한다.
지금까지 System과 String 같은 java.lang패키지의 클래스들을 패키지명 없이 사용할 수 있었던 이유는 모든 소스파일에는 묵시적으로 다음과 같은 import문이 선언되어 있기 때문이다.


import java.lang.*;


java.lang패키지에는 매우 빈번히 사용되는 중요한 클래스들이 속한 패키지이기 때문에 따로 import문으로 지정하지 않아도 되도록 한 것이다.

 

출처 : http://kin.naver.com/open100/db_detail.php?d1id=1&dir_id=10106&eid=PRkOvR1lMBu/xAgOgb4ka1KrOj9CeukU

반응형

+ Recent posts