https://intrepidgeeks.com/

 

개발자가 도움이 되는 문서와 사이트를 정리하고 수집하는 데 전념하다

Microsoft Docs Microsoft 문서 라이브러리 전 세계 최고의.NET, C\C++, C# 문서 라이브러리 중 하나

intrepidgeeks.com

 

 

 

 

이클립스에서 인텔리제이  find usage 기능 사용하기

https://hhjeong.tistory.com/179

function getToday() {
    var date = new Date();
    var year = date.getFullYear();
    var month = ("0" + (1 + date.getMonth())).slice(-2);
    var day = ("0" + date.getDate()).slice(-2);
    return year + month + day;
}

20221207

 

function formatDate(start, end, index) {
    if (index == 1) {
        return getToday().slice(start, end) + '년 '
    }
    if (index == 2) {
        return getToday().slice(start, end) + '월 '
    }
    if (index == 3) {
        return getToday().slice(start, end) + '일'
    }
}

2022년12월07일

가장 많이 쓰는 데이터 형식(자료형)

숫자

문자

날짜와 시간

 

 

 

테이블 생성 ( usertbl , buytbl )

-- 형식
CREATE TABLE [테이블명] (
	[컬럼명] [자료형] [제약조건],
	[컬럼명2] [자료형] [제약조건]

FOREIGN KEY [컬럼명] REFERENCES [테이블명] [컬럼명]  -- 외래키 설정  

);

CREATE TABLE usertbl -- 회원 테이블
( userID  	CHAR(8) NOT NULL PRIMARY KEY, -- 사용자 아이디(PK)
  name    	VARCHAR(10) NOT NULL, -- 이름
  birthYear   INT NOT NULL,  -- 출생년도
  addr	  	CHAR(2) NOT NULL, -- 지역(경기,서울,경남 식으로 2글자만입력)
  mobile1	CHAR(3), -- 휴대폰의 국번(011, 016, 017, 018, 019, 010 등)
  mobile2	CHAR(8), -- 휴대폰의 나머지 전화번호(하이픈제외)
  height    	SMALLINT,  -- 키
  mDate    	DATE  -- 회원 가입일
);


CREATE TABLE buytbl -- 회원 구매 테이블(Buy Table의 약자)
(  num 		INT AUTO_INCREMENT NOT NULL PRIMARY KEY, -- 순번(PK)
   userID  	CHAR(8) NOT NULL, -- 아이디(FK)
   prodName 	CHAR(6) NOT NULL, --  물품명
   groupName 	CHAR(4)  , -- 분류
   price     	INT  NOT NULL, -- 단가
   amount    	SMALLINT  NOT NULL, -- 수량
   FOREIGN KEY (userID) REFERENCES usertbl(userID)
);

 

 

mySQL 제약조건

PRIMARY KEY

  • 대부분의 테이블은 기본키를 하나씩 가지고 있다.
  • 절대 중복될 수 없는 값
  • NULL 이 입력될 수 없다.
  • 많은 행의 데이터를 구분할 수 있는 식별자이다.

FOREIGN KEY

  • 두 테이블 사이의 관계를 선언함.
  • 하나의 테이블이 다른 테이블에 의존하게 됨.
  • 외래키 테이블이 참조하는 테이블의 기준 열은 반드시 Primary Key 거나 Unique 제약조건이 설정되어 있어야한다.

UNIQUE

  • 중복되지 않는 유일한 값
  • Primary Key 와 차이점은. NULL을 허용한다.

CHECK

  • 입력되는 데이터를 점검하는 기능이다.
--형식
CREATE TABLE usertbl -- 회원 테이블
( userID  	CHAR(8)
  name    	VARCHAR(10) 
  birthYear   INT CHECK ( birthYear > 1996 )
);

 

DEFAULT

  • 값을 입력하지 않았을 때, 자동으로 입력되는 기본 값을 정의한다.
--형식
CREATE TABLE usertbl -- 회원 테이블
( userID  	CHAR(8) 
  name    	VARCHAR(10) DEFAULT '이름없음' 
  birthYear   INT 
);

NULL / NOT NULL

  • NULL 을 허용 / 비허용 하게 해주는 제약조건이다.
CREATE TABLE usertbl -- 회원 테이블
( userID  	CHAR(8) NOT NULL
  name    	VARCHAR(10)
  birthYear   INT 
);

 

 

 

 

테이블 삭제 DROP TABLE

--형식
DROP TABLE [테이블명];

 

테이블 수정 ALTER TABLE

-- 열의 추가
ALTER TABLE [테이블명]
	ADD [컬럼명] [자료형] [제약조건];

-- 열의 삭제
ALTER TABLE [테이블명]
	DROP COLUMN [컬럼명];

-- 열의 이름 및 데이터 형식 변경
ALTER TABLE [테이블명]
	CHANGE COLUMN [기존컬럼명] [변경할컬럼명] [변경할자료형] [제약조건];

-- 스키마 명으로 제약조건 조회
select * from information_schema.table_constraints
where CONSTRAINT_SCHEMA = '스키마명'; 

-- 테이블 명으로 제약조건 조회  ( 제약조건 삭제 할 때 필요함 )
select * from information_schema.table_constraints
where TABLE_NAME  = '테이블명';    -- WHERE 절 이기때문에 따옴표 필수

-- 열의 제약조건 추가 및 삭제
ALTER TABLE [테이블명]
	ADD PRIMARY KEY (컬럼명);  -- 기본키 추가
  ADD FOREIGN KEY (컬럼명) REFERENCES 테이블명(컬럼명);  -- 외래키 추가
	ADD UNIQUE KEY (컬럼명);    -- 유니크 키 추가
	ADD CHECK (조건식);    -- 체크 추가
	ALTER COLUMN 컬럼명 SET DEFAULT 값;    -- 디폴트값 추가

ALTER TABLE [테이블명]
	DROP PRIMARY KEY;  -- 기본키 제약조건 삭제
	DROP FOREIGN KEY [제약조건명];  -- 외래키 제약조건 삭제
	DROP INDEX | KEY [제약조건명];  -- 유니크 제약조건 삭제 (INDEX , KEY 둘 다 같은 명령어)
  DROP CHECK [제약조건명];   -- 체크 제약조건 삭제
  ALTER COLUMN 컬럼명 DROP DEFAULT;   -- 디폴트값 제거

 

 

외래키 생성 시 추가옵션

-- 바로 위에있는 테이블 수정에서 코드를 일부 가져 옴.

ALTER TABLE [테이블명]
  ADD FOREIGN KEY (컬럼명) REFERENCES 테이블명(컬럼명)
	ON DELETE CASCADE   -- 기존 테이블 삭제 시, 제약조건 테이블도 자동 삭제 
	ON UPDATE CASCADE  -- 기존 테이블 변경 시, 제약조건 테이블도 자동 변경

-- 옵션을 추가하지 않고 삭제 / 수정 요청시 , 무결성 제약조건에 위배된다는 오류와 
-- 함께 수행되지 않습니다.

DROP TABLE EMPLOYEE;
DROP TABLE DEPARTMENT;
DROP TABLE JOB;
DROP TABLE LOCATION;
DROP TABLE NATIONAL;
DROP TABLE SAL_GRADE;

--------------------------------------------------------
--  DDL for Table DEPARTMENT
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."DEPARTMENT" 
   ( "DEPT_ID" CHAR(2 BYTE), 
"DEPT_TITLE" VARCHAR2(35 BYTE), 
"LOCATION_ID" CHAR(2 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."DEPT_ID" IS '부서코드';
   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."DEPT_TITLE" IS '부서명';
   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."LOCATION_ID" IS '지역코드';
   COMMENT ON TABLE "EMPLOYEE"."DEPARTMENT"  IS '부서';
-- REM INSERTING into EMPLOYEE.DEPARTMENT
-- SET DEFINE OFF;
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D1','인사관리부','L1');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D2','회계관리부','L1');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D3','마케팅부','L1');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D4','국내영업부','L1');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D5','해외영업1부','L2');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D6','해외영업2부','L3');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D7','해외영업3부','L4');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D8','기술지원부','L5');
Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D9','총무부','L1');
--------------------------------------------------------
--  DDL for Index 엔터티1_PK2
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK2" ON "EMPLOYEE"."DEPARTMENT" ("DEPT_ID") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table DEPARTMENT
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."DEPARTMENT" ADD CONSTRAINT "DEPARTMENT_PK" PRIMARY KEY ("DEPT_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."DEPARTMENT" MODIFY ("LOCATION_ID" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."DEPARTMENT" MODIFY ("DEPT_ID" NOT NULL ENABLE);

--------------------------------------------------------
--  DDL for Table EMPLOYEE
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."EMPLOYEE" 
   ( "EMP_ID" VARCHAR2(3 BYTE), 
"EMP_NAME" VARCHAR2(20 BYTE), 
"EMP_NO" CHAR(14 BYTE), 
"EMAIL" VARCHAR2(25 BYTE), 
"PHONE" VARCHAR2(12 BYTE), 
"DEPT_CODE" CHAR(2 BYTE), 
"JOB_CODE" CHAR(2 BYTE), 
"SAL_LEVEL" CHAR(2 BYTE), 
"SALARY" NUMBER, 
"BONUS" NUMBER, 
"MANAGER_ID" VARCHAR2(3 BYTE), 
"HIRE_DATE" DATE, 
"ENT_DATE" DATE, 
"ENT_YN" CHAR(1 BYTE) DEFAULT 'N'
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_ID" IS '사원번호';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_NAME" IS '직원명';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_NO" IS '주민등록번호';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMAIL" IS '이메일';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."PHONE" IS '전화번호';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."DEPT_CODE" IS '부서코드';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."JOB_CODE" IS '직급코드';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."SAL_LEVEL" IS '급여등급';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."SALARY" IS '급여';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."BONUS" IS '보너스율';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."MANAGER_ID" IS '관리자사번';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."HIRE_DATE" IS '입사일';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."ENT_DATE" IS '퇴사일';
   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."ENT_YN" IS '재직여부';
   COMMENT ON TABLE "EMPLOYEE"."EMPLOYEE"  IS '사원';
-- REM INSERTING into EMPLOYEE.EMPLOYEE
-- SET DEFINE OFF;
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('200','선동일','621235-1985634','sun_di@uni.or.kr','01099546325','D9','J1','S1',8000000,0.3,null,to_date('90/02/06','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('201','송종기','631156-1548654','song_jk@uni.or.kr','01045686656','D9','J2','S1',6000000,null,'200',to_date('01/09/01','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('202','노옹철','861015-1356452','no_hc@uni.or.kr','01066656263','D9','J2','S4',3700000,null,'201',to_date('01/01/01','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('203','송은희','631010-2653546','song_eh@uni.or.kr','01077607879','D6','J4','S5',2800000,null,'204',to_date('96/05/03','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('204','유재식','660508-1342154','yoo_js@uni.or.kr','01099999129','D6','J3','S4',3400000,0.2,'200',to_date('00/12/29','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('205','정중하','770102-1357951','jung_jh@uni.or.kr','01036654875','D6','J3','S4',3900000,null,'204',to_date('99/09/09','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('206','박나라','630709-2054321','pack_nr@uni.or.kr','01096935222','D5','J7','S6',1800000,null,'207',to_date('08/04/02','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('207','하이유','690402-2040612','ha_iy@uni.or.kr','01036654488','D5','J5','S5',2200000,0.1,'200',to_date('94/07/07','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('208','김해술','870927-1313564','kim_hs@uni.or.kr','01078634444','D5','J5','S5',2500000,null,'207',to_date('04/04/30','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('209','심봉선','750206-1325546','sim_bs@uni.or.kr','0113654485','D5','J3','S4',3500000,0.15,'207',to_date('11/11/11','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('210','윤은해','650505-2356985','youn_eh@uni.or.kr','0179964233','D5','J7','S5',2000000,null,'207',to_date('01/02/03','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('211','전형돈','830807-1121321','jun_hd@uni.or.kr','01044432222','D8','J6','S5',2000000,null,'200',to_date('12/12/12','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('212','장쯔위','780923-2234542','jang_zw@uni.or.kr','01066682224','D8','J6','S5',2550000,0.25,'211',to_date('15/06/17','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('213','하동운','621111-1785463','ha_dh@uni.or.kr','01158456632',null,'J6','S5',2320000,0.1,null,to_date('99/12/31','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('214','방명수','856795-1313513','bang_ms@uni.or.kr','01074127545','D1','J7','S6',1380000,null,'200',to_date('10/04/04','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('215','대북혼','881130-1050911','dae_bh@uni.or.kr','01088808584','D5','J5','S4',3760000,null,null,to_date('17/06/19','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('216','차태연','770808-1364897','cha_ty@uni.or.kr','01064643212','D1','J6','S5',2780000,0.2,'214',to_date('13/03/01','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('217','전지연','770808-2665412','jun_jy@uni.or.kr','01033624442','D1','J6','S4',3660000,0.3,'214',to_date('07/03/20','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('218','이오리','870427-2232123','loo_or@uni.or.kr','01022306545',null,'J7','S5',2890000,null,null,to_date('16/11/28','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('219','임시환','660712-1212123','im_sw@uni.or.kr',null,'D2','J4','S6',1550000,null,null,to_date('99/09/09','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('220','이중석','770823-1113111','lee_js@uni.or.kr',null,'D2','J4','S5',2490000,null,null,to_date('14/09/18','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('221','유하진','800808-1123341','yoo_hj@uni.or.kr',null,'D2','J4','S5',2480000,null,null,to_date('94/01/20','RR/MM/DD'),null,'N');
Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('222','이태림','760918-2854697','lee_tr@uni.or.kr','01033000002','D8','J6','S5',2436240,0.35,'100',to_date('97/09/12','RR/MM/DD'),to_date('17/09/12','RR/MM/DD'),'Y');
--------------------------------------------------------
--  DDL for Index 엔터티1_PK
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK" ON "EMPLOYEE"."EMPLOYEE" ("EMP_ID") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table EMPLOYEE
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" ADD CONSTRAINT "EMPLOYEE_PK" PRIMARY KEY ("EMP_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("SAL_LEVEL" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("JOB_CODE" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_NO" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_NAME" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_ID" NOT NULL ENABLE);

--------------------------------------------------------
--  DDL for Table JOB
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."JOB" 
   ( "JOB_CODE" CHAR(2 BYTE), 
"JOB_NAME" VARCHAR2(35 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."JOB"."JOB_CODE" IS '직급코드';
   COMMENT ON COLUMN "EMPLOYEE"."JOB"."JOB_NAME" IS '직급명';
   COMMENT ON TABLE "EMPLOYEE"."JOB"  IS '직급';
-- REM INSERTING into EMPLOYEE.JOB
-- SET DEFINE OFF;
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J1','대표');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J2','부사장');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J3','부장');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J4','차장');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J5','과장');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J6','대리');
Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J7','사원');
--------------------------------------------------------
--  DDL for Index 엔터티1_PK1
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK1" ON "EMPLOYEE"."JOB" ("JOB_CODE") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table JOB
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."JOB" ADD CONSTRAINT "JOB_PK" PRIMARY KEY ("JOB_CODE")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."JOB" MODIFY ("JOB_CODE" NOT NULL ENABLE);

--------------------------------------------------------
--  DDL for Table LOCATION
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."LOCATION" 
   ( "LOCAL_CODE" CHAR(2 BYTE), 
"NATIONAL_CODE" CHAR(2 BYTE), 
"LOCAL_NAME" VARCHAR2(40 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."LOCAL_CODE" IS '지역코드';
   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."NATIONAL_CODE" IS '국가코드';
   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."LOCAL_NAME" IS '지역명';
   COMMENT ON TABLE "EMPLOYEE"."LOCATION"  IS '지역';
-- REM INSERTING into EMPLOYEE.LOCATION
-- SET DEFINE OFF;
Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L1','KO','ASIA1');
Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L2','JP','ASIA2');
Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L3','CH','ASIA3');
Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L4','US','AMERICA');
Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L5','RU','EU');
--------------------------------------------------------
--  DDL for Index 엔터티1_PK3
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK3" ON "EMPLOYEE"."LOCATION" ("LOCAL_CODE") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table LOCATION
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."LOCATION" ADD CONSTRAINT "LOCATION_PK" PRIMARY KEY ("LOCAL_CODE")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."LOCATION" MODIFY ("NATIONAL_CODE" NOT NULL ENABLE);
  ALTER TABLE "EMPLOYEE"."LOCATION" MODIFY ("LOCAL_CODE" NOT NULL ENABLE);

--------------------------------------------------------
--  DDL for Table NATIONAL
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."NATIONAL" 
   ( "NATIONAL_CODE" CHAR(2 BYTE), 
"NATIONAL_NAME" VARCHAR2(35 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."NATIONAL"."NATIONAL_CODE" IS '국가코드';
   COMMENT ON COLUMN "EMPLOYEE"."NATIONAL"."NATIONAL_NAME" IS '국가명';
   COMMENT ON TABLE "EMPLOYEE"."NATIONAL"  IS '국가';
-- REM INSERTING into EMPLOYEE.NATIONAL
-- SET DEFINE OFF;
Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('KO','한국');
Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('JP','일본');
Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('CH','중국');
Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('US','미국');
Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('RU','러시아');
--------------------------------------------------------
--  DDL for Index 엔터티1_PK4
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK4" ON "EMPLOYEE"."NATIONAL" ("NATIONAL_CODE") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table NATIONAL
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."NATIONAL" ADD CONSTRAINT "NATIONAL_PK" PRIMARY KEY ("NATIONAL_CODE")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."NATIONAL" MODIFY ("NATIONAL_CODE" NOT NULL ENABLE);

--------------------------------------------------------
--  DDL for Table SAL_GRADE
--------------------------------------------------------

  CREATE TABLE "EMPLOYEE"."SAL_GRADE" 
   ( "SAL_LEVEL" CHAR(2 BYTE), 
"MIN_SAL" NUMBER, 
"MAX_SAL" NUMBER
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."SAL_LEVEL" IS '급여등급';
   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."MIN_SAL" IS '최소급여';
   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."MAX_SAL" IS '최대급여';
   COMMENT ON TABLE "EMPLOYEE"."SAL_GRADE"  IS '급여등급';
-- REM INSERTING into EMPLOYEE.SAL_GRADE
-- SET DEFINE OFF;
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S1',6000000,10000000);
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S2',5000000,5999999);
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S3',4000000,4999999);
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S4',3000000,3999999);
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S5',2000000,2999999);
Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S6',1000000,1999999);
--------------------------------------------------------
--  DDL for Index 엔터티2_PK
--------------------------------------------------------

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티2_PK" ON "EMPLOYEE"."SAL_GRADE" ("SAL_LEVEL") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;
--------------------------------------------------------
--  Constraints for Table SAL_GRADE
--------------------------------------------------------

  ALTER TABLE "EMPLOYEE"."SAL_GRADE" ADD CONSTRAINT "엔터티2_PK" PRIMARY KEY ("SAL_LEVEL")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"  ENABLE;
  ALTER TABLE "EMPLOYEE"."SAL_GRADE" MODIFY ("SAL_LEVEL" NOT NULL ENABLE);


COMMIT;

IntelliJIdea2022.2 버전으로 작성되었습니다.

 

Tomcat 프로젝트 생성시

 

1. Tomcat 9 다운로드

 

https://tomcat.apache.org/download-90.cgi

 

Apache Tomcat® - Apache Tomcat 9 Software Downloads

Welcome to the Apache Tomcat® 9.x software download page. This page provides download links for obtaining the latest version of Tomcat 9.0.x software, as well as links to the archives of older releases. Unsure which version you need? Specification version

tomcat.apache.org

zip 파일을 다운받습니다 

경로는 C드라이브 바로 위를 추천드립니다 경로에 한글이 섞이면 난감한 상황이 발생할 수 도 있습니다 . . . .

설치가 끝나면 압축을 풀어줍니다.

 

 

 

2. 인텔리제이 New Project

Jakarta EE  클릭

Template  -> Web Application 선택

Application server  -> 아마 인텔리제이가 바로 경로를  찾아줄 수도? 있는데, <none> 이시라면 

직접 경로를 지정해주시면 됩니다. ( 아까 C드라이브 위에 풀었던 경로. 하위에 bin 이 있는 폴더를 선택.)

 

Build system ->  Gradle

 

JDK를 바로 다운로드 할 수 있습니다.

JDK  ->  1.8 (8) , 11버전이 가장 대중적인 버전이라고 하네요

Windows 사용자는 corretto 가 호환성이 좋고

Mac 사용자는 GraalVM 이 호환성이 좋다고 합니다 ( 뭐가 어떻게 좋은지는 직접 찾아봅시다 흠흠 ) 

 

 

NEXT !!!!!!!!!!

 

 

 

Java EE 8 선택하시고 Create !!!!!!!!!!!!!!!

 

 

성능에 따라 몇 분동안 기다리면... ( Gradle 세팅 등 초기설정을 위한 파일을 다운로드 받는중 )

 

우측 상단에 Tomcat 9버전이 잡혀 있으면 성공 ~ 

 

성공에 들뜬 나머지 바로 재생버튼을 누르게되면 . . . . 

아마 한글이 깨져있을겁니다

 

추가 설정이 필요한데요 

Help - Edit Custom VM Options  -> 

-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-8

 

 

우측 상단 Tomcat 9.0 클릭 -> Edit Configuration

 

VM Options ->  -Dfile.encoding=UTF-8 

 

 

 

 

혹시나 8080 port 가 이미 사용중 ~ 이라는 오류가 발생하신다면

(높은확률로) 아마 본인 컴퓨터에 Oracle 세팅이 되어있기 때문인데요.     -> 그녀석도 8080 포트를 사용함

 

https://leeyongjin.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-11g-express%EC%97%90%EC%84%9C-8080-%ED%8F%AC%ED%8A%B8-%EB%B3%80%EA%B2%BD

 

오라클 11g express에서 8080 포트 변경

1. sql plus 실행 > sqlplus /noglog 2. 관리자로 연결 SQL> conn /as sysdba 3. 현재 포트확인 SQL> select dbms_xdb.gethttpport() from dual; 4. 포트변경 내장프로시져 실행 SQL> exec dbms_xdb.sethttpport(9..

leeyongjin.tistory.com

 

여기를 참고하시면 됩니다

 

 


외부 프로젝트를 불러올 때

예시로 Tomcat을 설정하지않은(none) Tomcat 프로젝트를 인텔리제이에서 열어보겠습니다

 

 

 

아마 우측 상단이 비어있을텐데요. Tomcat을 직접 추가 해 봅시다.

Edit

 

 

 

 

 

 

 

더하기 누르시고 조금 스크롤하시면 Tomcat Local 이 있습니다.

 

 

 

Deployment 탭에 가서 Artifact   ->  exploded ( 비압축 이라는 뜻입니다 )

 

 

 

 

 

 

주소는 깔끔 하게     "  /   "  

 

 

 

다시 Server 탭으로 돌아와서

 

action 설정을 할 수 있습니다. 

update classes and resources 선택 !!!  ( 정적파일이 자동으로 반영 됨 ) ( html, jsp 등등 )

 

 

좌측 하단에 Deploy All 버튼을 누르면 서버 재시작 없이  동적파일 반영. ( java 파일 )

 

 

 

하루에 한 챕터도 못하는 날이 많아서 n일차보다는 n번째로 하는게 나을거같네요 리액트가 참 알아야할게 많습니다

 

 

 

React 라이브러리에 무슨 기능이 있는지 보려면~~

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 
    <title>Document</title>


</head>
<body>
<script type="text/babel">

        console.log(React)
        
    </script>
</body>
</html>

콘솔을 찍어보면 된다. 

 

 

 

React의 다양한 기능 중에 가장 중요하다고 생각되는 개념 (내 판단)

React Hooks의 대표적인 기능 useState, useEffect, useReducer, useContext 를 간단하게 정리 해보겠습니다

 

먼저 Hooks 가 무엇인지 에 대한 설명.

Hooks는 리액트 16.8에서 새로 도입된 기능으로,
        함수 컴포넌트에서 사용 불가능한 생명주기 메소드의 한계점으로 인해
        상태관리 및 랜더링 이후 시점 컨트롤 등 다양한 문제를 해결하기 위해 만든 함수 집합을 의미한다.


        컴포넌트가 랜더링 된 이후에 특정 작업을 수행할 필요가 있다면
        클래스형 컴포넌트에서는 componentDidMount 혹은 componentDidUpdate 메소드를 이용하면 된다.
        하지만, 함수형 컴포넌트에서는 생명주기 api 사용이 불가능하다. ( 클래스형 컴포넌트에서만 가능했다 )
        그렇기에 함수형 컴포넌트에서도 랜더링 된 이후 시점에 수행할 내용이 필요한 경우
        사용할 수 있게 추가한 hooks 가  useEffect이다.
 
 
 
 

0. props

Props 상위 컴포넌트 하위 컴포넌트에게 데이터를 전달하고자 할 때 사용하는 개념이다. 이때 전달하는 데이터는 하나의 값일수도 있고 함수일수도 있다.

아마도 properties (속성) 의 약자가 아닐까 ??? 

App.js

import React from 'react';
import PropsTest from './PropsTest';

// 상위 컴포넌트 App 에서 하위 컴포넌트 PropsTest 에게 props 전달 중
const App = () => {
  return(
    <>
      <PropsTest name="이대엽" /> 
    </>
  );
};

export default App;

 

PropsTest.js

import React from "react";

const PropsTest = ({ name }) => {
  return <h2>{name}님 어서오세요!</h2>;
};

export default PropsTest;

PropsTest.js는 상위 컴포넌트인 App.js로 부터 name값을 전달 받아 사용하고 있다.

 

 

1. useState

State란 컴포넌트 내부에서 가지고 있는 해당 컴포넌트의 상태 값들을 의미한다.

 

 사용 형태

// 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수

const [ 변수 , set변수 ] = useState(변수의 초기값)

 

const [ count , setCount ] = useState( 0 )

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
     <!-- 버전은 명시 상관x    standalone 가능 -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 
    <title>Document</title>


</head>
<body>
    <div id="root"></div>
    함수형 컴포넌트 에서는 state를 사용할 수 없었음. 

    <script type="text/babel">
        
        const {useState} = React;

        // const Say = () => {}
        function Say() {
            
            console.log(useState('기본상태'));
            let val = 0;  // 상태값이 하나라도 바뀌면 Say 컴포넌트가 새로 렌더링 되면서 계속 0으로 초기화 됨
            // 배열로 반환됨, 
            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [message , setMessage] = useState('기본상태')

            const onClickEnter = () => setMessage('하이요')  // onClick에 걸어줄 함수
            const onClickLeave = () => setMessage('바이요')  // onClick에 걸어줄 함수

            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [color , setColor] = useState('black')

            // 첫 번째 인자는 상태값 저장 변수, 두 번째 인자는 상태를 바꿔주는 함수
            const [backgroundColor, setBackgroundColor] = useState('white')

            // style 안에있는 color, backgroundColor 변수가, 위에 useState로 만든 상태값 저장 변수 !!
            return(
                <>
                    <h1 style = {{color, backgroundColor}}>{message}</h1>
                    <button onClick={onClickEnter}>입장</button>
                    <button onClick={onClickLeave}>퇴장</button>
                    <button onClick={()=>{
                        val = val + 1;
                        console.log(`지역변수 업데이트 : ${val}`);
                    }}>지역변수</button>
                    <div>
                        <button onClick= {() =>setColor('red') }>빨간색</button>    
                        <button onClick= {() =>setColor('purple') }>보라색</button>    
                        <button onClick= {() =>setColor('green') }>초록색</button>    
                    </div>
                    <div>
                        <button onClick= {() =>setBackgroundColor('white') }>기본배경</button>    
                        <button onClick= {() =>setBackgroundColor('black') }>반전배경</button>    
                    </div>                        
                
                </>
                
            );
        }

        ReactDOM.render( <Say/> , document.getElementById('root'));
        
    </script>
</body>
</html>

html 파일로 만들어서 쌩으로 실행이 가능한 코드입니다.

 

▲실행 결과 사진

 

 

input 창의 value 를 useState로 저장하는 방법

UseStateTest.js     ( App.js 는 생략 )

import React, { useState } from "react";

const UseStateTest = () => {
  
  const [name, setName] = useState('');
  const onChange = (e) => {
    setName(e.target.value);
  };

  return (
    <>
      <input onChange={onChange} />
      <h1>제 이름은 {name}입니다.</h1>
    </>
  );
};

export default UseStateTest;

onChange 함수에서 매개변수로 사용된 e 는 event 의 약자이며 , 로그를 찍어보면 

 

 

 

 

 

e 가 좀 괴상하게 생기긴 했는데, e에 있는 target 속성을 열어보면 input이 있는걸 확인할 수 있다.

 

 

 

onChange 가 될 때 마다, setName 함수가 호출될 것이고          그 말은 곧 ,

input 에 입력하는값이 즉시 name 상태 저장 변수로 저장된다.

 

 

2. useEffeft

useEffect란 컴포넌트가 조건에따라 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook 이다.

useEffect(()=> {
  // 실행하고자 하는 함수
  () => { 
  
  }
}, []);

 

 

 

1. 컴포넌트가 렌더링 될 때 마다 (의존성 배열 생략) ,

 

2. 최초 렌더링 시 한 번만 (의존성 배열에 공백),       (최초 렌더링 = 마운트 되다)

 

3. 특정 변수의 상태가 변할 때만 (의존성 배열에 상태 변수 명시),

용어 설명 !!! ->    deps : dependency (의존성)

useEffect 내에서 사용하는 State나 Props가 존재한다면, useEffect의 deps에 넣어주는 것이 규칙이다. 만약 넣어주지 않는 다면 useEffect 내의 함수가 실행될 때 최신 State, Props를 가리키지 않는다는 문제점이 생긴다!

 

4. 컴포넌트가 사라질 때, 특정 값이 바뀌기 직전에 (useEffect 안에 return 함수 (clean-up) )

 

Timer 컴포넌트

토글 버튼을 눌러서 1초마다 한번 씩 현재시간을 log에 출력하거나, 출력을 그만두는 기능.

 

 

특정값이 업데이트 되기 직전에 cleanup 함수를 사용하고 싶다면  deps(의존성배열) 안에 감지하고 싶은 값을 넣어주면 된다. (사진은 없다)

 

Timer 컴포넌트를 하위컴포넌트로 렌더링 시키는 중인 App.js 

 

 

 

 

컴포넌트가 사라질 때, 수행되는 함수(clean-up) 라서 뒷정리 함수라는 이름으로도 불린다. 

 

 

 

3. useReducer

useReducer 란 다양한 컴포넌트의 state를 일괄적으로 업데이트 할 때 사용하는 Hook 이다.

리듀서는 새로운 상태를 만들 때 반드시 불변성을 지켜주어야 한다. (기존 state의 값 변경 하지 말고 새롭게 만들 것)
리듀서를 사용했을 때 가장 큰 장점은 컴포넌트 업데이트 로직을 컴포넌트 밖으로 분리할 수 있다는 점이다.

 

react의 심오한 기술중 하나인 redux 에서 핵심 역할을 하는 함수이기도 하다.
너무 어려워서  나도 글과 말로 설명할 자신이 없다. ㄱ ㅡ
 
 Counter 컴포넌트
 
컴포넌트 바깥에 정의된 reducer 함수
 

1. 상태의 변화는 dispatch 의 호출에 의해서만 일어난다. 

2. dispatch 의 매개변수는

업데이트를 하기 위해 필요한 정보 객체  { type : 'INCREMENT' } , { type: 'DECREMENT' }

 = reducer 함수의 두 번째 인자로 들어가게 됨

 

이다. 

3. reducer 함수에서만 실질적인 값의 변화가 일어난다. (새로운 상태값이 반환 된다.)

 

 

value의 증가 감소의 상태 관리를 reducer 함수에서 모두 관리하고 있다. 

하나의 함수에서 상태관리를 하는것이 reducer의 장점.

 

 

 

4. useContext

Context 란?

React 공식 문서에 쓰여있는 설명에는, ' context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다 ' 라고 적혀있다.

 

 

일반적인 React 어플리케이션에서 데이터는 props를 통해서 부모에서 자식에게 전달 되어야 한다.

  Parent.js

 

Child.js

Parent 의 return 부분에서 컴포넌트 렌더링부분에 number={number} 라는 속성(props) 을 추가하여 컴포넌트간에 변수를 공유 할 수있다.

 

 

 

자식에서 부모로 전달되는 경우도 있긴 하지만, 구조가 기구하다.

부모에서 만든 함수를 자식에게 부여해서,

자식에서 그 함수를 이용하여 상태를 변화시키고 

부모가 변화를 감지하여 렌더링 하는 방식이다 .

 

    Parent.js

 

   Child.js

 

부모에서 만든 함수(  getData(number) )        를 자식에게 부여해서,   (   <Child getData={getData} ></Child>  }

자식에서 그 함수를 이용하여 상태를 변화시키고         (  onClick 에서 getData 함수 사용중  -> 상태 변화 됨 )

부모가 변화를 감지하여 렌더링 하는 방식이다 .

 

 

 

컴포넌트가 많아지면 많아질수록 , 이렇게 일일이 props 를 전달하기에는 현실적으로 무리...

 에휴 

 

그래서 사용하는것이 useContext.

 

어플리케이션 안의 여러 컴포넌트들에게 props를 전달해줘야 하는 경우

useContext를 이용하면 명시적으로 props를 넘겨주지 않아도 값을 공유할 수 있게 해준다.

 

 

<script type="text/babel">
        /*   context는 React컴포넌트 트리 안에서 전역적으로 데이터를 공유할 수 있도록 고안된 방법이다. 
         * 트리 구조가 복잡해질 수록 하위 컴포넌트로 props를 전달하기 위해 drilling  이 발생할 수 있게 되고,
         * 그러면 유지보수가 매우 힘들어지고 코드를 읽기도 힘들어지게 된다.
         * 하지만 context를 사용하면 중간 엘리먼트들에게 props를 넘겨주지 않아도 되고, 유지보수도 훨씬 수월해지게 된다.
         * 
         * 단, context를 사용하면 컴포넌트를 재사용하기 어려워지기 때문에 꼭 필요할 때만 써야 한다.
         * 따라서 때에 따라서는 context보다 컴포넌트 합성이 더 간단한 해결책일 수 있다.
         */
        const {useState, createContext, useContext} = React;

        // 주의 : 첫글자 대문자로 해야함
        const DarkModeContext = createContext(null);
        const UserContext = createContext(null);

        function Header() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);

            const {isDark} = context;

            return (
                <header className="header"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'lightgray' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <h1>어서오세요 헤더입니다</h1>
                </header>
            )
        }

        function Content() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);
            const userContext = useContext(UserContext);

            const {isDark} = context;
            const {username, setUsername} = userContext;
            setUsername('이대엽'); // 바로 실행이 되긴되네요

            return (
                <div className="content"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'white' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <p>콘텐츠 입니다<br/></p>
                    <p>{username}님 안녕하세요 ?</p>
                </div>
            )
        }

        function Footer() {
            // 사용이 필요한 곳에서 꺼내서 쓴다 >?
            const context = useContext(DarkModeContext);

            const {isDark, setIsDark} = context;
            const toggleHandler = () => {
                setIsDark(!isDark);
            }

            return (
                <footer className="footer"
                style = {{
                    backgroundColor:  isDark ? 'black' : 'lightgray' ,
                    color : isDark? 'white' : 'black'
                }}>
                    <button onClick={toggleHandler}>{isDark? '다크모드 해제' : '다크모드 전환!!' }</button>
                    우리집은 대한민국 부산시
                </footer>
            )
        }

        function Page({isDark, setIsDark}) {
            return (
                <div className="page">
                    <Header />
                    <Content />
                    <Footer />
                </div>
            )
        }

        // <Header isDark={isDark}/>
        // <Content isDark={isDark}/>
        // <Footer isDark={isDark} setIsDark={setIsDark}/>
        
        function App() {
            // App 에서 만든 setState 를 다른 컴포넌트한테 계속 넘겨주면서 사용할 수 있구나 
            const [isDark, setIsDark] = useState(false)
            const [username, setUsername] = useState('유재석')


            /* Provider는 context를 구독하고 있는 컴포넌트들에게 context의 변화를 알리는 역할을 한다.
             * Provider(제공자)는 value props을 이용하여 하위 컴포넌트에게 값을 전달한다.
             * 이 때 값을 전달받을 수 있는 컴포넌트 수에는 제한이 없다.
             * 
             * Provider 하위에서 context를 구독하는 모든 컴포넌트는 value prop이 바뀔 때 마다 다시 랜더링된다.
             *  즉 isDark 가 바뀌면 전체리랜더링
             * */


            return (
                // <Page isDark = {isDark} setIsDark = {setIsDark}/>
                // 하위 컴포넌트 들에서도 사용이 가능하다 
                <UserContext.Provider value = {{username, setUsername}}>
                    <DarkModeContext.Provider value = {{isDark, setIsDark}}>
                        <Page/>
                    </DarkModeContext.Provider>
                </UserContext.Provider>
            )
            
        }
        

        ReactDOM.render(<App/>, document.getElementById('root'));
    </script>

최상단에서 createContext 를 하고,  컴포넌트의 부모위치에서 Context.Provider 로 공유받을 수 있게 설정 하고.

각각의 컴포넌트에서도 따로 선언하여 사용하는 방식이다.

 

설명이 짧아서 미안하다

나  많은일이 있었다  힘들다 진짜

'더존 노션 필기 옮기기 > React' 카테고리의 다른 글

React 비상사태  (0) 2022.09.08
React 1일차 컴포넌트 ,JSX , props  (0) 2022.09.08

이 라이브러리의 업데이트가 너무 잦아서

옛날자료(정보 양이 많긴 함) + 현대자료(정보가 적음, 공식문서는 영어임) 들의 충돌이 너무많다

 

 

일단 할 수 있는 것과 할 수 없는 것의 구분부터 시작해야 할 것 같다.

 

 

 

리액트 컴포넌트의 역사

// * 첫 번째 인자는 만들려는 엘리먼트의 타입을 문자열로 정의한다.
// * 두 번째 인자는 만드는 엘리먼트의 프로퍼티를 표현한다.
// * 세 번째 인자는 엘리먼트의 자식 노드(텍스트노드)를 표현한다.

const greetingElement = React.createElement('h1', {id : "greeding1" } , 'hello world');

// 결과 
<h1 id="greeding1"> hello world </h1> 
라는 Element ( 리액트 에서는 일반적으로 컴포넌트 라는 개념으로 더 많이 알려져있다. )
가 생성된다.

옛날에는 정말 엿같은 방식으로 컴포넌트를 만들고 있었네요

그 이후에도 몇 가지 방법들이 추가가 되었지만

createClass 함수
클래스형 컴포넌트

리액트 16버전 이후로는 ‘함수형 컴포넌트’ 를 주로 사용하고 있습니다.

function Hellowolrd() {
            return React.createElement(
                    'h1',
                    {className : 'greeting'},
                    'Hello world!'
                );
        }
                                    // 함수 이름
ReactDOM.render(React.createElement(Hellowolrd) , document.getElementById('root'));

뭐지 정리해보고나니까 달라진게 없는데요 ??? ??????????????????   (바벨을 아직 적용 안해서)

 

바벨 이라는 문법 변환 도구를 적용 한 뒤, ( 밑에 JSX 내용을 보고 오면 더 좋음 )

function Title2() {                        // 1. 함수 만들어 (첫글자 대문자 !!)
    return(                                 // 2. 리턴 만들어
        <h1>함수형 컴포넌트</h1>            // 3. JSX 엘리먼트 만들어
    );
 }

 ReactDOM.render(<Title2/>, document.getElementById('root'));

ReactDOM.render(element, container) 인자(args) 정리

element = 내가 만든 DOM

container = 어느 노드에 넣을지 (그 노드가 부모가 되고, 내가 만든 DOM은 자식이 된다 )

JSX가 무엇인가

JS (JavaScript) + XML 로써 자바스크립트를 확장한 문법이라고 설명하겠습니다.

위에서 설명한 컴포넌트 작성 방법을 조금ㄷ ㅓ~~~ 깔끔하게 도와주는 문법입니다.

JSX 는 공식적인 자바스크립트 문법이 아니기 때문에 바벨(babel) 이라는 문법 변환 도구가 필요합니다.

이는 문서 맨 윗 단에 CDN 한 줄을 추가 해주시면 됩니다

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

JSX 문법 (스타일 관련은 그냥 거르세요 중요X)

xml 문법- 반드시 닫기 태그 와 함께 사용
        ex) <key>value</key>
        ex) <key/>--셀프클로징(자식노드에 값이없을때)
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

렌더링 할 요소는 최상위 엘리먼트 하나 만 있어야한다.
// const element = (<h1> Hello, {user.name} </h1> 
//                 <h3> Hello, {user.phone} </h3>); // 불가능

// 하나의 돔 트리로 만들면 가능
// const element = (
//     <div>
//         <h1> Hello, {user.name} </h1> 
//         <h3> Hello, {user.phone} </h3>
//     </div>    ); // 가능

// <React.Fragment>로 감싸서 형식상의 돔트리상 상위 엘리먼트를 만들어준다.
//     React 16 버전에서 추가 된 기능으로 별도의 노드를 추가하지않고 여러자식을 그룹화한다.
//     위의 div와 같이 불필요한 DOM node 생성을 막기 때문에 메모리를 적게 사용한다
// const element = (
//     <React.Fragment>
//          <h1> Hello, {user.name} </h1> 
//          <h3> Hello, {user.phone} </h3>
//     </React.Fragment>
// )

// React.Fragment 의 축약 문법 ( 그냥 아무것도 안써도 됨)
const element =(
    <>
        <h1> Hello, {user.name} </h1> 
        <h3> Hello, {user.phone} </h3>
    </>
);

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
속성값(Attribute) 적용방법

JSX는 html 태그처럼 보이지만 실제로는 자바스크립트이다. 
(React.createElement를 호출하는 코드로 컴파일된다.)
따라서 자바스크립트의 예약어와 동일한 이름의 attribute는 
다른 이름으로 우회적으로 사용하도록 정의되어 있다.

// const element = (
//     <div>
//         <h1> Hello, {user.name} </h1> 
//         <h3> Hello, {user.phone} </h3>
//     </div>    );
즉 작성은 이렇게 하지만 바벨로 변환하고 나면 실제 실행은 위에 봤던 엿같은 코드로 실행된다는 
이야기.

// 1. 문자열로 속성값 정리하는 방법
// const element = <h1 id="title" className="light"> Hello world~</h1>;

// 2. JavaScript 표현식 ({}) 을 이용하여 정의하는 방법
const id = "title";
const className = "light"

const element = <h1 id= {id} className = {className}> Hello world~</h1>;

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

컴포넌트에 스타일 적용하기 ( 내부 )
/* 스타일을 적용하기 위한 객체의 속성명은 카멜케이스로 작성해야 한다.
*  예) background-color -> backgroundColor 
*  속성값은 문자열 혹은 숫자 형태로 작성해야 한다.
* */
// 스타일 객체
const styleVal = {
    backgroundColor : 'black',
    color : 'white',
    cursor : 'pointer',
    textAlign : 'center',
    padding : 20
}

const element = (
    <>          // 객체 때려박기
        <h1 style = {styleVal}> Hello world</h1>
        <h3> inline styling test</h3>
    </>
);

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

이벤트 처리하기

// 1. 인라인으로 간단한 이벤트 적용 시 JSX의 자바 스크립트 표현식 내에 이벤트처리 함수 작성
// const element = (
//     <>
//         <h1> Event Attribute</h1>
//         <button onClick = {function(){alert('Hello world')}}> 클릭하세요</button>
//         <button onClick = {() => alert('Hello arrow world')}> 클릭하세요</button>
//     </>
// )

// 2. 이벤트 동작 시 사용할 핸들러 메소드를 사전 정의 후 JSX 내에 표현식으로 사용
const onClickHandler = () => {
alert('Hello');
}

const onClickHandler2 = function (){
alert('Hello2');
}

const element = (
<>
    <h1> Event Attribute</h1>
    <button onClick= {onClickHandler2}> 클릭하세요 핸들러 </button>
</>
)

// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
조건부 렌더링 ( if문 사용 불가 )
아직 정확한 조건은 모르겠지만 JSX 에서 IF 문 사용을 권장하지 않는것 같다.
어디에선 써지고 어디에선 안써진다...
그래서 이러한 방법으로 조건을 확인 할 수 있다.
1. 삼항연산자 (아니깐 패스)

2. && 문법
true만 확인 할 수 있는 조건문 이다. 
1 == 1 && <p> 트루입니다 !</p> 

3. 즉시발동함수  https://myhappyman.tistory.com/60
const word = 'react';
  return (
    <div>
    {
      (function(){
        if(word == 'react'){
          return ("리액트!")
        }else if(word == 'hello'){
          return ("헬로우!")
        }else if(word == 'world'){
          return ("월드!")
        }
      })()
    }
    </div>
  );

3.1 즉시발동함수 화살표함수
(()=>{
      if(word == 'react'){
        return ("리액트!")
			}
		})
 
 

JSX 문법으로 위에서 만든 컴포넌트랑 똑같은 컴포넌트를 만들어보겠습니다.

<script type = "text/babel">
	  const helloworld = <h1> hello world </h1>;
	
	  ReactDOM.render(helloworld, document.getElementById('root'));

</script>

helloworld 변수에 HTML 코드를 냅다 넣고있는데 오류가 없습니다.

컴포넌트 합성

const user = {
             name: '홍길동',
             age: 20,
             phone: '010-1234-5678',
             email: 'hong123@gmail.com'
         }
        
         function NameCard() {
            return <h1>{user.name}</h1>
         }
         function AgeCard() {
            return <h1>{user.age}</h1>
         }
         function PhoneCard() {
            return <h1>{user.phone}</h1>
         }
         function EmailCard() {
            return <h1>{user.email}</h1>
         }

         // 각각의 컴포넌트 들을 감싸는 컴포넌트
         function UserInfo() {
            return (<div style={{width:300 , border: '1px solid black'}}>
                <NameCard/>    
                <AgeCard/>    
                <PhoneCard/>    
                <EmailCard/>    
            </div>);            
         }
        

        ReactDOM.render(<UserInfo/>, document.getElementById('root'));

배우진 않았지만 State 혼자 정리

State (상태)는 컴포넌트가 갖고있는 속성값 입니다. 이 속성값이 변하면 리액트 엔진은 자동으로 UI를 업데이트 시켜줍니다.

state 실습예제를 하려면 import 가 필요한데 예제를 전부 html 에서 해서 ㅠㅠ

나중에 추가하겠습니다.

props

properties의 약어로, 컴포넌트의 속성을 설정할 때 사용하는 요소이다.

부모에게 받아온 데이터입니다.

리액트의 Data Flow는 단방향 형식으로 부모에서부터 자식으로 이동하기 때문에 거꾸로 올라갈 수 없습니다.

따라서 props에 있는 데이터들은 수정이 불가능하며 오직 안에있는 값을 꺼내서 사용할수만 있습니다.

 

>> 라고 처음엔 생각했지만 ? useState 의 기능으로 상태값 관리를 하게된다면 말이 달라질지도 ...

props 기본 렌더링

const name1 = '이대엽';
const name2 = 'dleoduq';

// 2. xxx 에 name1 을 전달해서 표현    매개변수에 props, state 라고 적어주는게 
// 규칙 이라는듯 !?

function Title2(props) {
    console.log(props);
    return <h1> 안녕하세요 {props.name} 님~! </h1>
}

ReactDOM.render(
    <Title2 name = {name1}/>, document.getElementById('root')
);

자바스크립트로 선언된 변수를 JSX 에서 쓰고싶다면,

{ 변수이름 } 중괄호를 씌워주면 된다.

자식노드 렌더링

자식 노드를 전달하는 props.children 리액트 컴포넌트를 사용할 때 태그 사이의 내용을 props의 children 속성에서 관리한다.

function ChildNodePrinter(props) {
    console.log(props);
    return (
        <>
        <h1>자식노드가 가지고 있는 값은</h1>
        <h3>Children : <font style={{color : 'orange'}}>{props.children}</font> </h3>
        </>
    )
}

ReactDOM.render(
[
    <ChildNodePrinter>텍스트노드</ChildNodePrinter>,
    <ChildNodePrinter><div>자식노드</div></ChildNodePrinter>,
    <ChildNodePrinter><div>1</div><div>2</div><div>3</div></ChildNodePrinter>

],
document.getElementById('root')
)

결과 >>

 

props 구조분해할당 https://youtu.be/lV7ulA7R5Nk?t=178

구조분해할당 : 배열이나 객체의 속성을 구분해서 그 값을 변수에 담을 수 있게 하는 표현식

중괄호로 감싼 변수로 제시한 속성 {name, children} 에

props 객체의 속성과 이름이 일치하면, 그 값을 부여하는 기능입니다.

 

const {name, children} = props; 는 아래와 같다
        const name = props.name;
        const children = props.children;

 

리액트를 이래저래 다루다 보니 알게모르게 배열 구조분해할당, 객체 구조분해할당을 굉장히 많이 사용하고 있길래

제 생각엔 절대 모르면 안될 내용일 것 같습니다.

 

// 전달 받는 인자를 바로 비구조화 할당
function PropsPrinter(props) {
    // 비구조화 할당을 하게 되면 공통적으로 사용하는 props.을 생략하고 사용할 수 있다.
    console.log(props);  // {name: 'dleoduq', children: '문자열자식'}  객체 타입이다
    const {name, children} = props;
    /*
    	const {name, children} = props; 는 아래와 같다
        const name = props.name;
        const children = props.children;
    */

    return (
        <>
            <h1>제이름은 {name} 입니다</h1>
            <h3>제가 가지고있는 자식은 {children} 입니다</h3>
        </>
    )
}

ReactDOM.render(<PropsPrinter name = "dleoduq" children = "문자열자식"/>
, document.getElementById('root'));

props 에 전달되는 타입 검증

근데 콘솔에서만 오류를 알려주던데 어떻게 사용하는걸까 ?? - 고민해결되면 수정할 것 ( 아니 수정안할거< <이게 수정임)

propTypes 를 이용하기 위해 CDN 추가
function PropsVerify({name, favoriteNumber, children}) {
    return (
        <>
            <h1>제이름은 {name}</h1>
            <h1>제가 가잫 좋아하는 숫자는 {favoriteNumber}</h1>
            <h1>제가 가지고있는 children은 {children}</h1>
        </>

    )
}
// 문법
PropsVerify.propTypes = {
    name : PropTypes.string,         // 문자열인지 검증
    favoriteNumber : PropTypes.number.isRequired   // 숫자형인지 검증, 값을 입력했는지 검증

}

ReactDOM.render(
    [
        <PropsVerify name="이대엽" favoriteNumber={5}>텍스트노드</PropsVerify>,
        <PropsVerify name="이대엽" favoriteNumber={5}>자식 텍스트노드</PropsVerify>,
        /*중괄호 씌우면 숫자*/
        <PropsVerify name={3}  favoriteNumber={5}>자식 텍스트노드</PropsVerify>,  // name string 무시
        <PropsVerify name="이대엽3" >자식 텍스트노드</PropsVerify>   // isRequired 무시
    ]
    , document.getElementById('root'));

Window 객체

자바스크립트의

최상위 객체,

전역 객체,

모든 객체가 소속된 객체

이다. (가장 큰형님) 자바로 치면 Object 쯤 되는 객체 되시겠다.

우리가 곧 공부 할 내용인

DOM , BOM , JavaScript(CORE) 도 모두 window 를 형님으로 모시고 있다.

DOM (Document Object Model , 문서 객체 모델)

‘객제지향모델’ 로써 구조화된 문서를 표현하는 형식이다.

(완전 내 마이웨이 대로 설명하면, 디자인 패턴 같은 하나의 형식 이라는 이야기 같다.)

텍스트 파일로 이루어진 웹 문서를 브라우저에 렌더링 하려면 웹 문서를 브라우저가 이해할 수 있는 구조로 메모리에 올려야 한다.

여기서 브라우저가 웹 문서를 쉽게 이해할 수 있도록 구성된 형태를 DOM 이라고 하는 것이다.

모든 요소들 과의 관계를 부자 관계로 표현할 수 있는 트리 구조이다.

주로 만나게되는 노드 4가지

문서 노드(Document Node)

트리의 최상위에 존재하며 각각의 하위 요소들(Element, Attributes, Text)에 접근하려면 이 노드를 거쳐야한다. 예시(document.getElement ~

요소 노드(Element Node)

쉽게 말하자면 태그 이름이다. <div> 의 요소는 div 이고, <img>의 요소는 img …

(심화)  아직은 이해가 안되지만 일단 적어둠

JS DOM 에서 Node 는 node의 constructor 이고, HTMLElement는 element의 constructor이다.

paragraph는 node이자 동시에 element이다.

어트리뷰트 노드 (속성 노드, Attribute Node)

<input> 태그 안에는 name, value 등의 속성을 사용할 수 있는데 이러한 속성(Attribute) 들을 가리키는 노드이다.

텍스트 노드 (Text Node)

태그 내 텍스트를 가리킨다. 텍스트 노드는 요소 노드(Element Node)의 자식이며

자신은 자식 노드를 가질 수 없기 때문에 DOM 트리의 최종단 이다.

<p> 텍스트!!! </p> 에서 ‘텍스트!!!’ 가 바로 텍스트 노드이다.

1. DOM 노드 취득(접근)

HTMLCollection과 NodeList

  • HTMLCollection과 NodeList는 DOM API가 여러 개의 결과 값을 반환하기 위한 DOM 컬렉션 객체이다.
  • HTMLCollection과 NodeList는 모두 유사 배열 객체면서 이터러블이다.
  • 따라서 for...of 문으로 순회할 수 있으며 배열로 변환할 수 있다.

HTMLCollection

  • getElementsByTagName, getElementsByClassName 메서드가 반환하는 객체이다.
  • 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는(live) DOM 컬렉션 객체이다.
  • HTMLCollection 객체는 실시간으로 노드 객체의 상태 변경을 반영하여 요소를 제거할 수 있기 때문에 for문으로 순회하면서 노드 객체의 상태를 변경하는 경우 주의해야 한다.
    • 반복문 역방향 순회 혹은 while문 사용 등을 통해 회피할 수 있다.
    • 하지만 HTMLCollection 객체를 사용하지 않고 배열로 변환하는 것이 권장 된다.

NodeList

  • querySelectorAll 메서드가 반환하는 객체이다.
  • 실시간으로 노드 객체의 상태를 변경하지 않기(non-live) 때문에 HTMLCollection의 부작용을 해결할 수 있다.
  • NodeList 객체는 NodeList.prototype.forEach 메서드를 상속 받아 사용할 수 있다.
  • NodeList.prototype은 forEach 외에도 item, entries, keys, values 메서드를 제공한다.
  • 대부분의 NodeList는 non-live 객체로 동작하지만 childNodes 프로퍼티가 반환하는 NodeList 객체는 HTMLCollection 객체와 같이 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작하므로 주의가 필요하다.

노드 객체의 상태 변경과 상관 없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것을 권장한다. 각각의 객체가 메서드를 제공하지는 하지만 배열의 고차 함수만큼 다양한 기능을 제공하지 않는다. 두 객체 모두 유사 배열 객체이면서 이터러블이므로 스프레드 문법이나 Array.from 메서드를 사용하여 간단하게 배열로 변환할 수 있다

배열로 변환하여 사용하는 것을 권장한다!!!!!!

굿.

2. DOM 노드 탐색

요소를 취득한 다음, 취득한 요소를 기점으로 DOM 트리의 노드를 옮겨다니며 부모, 형제, 자식 노드 등을 탐색(traversinig)해야 할 때가 있다.

DOM 트리 상의 노드를 탐색할 수 있도록 Node, Element 인터페이스는 트리 탐색 프로퍼티를 제공한다. ( 기능이 스레기 같아서 안쓰지만 )

노드 탐색 프로퍼티는 모두 참조만 가능한 읽기 전용 접근자 프로퍼티이다. 읽기 전용 접근자 프로퍼티에 값을 할당하면 아무런 에러 없이 무시된다.

child(자식) , parent(부모) , sibling(형제)

3. DOM 노드 수정

innerHTML

  • setter와 getter 모두 존재하는 접근자 프로퍼티로 요소 노드의 HTML 마크업을 취득하거나 변경한다.
  • textContent 프로퍼티는 HTML 마크업을 무시하고 텍스트만 반환하지만 innerHTML 프로퍼티는 HTML 마크업이 포함 된 문자열을 그대로 반환한다.

insertAdjacentHTML

  • Element.prototype.insertAdjacentHTML(position, DOMString) 메서드는 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입한다.
  • 첫번째 인수로 전달할 수 있는 문자열은 'beforebegin', 'afterbegin', 'beforeend', 'afterend'의 4가지이다.
  • insertAdjacentHTML 메서드는 기존 요소에 영향을 주지 않고 새롭게 삽입될 요소만을 파싱하여 자식 요소로 추가하므로 기존의 자식 노드를 모드 제거하고 다시 처음부터 새롭게 자식 노드를 생성하여 자식 요소로 추가하는 innerHTML 프로퍼티보다 효율적이고 빠르다. 단, HTML 마크업 문자열을 파싱하므로 크로스 사이트 스크립팅 공격에 취약하다는 점은 동일함

4. 노드 이동 교체 삭제

node insert move

node copy replace remove

요소 사이에 값을 넣고 싶을 때 !!!!!!!!!!!!!!!!!!!! 바로 그때가 되면 !!!!!!!!!!! 찾아보세요 .

5. 어트리뷰트 (속성)

attributes , getAttribute , setAttribute , hasAttribute , removeAttribute

6. 스타일

className ( 반환 문자열 ) , classList ( 반환 DOMTokenList ?? )

classList 메소드

add , item ( 0 ) , contains ,
replace(old , new) , toggle , remove

BOM (Browser Object Model, 브라우저 객체 모델)

BOM은 자바스크립트가 브라우저와 소통하기 위해서 만들어진 모델이다.

공식 표준은 아니지만 브라우저 대부분이 자바스크립트와의 상호작용에 있어서 비슷한 메소드와 속성으로 동작하기에 이와 같은 메소드들을 통칭하여 BOM 이라고 한다. Window객체를 통해 접근이 가능하다.

바로 F12 를 열어서 콘솔에 해당 메소드를 실행시켜 보면 엄청나게 많은 프로퍼티들을 볼 수 있다,

navigator , location , history , screen

EVENT ( 이벤트 )

표준 이벤트 모델

w3 에서 공식적으로 지정한 이벤트 모델. 한번에 여러개의 이벤트 핸들러 설정가능 IE 는 9버전부터 지원

[참고] HTML DOM 이벤트 종류

https://www.w3schools.com/jsref/dom_obj_event.asp

addEventListener ( type , listener() , option ) 인자 설명

type : 언제 (작동 원인) = 위에 있는 문서에 들어가면 종류가 정리되어있다.

자주 사용되는 type들

이벤트 명설명
change : 변동이 있을 때 발생

click : 클릭 시 발생

focus : 포커스를 얻었을 때 발생

keydown : 키를 눌렀을 때 발생

keyup : 키에서 손을 땟을 때 발생

load : 로드가 완료 되었을 때 발생

mousedown : 마우스를 클릭 했을 때 발생

mouseout : 마우스가 특정 객체 밖으로 나갔을 때 발생

mouseover : 마우스가 특정 객체 위로 올려졌을 때 발생

mousemove : 마우스가 움직였을 때 발생

mouseup : 마우스에서 손을 땟을 때 발생

select : option 태그 등에서 선택을 햇을 때 발생

출처:

https://chlolisher.tistory.com/10

[클로리셔 작은 공간:티스토리]

listner() : 무엇을 (취할 행동) = 호출할 함수

addEventListener ( type , listener() , option )

option 프로퍼티

option {
( capture 설명은 좀 자신이 없네요 false 와 useCapture 가 엄밀히 말하면 다른거같은데 
그냥 놓고 보면 똑같거든요)

capture : 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에,
 이 수신기가 먼저 발동돼야 함을 나타내는 불리언 값입니다. 
명시하지 않을 경우 기본 값은 false(useCapture)입니다. ( 본인부터 실행되고 부모를 실행함)
true  :   ( 최상위 부터 실행되고 자식을 실행함)

once : 수신기가 최대 한 번만 동작해야 함을 나타내는 불리언 값입니다. true를 지정할 경우, 
수신기가 발동한 후에 스스로를 대상에서 제거합니다. 명시하지 않을 경우 기본 값은 false입니다.

passive : true일 경우, 이 수신기 내에서 preventDefault()를 절대 호출하지 않을 것임을 
나타내는 불리언 값입니다.

}

preventDefault() 예제 문서

사용자의 행동을 방지하게 해주는 메소드이다.

https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault

 

이벤트가 발생한 해당 요소 객체에 접근하는 방법

+자바스크립트 this 가 무엇을 가리키는지…

<button id = "btn4">고전이벤트방식</button>
    <button onclick="test6();">인라인이벤트방식</button>
    <button id = "btn5">표준이벤트방식</button>

    <script>
        // 고전이벤트 방식 
        var btn4 = document.getElementById("btn4");
      
        btn4.onclick = function(e){//e 매개변수  : 발생한 이벤트 객체
            //MouseEvent객체
            console.log(e);           // PointerEvent 객체 정보
            console.log(window.event);  // PointerEvent 객체 정보

            //현재 이벤트가 발생한 요소에 대한 정보를 가져오고자 한다면 세가지 방법
            console.log(e.target);     // Element 요소 정보   (객체)
            console.log(window.event.target);    // Element 요소 정보   (객체)
            console.log(this);       // Element 요소 정보 (객체)

            e.target.style.color = "white";
            this.style.backgroundColor="red";
        }

        //인라인방식 -- 위 버튼에서 인라인으로 호출
        function test6(e){
            console.log(e);//매개변수로 이벤트 객체아는것은  불가능   undefined
            console.log(window.event.target); //정상    Element 요소 정보 (객체)
            console.log(this);// window 객체를 가리킴 (이벤트 객체를 아는 것은 불가능 )
        }

        //표준이벤트 방식 
        var btn5 = document.getElementById("btn5");
        btn5.addEventListener('click', function(e){
            console.log(e.target);     // Element 요소 정보 (객체)
            console.log(window.event.target);   // Element 요소 정보 (객체)
            console.log(this);   // Element 요소 정보 (객체)
        });

input type = submit 에게 이벤트를 만들어주면

이벤트를 우선 실행. return이 true 이면 그 다음 submit 실행. false 이면 submit 실행 안함

 

1. 클래스

클래스 , 익명클래스 , 기명클래스, 동적생성 클래스

생성 방법에 따라 이름을 나눠보았습니다

클래스

class Student{
    constructor(name){

        // 생성자는 1개이상 정의 될 수 없고 생략할 경우 암묵적으로 정의, 
        this.group = 1;
        this.name = name
        // 암묵적으로 this 반환 중
    }

    // 메소드
    introduce(){
        console.log(`저는 ${this.group}반 학생 ${this.name} 입니다!`);
    }
    // 암묵적으로 this 반환 하는 중 
    
}
//  결과 

console.log(new Student());            // constructor 실행 ,  Student { group: 1, name: undefined }
console.log(typeof Student);         // function
console.log(Student === Student.prototype.constructor);        // true
console.log(Student.prototype.introduce); // 클래스 내부에 정의한 메소드는 클래스, prototype에 저장 ,Array.prototype 처럼

익명클래스

// 1. 익명클래스 표현식     클래스 이름이 없으니까 생성자선언 + 바로사용 하는 용도 ??  (일회용)
let Tutor = class {
    teach(){
        console.log(`이해되시나요`);
    }
}
console.log('여기');
console.log(Tutor);       //  [class Tutor]
console.log(new Tutor());   //    Tutor {}
new Tutor().teach();    //   이해되시나요

기명클래스

// 2. 기명클래스 표현식
let Tutee = class MyTutee {
    learn(){
        console.log('이해 했습니다');
        console.log(MyTutee);   
    }
}

// console.log(MyTutee);      // 클래스 밖에서 사용불가
new Tutee().learn();     
//   이해 했습니다
//  [class MyTutee]

동적 생성 클래스

// 3. 클래스 동적 생성
function makeTutee(message) {  
    return class {
        feedback(){
            console.log(message);
        }
    }
    
}

let secondTutee = makeTutee("10점 맍점");
new secondTutee().feedback();       // 10점 맍점

get set

class Product{

    constructor(name, price){
        this.name = name;
        this.price = price;
    }

    get name(){
        console.log('get name동작');
        return this._name;   
        // 언더바를 붙이지 않으니 무한루프에 빠져버린다 .. 
        // this.name (언더바없음) 을 호출 할때 get (같은이름)의 함수가 호출된다고 한다. (작동원리)
        // 그래서 프로퍼티 이름을 일부러 다르게 써서 무한루프 방지를 한다.

    }

    get price(){
        console.log('get price동작');
        return this._price;  
    }

    set name(value){
        console.log('set name동작');
        this._name = value;  
    }
    set price(value){
        console.log('set price동작');
        if(value < 0){
            console.log('가격은 음수가 아닙니다');
            this._price = 0;
            return;
        }
        this._price = value;  
    }

}

// get은 프로퍼티를 읽으려 할 때   set은 프로퍼티에 값을 할당하려 할 때  자동으로 실행 됨

let phone = new Product('전화기', 23000);         // set 동작    음수처리 기능이 있다 !!!
console.log(phone.name + ',' + phone.price);           // get 동작

// 결과
set name동작
set price동작
get name동작
get price동작
전화기,23000

클래스 상속

class Animal{
    constructor(name, weight){
        this.name = name;
        this.weight = weight;
    }

    eat(foodWeight){
        this.weight = this.weight + foodWeight;
        console.log(`${this.name}(은)는 ${foodWeight}kg의 식사를 하고 ${this.weight}kg이 되었습니다.`);
    }

    move(lostWeight){
        if(this.weight > lostWeight)
        this.weight = this.weight - lostWeight;
        console.log(`${this.name}(은)는 움직임으로 인해 ${lostWeight}kg 감량되어 ${this.weight}kg이 되었습니다.`)
    }
}

let animal = new Animal('동물', 30);

animal.eat(1);   //  동물(은)는 1kg의 식사를 하고 31kg이 되었습니다.
animal.move(0.5);  //   동물(은)는 움직임으로 인해 0.5kg 감량되어 30.5kg이 되었습니다.

class Human extends Animal{

    develop(language){
        console.log(`${this.name}(은)는 ${language}로 개발을 합니다. 정말 즐겁습니다^.^`);
    }
}

let human = new Human('수강생', 70);

human.eat(2);    //   수강생(은)는 2kg의 식사를 하고 72kg이 되었습니다.
human.move(1);     //    수강생(은)는 움직임으로 인해 1kg 감량되어 71kg이 되었습니다.

human.develop('javascript') 
//    수강생(은)는 javascript로 개발을 합니다. 정말 즐겁습니다^.^

class Tiger extends Animal{
    attack(target){
        console.log(`${this.name}은 ${target}을 공격합니다`);
    }

    move(target){
        super.move(0.1);  // 부모 move 실행 
        this.attack(target);   // Tiger 만의 기능
    }
}

let tiger = new Tiger("호랭이", 90);
tiger.move('사슴');    
//   호랭이(은)는 움직임으로 인해 0.1kg 감량되어 89.9kg이 되었습니다.
//   호랭이은 사슴을 공격합니다

class Deer extends Animal{
    constructor(name, weight, leglength){
        super(name, weight); // 부모 생성자, 반드시 this 호출 전에 super 사용
        this.leglength = leglength;
    }

    hide(place){
        console.log(`${this.name} 은 ${place}에 숨습니다`);
    }
}

let deer = new Deer('사슴2', 100, 15);
deer.hide('나무밑');   //   사슴2 은 나무밑에 숨습니다

2. 화살표 함수 ( 보기 어려워 죽겠다 )

함수의 형식을 파괴해버리고

매개변수와 반환값만 적어주는 엄청 축약된 형태의 함수 입니다

(매개변수) ⇒ ( { 반환값 } ) ;

기본 구문 (MDN 문서 내용 중)

`(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// 다음과 동일함:  => { return expression; }

// 매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요:
() => { statements }`
// 객체 리터럴을 반환하는 경우 소괄호로 감싸주는것이 좋다.    
const createUser = (id, name) => ({id, name});
console.log(createUser(1,'이효리'));
//   { id: 1, name: '이효리' }

// 고차함수에 인수로 전달 가능하고 일반 함수 표현식 보다 간결하여 자주 사용
// map : 배열 요소 전체를 대상으로 콜백 함수 호출후 반환값들로 구성된 새로운 배열 반환
console.log([1,2,3,4,5].map(val => val * 10));
//   [ 10, 20, 30, 40, 50 ]    map 은 배열순회 함수

// 화살표 함수는 this를 가지지 않는다!!!!
// 객체 리터럴 (대문자가 아니니 생성자는 아님)
let theater = {
    store : '건대점',
    titles : ['어벤져스', '겨울왕국', '스파이더맨', '라이언킹', '알라딘'],

    // this는 자신의 상위를 뜻한다 ??
    // 외부에서 값을 가져온다 ?? 상위타입을 가져온다 ??

    // 일반함수에서의 this 는 전역(global) 을 가리킨다 ??

    // forEach : 배열 순회 함수
    showMovieList(){
        this.titles.forEach(
            title => console.log(this.store + ' : ' + title)
        );
    }
}

theater.showMovieList();
//  건대점 : 어벤져스
//  건대점 : 겨울왕국
//  건대점 : 스파이더맨
//  건대점 : 라이언킹
//  건대점 : 알라딘

// 화살표 함수는 new와 함께 호출할 수 없다

const arrowFunc = () => {};
// new arrowFunc();           //TypeError: arrowFunc is not a constructor
console.log(arrowFunc.hasOwnProperty('prototype')); //  false
console.log(arrowFunc.constructor);     // [Function: Function]

// 화살표 함수는 arguments 지원하지 않음    화살표함수 너무 보기힘드네요 무슨뜻일까요 이게
(function(){
    const arrowFunc = () => console.log(arguments);

    arrowFunc(3,4)
}(1,3));
//    [Arguments] { '0': 1, '1': 3 }

// 1,3 지우니까 출력이 안됨

MDN 문서 내용 중

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

`function foo(n) { var f = (...args) => args[0] + n; return f(2); }

foo(1); // 3`

이전 예제를 '나머지 매개변수' 라는 좋은 대안으로 고친 코드

// 화살표 함수는 arguments 지원하지 않음    화살표함수 너무 보기힘드네요 무슨뜻일까요 이게
(function(){
    // const arrowFunc = () => console.log(arguments);
    const arrowFunc = (...args) => console.log(args);

    arrowFunc(3,4)   // 함수 실행을 하는 문장이긴한데 (위에 문장으로 실행하면) 매개변수 무시되고 있는듯
}(1,3));

// [ 3 , 4 ]

3. 심볼 (Symbol) 중요도 하

MDN 문서 내용 중

"심볼" 데이터 형식은 값으로 익명의 객체 속성(object property)을 만들 수 있는 특성을 가진 원시 데이터 형식(primitive data type)입니다

심볼  데이터 형식은 고도로 특화된 용도로 쓰이며, 범용성은 현저히 떨어집니다. 심볼 의 인스턴스에 L값(L-value)을 할당할 수 있고 식별자로 이용할 수 있습니다. 그게 전부입니다. 적용할 수 있는 연산자도 없습니다.

대놓고 쓰지 말라고 적어 놓은 듯한 데요. 허허허허허

중요하지 않은것 같으니 패스

//Symbol << 외부코드에서 접근 불가능 , 값도 덮어쓸 수 없는 숨김 프로퍼티를 만들 수 있다.

let student = {
    name : '홍길동'
}

let id = Symbol('id');
student[id] = 500; 

// student  [key] = value   로 프로퍼티 추가하는 문법
let name = 'name';
student[name] = '이대엽';

console.log(Object.keys(student));
console.log(student[id]);
console.log(student);

let student2 = {
    name : '홍길동',
    age : 15,
    [id] : 2 // 객체 리터럴 안에서 사용할 경우 대괄호를 사용해 심볼형 키를 만들 수 있다.
}

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
// 프로퍼티 이름 출력하는 반복문
for(let key in student2) console.log(key); // for in 반복문에서 키가 심볼인 경우 배제된다.
console.log(student2[id]);

console.log(Object.getOwnPropertySymbols(student));
console.log(Object.getOwnPropertySymbols(student2));

// 심볼은 유일무이하다 !!
let symbol1 = Symbol('mySymbol');
let symbol2 = Symbol('mySymbol');

console.log(symbol1 === symbol2);   // false

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);

// Symbol.for(key) 를 사용해 심볼을 전역 레지스트리에 만들고 읽는다. 
// 그래서 동일한 이름으로 존재하지 않으면 새로운 심볼을 만들고, 이름이 있다면 심볼을 다시 읽어온다

// 음 그래서 심볼의 용도가 무엇일까 ?????????   >>     나중에 찾아보기
let symbol = Symbol.for('id1');
let id1 = Symbol.for('id1');
console.log(symbol === id1);  // true

// 이름이 같더라도 값이 항상 다르므로 이름이 같을때 값도 같기를 원한다면 전역 레지스트리에 생성해서 사용해야함

4. 이터레이터 , 이터러블

/* 01_iterable (이터러블)
ES6 이전의 순회 가능한 데이터 컬렉션, 배열, 문자열, 유사 배열 객체, DOM 컬렉션 등은 
통일 된 규약 없이 for문, for...in문, forEach 메서드 등 다양한 방법으로 순회 할 수 있었다.

ES6에서는 순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하여 
for...of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용할 수 있도록 일원화했다.
*/  // 이터레이션 프로토콜

let range = {
    from : 1,
    to : 5
};

range[Symbol.iterator] = function () {
    return {
        current : this.from,
        last : this.to,

        // done : Iterator(반복자)가 마지막 반복 작업을 마쳤을 경우 true
        // value : Iterator(반복자)으로부터 반환되는 모든 자바스크립트 값
        next(){ // 인덱스마다 호출되는 함수
            if (this.current <= this.last){
                return {done : false , value : this.current++};     
            } else{
                return {done : true};
            }
        }
    }
}

// TypeError: range is not iterable
for(let num of range){
    console.log(num);
}

// 유사 배열 객체
let arrayLike = {
    0: '배열같은',
    1: '배열아닌',
    2: '배열이다',
    length : 3
}

// 배열 메서드 사용 불가
console.log(arrayLike);   
// { '0': '배열같은', '1': '배열아닌', '2': '배열이다', length: 3 }

console.log(typeof arrayLike);
//  object

// console.log(arrayLike.pop());

// 메서드는 유사 배열 객체(array-like object)나 
// 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.
let arr = Array.from(arrayLike);
console.log(arr.pop());
// 배열이다

let arr2 = Array.from(range);
console.log(arr2);
//  [ 1, 2, 3, 4, 5 ]

// from 설명
// (iterable: Iterable<any> | ArrayLike<any>   ,     mapfn: (v: any, k: number) => any, thisArg?: any)
          // 이터러블 | 유사배열 ,  매개변수 => 리턴값                 화살표좀 작작써라!!!!!!!!!!   
let arr3 = Array.from(range, num => num * num);
console.log(arr3);
//  [ 1, 4, 9, 16, 25 ]

5. 스프레드 문법 ( 나머지 매개변수 ) [ …args]

// 스프레드 문법, 전개 문법

// max 안에는 숫자들만 들어갈 수 있다.
console.log(`가장 큰 값 : ${Math.max(10,20,30)}`); // 가장 큰 값 : 30

// max 안에는 배열은 들어갈 수 없다.
let arr = [10, 20, 30];
console.log(`가장 큰 값 : ${Math.max(arr)}`);   가장 큰 값 : NaN

// Spread!!!!!!!!!!!!!!!!!!!
console.log(`가장 큰 값 : ${Math.max(...arr)}`);  // 가장 큰 값 : 30

let arr1 = [10, 20, 30];
let arr2 = [100, 200, 300];

console.log(`가장 큰 값 : ${Math.max(...arr1, ...arr2)}`);    // 가장 큰 값 : 300
console.log(`가장 큰 값 : ${Math.max(...arr1, ...arr2, 500000)}`);
//  가장 큰 값 : 500000

let merged = [0, ...arr, 2, arr2]  //  (일부러 이상하게 합침)
console.log(merged);   //   [ 0, 10, 20, 30, 2, [ 100, 200, 300 ] ]

let str = "JavaScript";
console.log([...str]);
/**
[
  'J', 'a', 'v', 'a',
  'S', 'c', 'r', 'i',
  'p', 't'
]
*/

console.log(Array.from(str));
/**
[
  'J', 'a', 'v', 'a',
  'S', 'c', 'r', 'i',
  'p', 't'
]
*/

구조 분해 distructuring-assignment

MDN 문서 내용 중

구조 분해 할당  구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

 

배열 구조 분해

// 배열 구조 분해 할당

let nameArr = ['길동', '홍'];

// let firstName = nameArr[0]
// let lastName = nameArr[1]

let [firstName, lastName] = nameArr;

console.log(firstName);   // 길동
console.log(lastName);    //  홍

let [firstName2, lastName2] = '길 동'.split(' ');

console.log(firstName2);    //길
console.log(lastName2);     //동

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');
// 쉼표를 사용해서 필요하지 않은 배열요소는 버릴 수 있다
let [firstName3,      ,lastName3] = ['firstName', 'middleName', 'lastName'];
console.log(firstName3);        //firstName
console.log(lastName3);         //lastName

// 대입 연산자를 기준으로 우측에는 모든 이터러블 가능, 좌측에는 객체 프로퍼티도 가능
let user = {};
[user.firstName, user.lastName] = '길동 홍'.split(' ');

console.log(user.firstName);        //    길동
console.log('ㅡㅡㅡㅡㅡㅡㅡㅡkey valㅡㅡㅡㅡㅡㅡㅡㅡ');

//   entries  : Returns an array of key/values of the enumerable properties of an object
for(let [key,value] of Object.entries(user)){
    console.log(`${key} : ${value}`);
}
//    firstName : 길동
//    lastName : 홍

let student = '유관순';
let teacher = '홍길동';

[student, teacher] = [teacher, student];

console.log(`stu : ${student} ,tea : ${teacher}`);
//  stu : 홍길동 ,tea : 유관순

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡrestㅡㅡㅡㅡㅡㅡㅡㅡ');

let [sign1, sign2, ...rest] = ['양자리', '황소자리', '쌍둥이자리', '개자리',]
console.log(sign1);   //  양자리
console.log(sign2);    //    황소자리
console.log(rest);     //   [ '쌍둥이자리', '개자리' ]

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

let [firstName4 ='아무개', lastName4 = '김'] = ['길동'];
console.log(firstName4);    // 길동
console.log(lastName4);     //    김   (기본값으로 할당)

 

객체 구조 분해

// 객체 구조분해 할당

let pants = {
    productName : '팬츠',
    color : '검정색',
    price : 30000
}


let {productName, color, price} = pants;

console.log(productName);
console.log(color);
console.log(price);
/*
팬츠
검정색
30000
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');
let { color : co, price : pr, productName : pn } = pants;

console.log(co);
console.log(pr);
console.log(pn);
/*
검정색
30000
팬츠
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

let shirts = {
    productName : '베이직 셔츠'
}

// 초기값 할당 가능
let { productName : productName2 = '어떤상품', color : color2 = '어떤색상' , price : price2 = 0} = shirts;

console.log(productName2);
console.log(color2);
console.log(price2);

/*
베이직 셔츠
어떤색상
0
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

// pants 로 초기화 ????
let {productName : productName3} = pants;
console.log(productName3);   // 팬츠


let {productName : productName4, ...r} = pants;
console.log(productName4);
console.log(r.color);
console.log(r.price);

/*
팬츠
검정색
30000
*/

// 프로퍼티 값에 직접 그냥 할당하고 있음, 기본값도 할당하고
let productName5, color5, price5;
({productName : productName5 , color : color5 , price : price5 = 0} = pants);
console.log(productName5);
console.log(color5);
console.log(price5);

/*
팬츠
검정색
30000   (pants 에 30000이 있으니까 기본값 할당x )
*/


console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
// 중첩 구조 분해

let product = {
    size : {
        width : 10,
        height : 30
    },
    items : ['doll', 'robot']
};

let {
    size : {
        width,
        height
    },
    items : [item1, item2]          
} = product;   //  할당


// console.log(product.size.height);


console.log(width);
console.log(height);
console.log(item1);
console.log(item2);
/*
10
30
doll
robot
*/

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
let {
    size , 
    items 
} = product;   // 할당

console.log(size.width);   // 10



// 함수의 매개변수에 적용
// 함수의 매개변수가 많거나 기본 값이 필요한 경우 활용, 순서도 고정되지 않아도 됨
// 구조분해 = 중괄호  {} 로 감싸주기가 중요
function displayProduct({producer = '아무개', width =0, height=0, items = []}) { 
    console.log(`${producer}, ${width}, ${height}`);
    console.log(items);
} ;
console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡ조금 이상하게ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
displayProduct({width:'이대엽',producer: undefined, undefined, items:['Coffee', 'Donut']});
//  순서를 안맞게 해도 프로퍼티 값에 맞게 잘 들어가고있다.
//   아무개, 이대엽, 0
//    [ 'Coffee', 'Donut' ]


console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);  
// 객체 하나 임의로 생성
// 매개변수 순서가 맞지않아도 됨
let exProduct = {
    items : ['이효리', '도넛'],
    producer : '커피'
}

displayProduct(exProduct);
//  커피, 0, 0
//   [ '이효리', '도넛' ]

 

목차

상속

proto , prototype

배열

push , pop , indexof , lastindexof, includes , shift , unshift

slice , splice , reverse

배열 고차함수

sort, map , foreach , filter , concat , reduce , some , every

생성자함수 / 일반함수

//Object 생성자함수

const student = new Object();         // 빈 객체 생성

student.name = '이대엽';              // 프로퍼티 추가
student.age = 27;

console.log(student);
//결과
{ name: '이대엽', age: 27 }
// 생성자 함수 (리터럴 ?? ㅁㄹ)

const student1 = {            // 프로퍼티 값을 하나하나... 
    name : '이이대엽',
    age : 28,
    getInfo : function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}

const student2 = {            // 프로퍼티 값을 하나하나... (리터럴 단점)
    name : '22대엽',
    age : 22,
    getInfo : function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}

‘리터럴’ 은 변수에 할당하는 고정 형태의 값입니다.

int a 우항에 놓이는 1 int a = 1; var empty_object 우항에 놓이는 {} **var** empty_object = {} //빈 객체  와 같이 표기한 문자가 있는 그대로 자신을 나타내는 값이죠.

이것이 진짜 생성자 함수

// 리턴을 명시하지 않아도된다. 기본으로 빈 객체가 반환 된다 (고민? 좀 해볼만할지도)
// new 를 사용해서 함수를 호출했을때 이야기이다 !!!!!!!!!!! (암묵적인 return이 있다. )
// 일반함수처럼 사용하면 눈에 보이는대로 return이 없다.
// ( 첫글자를 대문자로 작성해야함. 작성자가 스스로 지켜야하는 컨벤션)
function Sstudent(name, age) {
    this.name = name;
    this.age = age;
    this.getInfo = function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}
const sstudent = Sstudent('유재', 30);
// const sstudent = new Sstudent('유재', 30);
console.log(sstudent);

// 결과 
undefined
// 해석
new Sstudent(~~ ) 가 아닌 일반함수처럼 Sstudent(~~) 를 호출 했기 때문에
return 된게 아무것도 없기 때문이다.

target - new 연산자 없이 호출되는것을 방지하기 위해 지원하는 함수

function Dog(name, age) {
    // 일단 타겟이 뭐하는 넘인가?
    // new 연산자 없이 호출되는것을 방지하기 위해 지원하는 함수 (new.target)
    // 내부는 undefined 이다
    console.log(new.target);        // [Function: Dog]
    
    // 생성자목적으로 만들경우
    if(!new.target){
        return new Dog(name, age);
    }

    this.name = name;
    this.age = age;
}

const dog = Dog('ㅃㅃ', 3);
console.log(dog);

// 결과
[Function: Dog]
Dog { name: 'ㅃㅃ', age: 3 }

개발자의 실수를 방지하기 위해(?) 만들어진 함수라고 생각중 입니다

상속!!!!!!!!!!! (한 번도 써본적은 없음 )

const user = {
    activate : true,
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true
};

student.__proto__ = user;

console.log(student.activate);// 프로퍼티 activate를 student에서도 사용 가능
student.login();// 메소드 login도 student를 통해 호출 가능console.log(student.passion);

  • 'student의 프로토타입은 user이다.' 혹은 'student는 user를 상속 받는다.' 라고 한다.
  • 프로토타입에서 상속받은 프로퍼티를 상속 프로퍼티(inherited property)라고 한다.

내용이 너무 심오하다 …

그냥 아무 연관이 없는 객체 두 개를 만들고 뜬금없이 프로퍼티를 호출 하면 상속이 된다고하니 ..

아무 연관이 없는게 아니었다
__proto__ 라는 프로퍼티(key) 값에 user 라는 value 를 넣어서

student 는 user를 상속받는다 라는 선언이 되어있는것이었다.

  '        student.__proto__ = user;          '  바로 이 문장

 

const user = {
    activate : true,
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true
};

const greedyStudent = {
    class : 11,
    __proto__ : student       // set, get 역할을 한다?? student 만 바라보게 하는건가 ??
};

console.log(greedyStudent.activate);        // user에서 상속
console.log(greedyStudent.passion);         // student에서 상속
//결과 
undefined
true

student 객체 선언에 ' __proto__ : user ' 가 적혀 있었으면 undefined 안나왔음
const user = {
    id : 'user',
    login : function(){
        console.log(`${this.id}님 로그인 되었습니다.`);
    }
};

const student = {
    __proto__ : user
};

student.id = 'user01';
student.login();            // user01님 로그인 되었습니다.
  • 프로토타입은 프로퍼티를 읽을 때만 사용하며 프로퍼티를 추가, 수정, 삭제하는 연산은 객체에 직접 한다.
  • 메소드 내의 this는 프로토 타입에 영향받지 않으며 메소드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 this는 언제나 .앞에 있는 객체이다.

( . 앞에 있는 객체 = [student] . << 여기 앞 말하는듯? login() )

  • 메소드는 공유되지만 객체의 상태는 공유되지 않는다.

for...in문은 열거 가능한 non-Symbol 속성에 대해서만 반복합니다.

이것은 쉽게 객체의 속성을 확인(콘솔이나 다른 방법으로 출력)할 수 있기 때문에 실질적으로 디버깅을 위해 사용될 수 있습니다.

배열이 데이터의 저장에 있어서는 더 실용적이지만, 키-값 쌍이 선호되는 데이터의 경우(속성이 "key"의 역할을 함)

특정 값을 가진 키가 있는지 확인하려는 경우에 for...in을 사용할 수 있습니다

const user = {
    testprop : 'test1',
    activate : true,
    
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true,
    __proto__ : user
};

const greedyStudent = {
    class : 11,
    __proto__ : student       // set, get 역할을 한다?? student 만 바라보게 하는건가 ??
};
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

for(let prop in greedyStudent) {
    console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2`);
    console.log(prop);

    // key에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 obj에 직접 구현되어있는 프로퍼티일 때만 true를 반환한다.
    let isOwn = greedyStudent.hasOwnProperty(prop);
    
    if(isOwn) {
        console.log(`객체 자신의 프로퍼티 ${prop}`);
        // greedyStudent.hasOwnProperty.
    } else {
        console.log(`상속 프로퍼티 ${prop}`);
    }
   
}
//결과 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
class
객체 자신의 프로퍼티 class
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
passion
상속 프로퍼티 passion
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
testprop
상속 프로퍼티 testprop
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
activate
상속 프로퍼티 activate
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
login
상속 프로퍼티 login

자신의 프로퍼티 순회 후  상속된 객체의 프로퍼티를 끝까지 순회 한다
키 값을 출력한다.  

함수형 프로토타입(상속)

const user = {
    activate : true,
    
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

// 생성자 함수
function Student(name) {
    this.name = name;
}

// 여기서의 prototype은 일반적인 프로퍼티 (일반적인? 무엇이?.. 이해가 잘 안되었음)
// 프로토타입(상속) 을 정의

//const student = {
//    name : 'name',
//    __proto__ (= prototype) : user
//}; 
Student.prototype = user;               

let student = new Student("홍길동");    

console.log(student.activate);
//결과 ( user 의 activate 값 )
true
  • new 연산자를 사용해 만든 객체는 생성자 함수의 프로토타입 정보를 사용해 [[Prototype]]을 설정한다.
  • F.prototype은 new F를 호출할 때만 사용된다. new F를 호출할 때 만들어지는 새로운 객체의 [[Prototype]]을 할당한다.
function Student() {}
// 함수를 만들기만 해도 디폴트 프로퍼티인 prototype이 설정
// Student.prototype = { constructor: Student }
console.log(Student.prototype.constructor);
console.log(Student.prototype.constructor == Student);

let student = new Student();    // // {constructor: Student}을 상속받음
console.log(student.constructor == Student); // true ([[Prototype]]을 거쳐 접근함)
// 결과
[Function: Student]
true
true
  • 개발자가 특별히 할당하지 않더라도 모든 (생성자?)함수는 기본적으로 "prototype" 프로퍼티를 갖는다.
  • 디폴트 프로퍼티 "prototype"은 constructor 프로퍼티 하나만 있는 객체를 가리키는데, 여기서 constructor 프로퍼티는 함수 자신을 가리킨다.

이거는 이해하고 작성한건 아닙니다

느낌은 알겠음 하지만 논리적으로는 모르겠음

built in object prototype

 

const num = new Number(100);

// num은 Number.prototype을 상속받았는가?
console.log( num.__proto__ === Number.prototype ); // true

// num은 Object.prototype을 상속받았는가?
console.log( num.__proto__.__proto__ === Object.prototype ); // true

// 체인 맨 위엔 null이 있다.
console.log( num.__proto__.__proto__.__proto__ ); // null

// Number.prototype의 toString 사용
console.log(num);                  // [Number : 100]
console.log(num.toString());         // 100
    • Function, String, Number을 비롯한 내장 객체들 역시 프로토타입에 메서드를 저장한다.
    • 모든 내장 프로토타입의 상속 트리 꼭대기엔 Object.prototype이 있어야 한다고 규정한다.
    • Object.prototype에도 메서드 toString이 있다
    • 중복 메서드가 있을 때는 체인 상에서 가까운 곳에 있는 메서드가 사용된다.

 

배열 (자바스크립트의 배열)

// 1. 배열 리터럴을 통해 배열 생성
const arr = ['바나나', '복숭아', '키위'];

//전달된 인수값이 1개, 숫자 >> length 만큼 배열 생성
const arr3 = new Array(10);
console.log(arr3);  // [ <10 empty items> ]

// 인수값이 2개 이상이거나 , 숫자가 아닌경우 인수를 요소로 갖는 배열 생성
const arr4 = new Array(1,2,3,4,5);
console.log(arr4);  // [ 1, 2, 3, 4, 5 ]

// Array.of 메소드   =    전달 된 인수를 요소로 갖는 배열 생성
console.log(Array.of(10));   //  [ 10 ]
let testArr = Array.of(1,2,3);
console.log(testArr);   //  [ 1, 2, 3 ]

const arr6 = [1,2,3,4,5];
arr6.push(6);          // 마지막 인덱스로 값 추가
arr6.pop();              // 마지막 인덱스 제거 (원본 영향 o)

const sparse = [,2 , , 4];   // 구멍 숭숭 내도 만들어짐
console.log(sparse);        //[ <1 empty item>, 2, <1 empty item>, 4 ]
console.log(sparse.length);        // 4

console.log('프로퍼티 정보');
console.log(Object.getOwnPropertyDescriptors(sparse));

//결과 
{
  '1': { value: 2, writable: true, enumerable: true, configurable: true },
  '3': { value: 4, writable: true, enumerable: true, configurable: true },
  length: { value: 4, writable: true, enumerable: false, configurable: false }
}

'인덱스' : { 상세 정보 }
writable – true이면 값을 수정할 수 있다. 그렇지 않다면 읽기만 가능하다.
enumerable – true이면 반복문을 사용해 나열할 수 있다. 그렇지 않다면 
							반복문을 사용해 나열할 수 없다.
configurable – true이면 프로퍼티 삭제나 플래그 수정이 가능하다.

함수 메소드

indexof , lastindexof, includes

const foodList = ['물회', '삼계탕', '냉면', '수박', '물회'];

// indexOf  :  요소가 위치한 인덱스 반환
console.log(`foodList.indexOf('물회') : ${foodList.indexOf('물회')}`);       
// 0           

console.log(`foodList.indexOf('물회', 1) : ${foodList.indexOf('물회', 3)}`);  
//   n번 인덱스 이후로 검색      

console.log(`foodList.indexOf('삼겹살') :  ${foodList.indexOf('삼겹살')}`);    
// 없으면 -1 반환

// lastIndexOf  :  요소가 위치한 마지막 인덱스 반환
console.log(`foodList.lastIndexOf('물회') : ${foodList.lastIndexOf('물회')}`);     
     // 4

console.log(`foodList.lastIndexOf('물회', 1) : ${foodList.lastIndexOf('물회', 1)}`);
     // 0   n번 인덱스부터 0까지 거꾸로 찾는것같음

console.log(`foodList.lastIndexOf('삼겹살') : ${foodList.lastIndexOf('삼겹살')}`);  
    // 없으면 -1 반환

// includes 포함여부
console.log(`foodList.includes('물회') : ${foodList.includes('물회')}`);     
 // true          

console.log(`foodList.includes('삼겹살') : ${foodList.includes('삼겹살')}`);    
 // false

unshift , shift

//Array.prototype.unshift : 배열의 맨앞 요소 추가
//Array.prototype.shift : 배열의 맨앞 요소 제거 후 반환
const chickenList = ['양념치킨', '후라이드', '반반'];

chickenList.unshift('간장치킨');
console.log(chickenList);        // [ '간장치킨', '양념치킨', '후라이드', '반반' ]

chickenList.shift();
chickenList.shift();
chickenList.shift();
console.log(chickenList);         //[ '반반' ]

concat

// Array.prototype.concat : 두 개 이상의 배열을 결합
const idol1 = ['아이브', '오마이걸'];
const idol2 = ['트와이스', '에스파'];
const idol3 = ['블랙핑크', '레드벨벳'];

// 배열명.concat(배열명1, 배열명2, ...)
const mix = idol1.concat(idol2);
const mix2 = idol3.concat(idol1, idol2);

console.log(`idol1 기준으로 idol2 배열을 concat : ${mix}`);
// idol1 기준으로 idol2 배열을 concat : 아이브,오마이걸,트와이스,에스파

console.log(`idol3 기준으로 idol1, idol2 배열을 concat : ${mix2}`);
// idol3 기준으로 idol1, idol2 배열을 concat : 
//  블랙핑크,레드벨벳,아이브,오마이걸,트와이스,에스파
//  블핑 레드벨벳 트와이스는 ㅇㅈ

slice , splice , reverse

// Array.prototype.slice : 배열의 요소 선택 잘라내기
// Array.prototype.splice : 배열의 index 위치의 요소 제거 및 추가
const front = ['HTML', 'CSS', 'JavaScript', 'jQuery'];

//slice (시작인덱스, 종료인덱스)          1번에서 3번 앞에놈 까지 넥슬라이스
console.log(`front.slice(1,3) : ${front.slice(1,3)}`);  
console.log(front);

// splice (index, 제거수, 추가값)       3번 뒤에 1놈 자르고 "내용추가"
console.log(`front.splice(3,1,"react") : ${front.splice(3,1,"react")}`);
console.log(front);

// Array.prototype.reverse : 배열의 순서 뒤집기
console.log(`${[1,2,3,4,5].reverse()}`);

고차메소드

sort 를 사용하는 방법 - MDN 문서

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

그냥 sort 함수는 유니코드 기준으로 비교하기 때문에 숫자 비교에는 부적합한 함수다.......

sort

let numbers = [];

for (let i = 0; i < 10; i++) {
    numbers[i] = Math.floor(Math.random() * 100) + 1;      // 1부터 100까지 소수점 다 버리기?
    
}

// 무작위 난수 생성    정렬 드가자 !!!

function compare(a,b) {
    if(a > b) return 1;
    if(a == b) return 0;
    if(a < b) return -1;
}

// sort 함수의 인자로 반환값이 1, 0 , -1 인 정렬함수를 이용해야한다.
// MDN 에게 물어보세요
numbers.sort(compare);                
console.log(`정렬 후 : ${numbers}`);

//     function(a,b) return b - a;   ( 양수값이면 a>b 음수값이면 a<b 라는 뜻)
numbers.sort((a,b) => b - a );
console.log(`내림차순 : ${numbers}`);

//     function(a,b) return a - b;   ( 양수값이면 a>b 음수값이면 a<b 라는 뜻)
numbers.sort((a,b) => a - b );
console.log(`오름차순 이해완료 : ${numbers}`);

foreach

numbers = [1,2,3,4,5];

numbers.forEach(function (item, index, array) {
    // 배열의 요소에 각각 실행할 기능을 작성, 각 요소에 대해 콜백을 실행, 배열을 순회하기때문에 break 사용 불가
    // 반환값 없음  , 배열 전용 함수이군요
    
    console.log(`item : ${item}`);
    console.log(`index : ${index}`);
    console.log(`array : ${array}`);
})

결과

item : 1
index : 0
array : 1,2,3,4,5

item : 2
index : 1
array : 1,2,3,4,5

item : 3
index : 2
array : 1,2,3,4,5

item : 4
index : 3
array : 1,2,3,4,5

item : 5
index : 4
array : 1,2,3,4,5

map

// Array.prototype.map  : 배열 요소 전체를 대상으로 콜백 함수 호출후 
//   반환값들로 구성된 새로운 배열 반환

//                                매개변수    return 값
const types = [true, 1, 'text'].map(item => typeof item);
console.log(`types : ${types}`);

//                                                         매개변수    return 값
const lengths = ['apple', 'banana', 'cat', 'dog' , 'egg'].map(item => item.length);
console.log(`length : ${lengths}`);

// 결과 
types : boolean,number,string 
length : 5,6,3,3,3 

filter

// Array.prototype.filter  : 배열 요소 전체를 대상으로 콜백 함수 호출후 
//          반환값이 true인 요소로만 구성된 새로운 배열 반환 // 원본에 영향 x

numbers = [1,2,3,4,5];

//                         매개변수    return 값
const odds = numbers.filter(item => item % 2);

console.log(odds);
console.log(numbers);    // 원본에 영향 x

// 결과
[ 1, 3, 5 ]
[ 1, 2, 3, 4, 5 ]

reduce ★★★★★★ 잠재력이 많은 함수인듯…

 

‘배열을 순회하며 ‘

각 요소에대해 이전의 콜백함수 실행 반환값을 전달하여 콜백함수를 실행하고 그 결과를 반환

 

(method) Array<number>.reduce(callbackfn:

(previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number)

// Array.prototype.reduce  : 
//    배열을 순회하며 각 요소에대해 이전의 콜백함수 실행 반환값을 
//    전달하여 콜백함수를 실행하고 그 결과를 반환

numbers = [1,2,3,4,5];

numbers.reduce(function (preValue, curValue, curIndex, array) {
    console.log(`preValue : ${preValue}`); // 이전 콜백의 반환 값
    console.log(`curValue : ${curValue}`); // 배열 요소의 값
    console.log(`curIndex : ${curIndex}`); // 배열 요소의 인덱스
    console.log(`array : ${array}`); // 메소드를 호출한 배열
}   
// 이부분에 추가로 인자를 작성할 수 있다.
// 초기 값
);

reduce 합산

// 합산
numbers = [1,2,3,4,5];
const sum = numbers.reduce(function (preValue, curValue) {
    console.log(`pre : ${preValue}, cur : ${curValue}`);

    return preValue + curValue;
});

console.log(`sum : ${sum}`);

// 결과
pre : 1, cur : 2
pre : 3, cur : 3
pre : 6, cur : 4
pre : 10, cur : 5
sum : 15

reduce 최대값

//최대값
numbers = [1,2,3,4,5];
const max = numbers.reduce(function(preValue, curValue){

        return preValue > curValue ? preValue:curValue;       
})
console.log(max);   // 5

some

배열 내 ‘일부’ 요소가 콜백 함수의 테스트를 통과하는지 확인하여 그 결과를 boolean 으로 반환

// Array.prototype.some : 

// 화살표 함수 좀 안썼으면 좋겠다 !!!!!!!!!!!
let result = [1,5,2,3,4].some(item => item > 10);
console.log(`result : ${result}`);      //    result : false

let result1 = [1,5,2,3,4].some(item => item > 3);
console.log(`result1 : ${result1}`);    //    result1 : true

result = ['apple', 'banana', 'cat', 'dog'].some(item => item === 'egg')

console.log(`result : ${result}`);     //    result : false

▼ 약간 SQL문의 ANY , ALL 느낌 △

                                          some               every

 

every

배열 내 ‘모든’ 요소가 콜백 함수의 테스트를 통과하는지 확인하여 그 결과를 boolean으로 반환

// Array.prototype.every  : 
result = [1,5,2,3,4].every(item => item > 3);
console.log(`result : ${result}`);        //   result : false


result1 = [1,5,2,3,4].every(item => item > 0);
console.log(`result : ${result1}`);        //      result : true

 

 

 

DOM이란 무엇인가?

  • Document Object Model = 문서 객체 모델
  • HTML 요소를 자바스크립트 객체(Object)처럼 조작할 수 있게 만든 모델/구조
  • 즉, DOM을 이용해서 HTML로 구성된 웹페이지를 동적으로 움직이게 만들 수 있다

w3school.com   

 

Mega site of Bible Information

You can write to us at BIBLE DESK, P.O. BOX 11106, ST PETERSBURG, FL 33733. We want to help. We confess that Jesus Christ is come in the flesh. It is written, Hereby know ye the Spirit of God: Every spirit that confesseth that Jesus Christ is come in the f

w3school.com

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript

 

JavaScript | MDN

JavaScript (JS)는 가벼운, 인터프리터 혹은 just-in-time 컴파일 프로그래밍 언어로, 일급 함수를 지원합니다. 웹 페이지를 위한 스크립트 언어로 잘 알려져 있지만, Node.js, Apache CouchDB, Adobe Acrobat처럼

developer.mozilla.org

JavaScript Reference

Properties and Methods of all JavaScript Objects

모든 자바스크립트 객체의 속성(Properties)과 함수들(Methods)

 

 

HTML DOM Reference

Properties and Methods of all DOM Objects

모든 DOM 객체의 속성(Properties)과 함수들(Methods)

 

 

 

 

특히 MDN 이 자신이 객체, 인스턴스, 배열, 반환값, 등등.. 용어 정리만 되어있다면 진짜 미친듯이 도움 많이 되는 

문서입니다.

 

바닐라 JS 공부를 열심히 합시다

클라이언트 >> 브라우저(뷰) >> Request (Controller) (자바프로그램) >> DB

클라이언트 << 브라우저(뷰) << Response << DB

 

 

 

document.getElementById(”아이디명”)

 


자바스크립트의 변수, 데이터 타입

원시 타입의 불변성 (immutable)

자바스크립트에서 원시 타입은 변수에 할당될 때 메모리에 고정 크기로 원시 값을 저장하고 그 값을 변수가 직접 가리키는 형태를 띈다.

즉 데이터를 저장하기 위한 별도의 데이터 공간을 확보해 값을 저장하고, 그 공간을 변수 영역에 저장한다.

➡️ 변수 영역과 데이터 영역이 존재 <<<<<<< 기억!!!!!!!!!!!

 

이렇게 할당된 값은 **불변성(immutable)**을 갖는다.즉 메모리에 할당된 원시 타입의 값은 그 자체가 변경될 수 없다. ( 메모리 주소가 변경되는 것이다 )

이에 대해 조금 더 자세히 설명해 보자면, 변수에 값을 재 할당할 때 기존 값이 변하는 것처럼 보이지만 사실은 새로운 메모리에 재 할당한 값이 저장되고 변수가 가리키는 메모리가 달라지는 것이다.

 

 

string 의 주소값이 계속 바뀌면서 '새 메모리 값'이 저장되고 있다는 말 .

(사진 속 주석의 의미가 조금 모호해서 이걸로 이해하기 바람)

 

 


메모리의 개념은 자꾸 자꾸 말해도 어렵고 중요한 내용이라 중복이지만 또 작성하겠습니다

변수 영역과 데이터 영역이 따로 존재합니다. (중요, 기억)

 

변수 영역에는 변수의 이름과 데이터의 ‘주소값’ 만 들어있습니다.

 

데이터 영역의 주소값 에는

@5004 >> ‘abc’

@5005 >> ‘abcdef’

이 저장되어있고

 

let a = ‘abc’;

@5004 가 저장되어있던 변수 a 에 ‘abcdef’ 값을 재 할당 하려고 하면,

a = ‘abcdef’;

변수 a 의 메모리 주소가 @5005 로 교체가 됩니다.

 


 

불변값 (Immutable Value)

  • 변수와 상수를 구분 짓는 요소 : 변수 영역 메모리의 변경 가능성
  • 불변성 여부를 구분 짓는 요소 : 데이터 영역 메모리의 변경 가능성
  • 기본형 데이터(Number, String, Boolean, Null, Undefined, Symbol)들은 모두 불변값

원시 타입에 속하는 데이터 타입에는

숫자(Number & Bigint)

문자열(String)

논리형(Boolean)

null, undefined

심볼(Symbol) 이 있다.

참조 타입 (Reference Type)

자바스크립트에서 원시 타입을 제외한 나머지는 참조 타입**(객체, Object)**이라 할 수 있다.

참조 타입과 원시 타입의 가장 큰 차이점은, 객체의 변수(프로퍼티) 영역이 추가로 존재 한다는 것이다.

  • 기본형 데이터와 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재하는 점
  • 데이터 영역에 저장 된 모든 값은 불변값
  • 변수 영역에 저장 된 값은 가변값
  • 불변값이 들어가야 되는 데이터영역에 가변값을 갖는 객체 프로퍼티 주소를 가지고 있기 때문에 참조형 데이터는 가변한다고 표현

 

 

 

위에 적은 설명으로 대체합니다 … ..

  • 데이터 영역에 저장 된 모든 값은 불변값
  • 변수 영역에 저장 된 값은 가변값
  • 불변값이 들어가야 되는 데이터영역에 가변값을 갖는 객체 프로퍼티 주소를 가지고 있기 때문에 참조형 데이터는 가변한다고 표현


 

 

 


 

 

 

 

 

 

~ = >> 문자열 포함

| = >> - 로 구분되는 단어 기준으로 일치

^ = >> 특정 값으로 시작하는 태그 ( name 이면 n 만 입력해도 적용 )

$ = >> 특정 값으로 끝

*= >>> 특정 값 포함

 

지금보니까 정규표현식이랑 문법이 비슷하군요

 

 

 

div>h4 { }

div ul { } ( ul 하위 선택자들 모두 적용 )

div li { } ( 후손에게 바로 접근 가능 )


 

 

 

 

 

선택자{ text-shadow:none|가로거리 세로거리 번짐정도 색상; }

 

하이퍼링크 밑줄 없애기   text-decoration : none;

 

 

 

 

 

 

 

예외처리   /    파일 입출력

 

JDBC 

 

Properties(설정 파일) , exception_handling     log4jdbc    스레드    소켓네트워크

 

 

제일 까다로운 것들만 남아서   

나원참 ㅡㅅㅡ

'더존 노션 필기 옮기기 > Java' 카테고리의 다른 글

Java 8일차 제네릭, 컬렉션  (1) 2022.08.30
Java 7일차 다형성  (1) 2022.08.30
Java 6일차 객체배열, 상속  (0) 2022.08.30
Java 5일차 객체  (0) 2022.08.30
Java 4일차 배열  (0) 2022.08.30

Java의 컬렉션 프레임워크의 상속구조 입니다.

컬렉션 : 요소들의 저장소이다. 요소의 개수에 따라 크기가 자동 조절된다. 요소의 삽입, 삭제에 따른 요소의 위치 자동 이동.-> 배열이 가진 고정 크기의 단점을 극복하기 위해 객체들을 쉽게 삽입 삭제 검색 할 수 있는 가변 크기의 컨테이너이다.

가변 크기의 컨테이너 답게 add 함수를 이용해서 초기 값을 넘겨 추가를 해도 계속 삽입 되어진다.

 

 

자주쓰는 프레임워크 : LIst , ArrayList

 

배열과 컬렉션의 차이점 배열은 고정 크기 이상의 객체를 관리할 수 없고, 중간에 객체가 삭제되면 응용프로그램에서 자리를 옮겨야 한다. 하지만 컬렉션은 가변 크기로서 객체의 개수를 염려할 필요가 없고 컬랙션 내의 한 객체가 삭제되면 컬렉션이 자동으로 자리를 옮겨준다.

 

컬렉션의 특징 : 컬렉션 자체가 제네릭 기법으로 구현되어있고, 컬렉션의 요소는 객체만 가능하다.

ArrayList<E> 에서 E 대신 구체적인 타입을 지정하면 그 값만 저장하는 ArrayList를 사용할 수 있다. 특정 타입만 다루지 않고 여러 종류의 타입으로 변신할 수 있도록 컬렉션을 일반화시키기 위해 <E>를 사용하는 것. <E> 자체를 타입 매개변수라고 부르고 타입 매개변수를 일반화 시킨 타입을 제네릭 타입이라고 부른다.

 

제네릭 타입 매개변수 컬렉션(ArrayList의 부모) 클래스에서 타입 매개변수로 사용하는 문자는 다른 변수와 혼동을 피하기 위해 일반적으로 하나의 대문자를 사용 ex(E :element T : type V : value K : key)

 

제네릭 컬렉션 활용

ArrayList**<E>** : 배열을 가변 크기로 다룰 수 있게 하고 객체의 삽입 삭제 이동이 쉽도록 구성한 컬렉션 클래스이다. ArrayList는 삽입되는 요소의 개수에 따라 자동으로 크기를 조절하고, 요소의 삽입과 삭제에 따라 자동으로 요소들의 자리를 이동.

 

ArrayList<E>

가변 크기의 배열을 구현한 컬렉션 클래스. 경로명은 java.util.ArrayList, Vector 클래스와 거의 동일.차이점은 ArrayList는 스레드 간에 동기화를 지원하지 않기 때문에 다수의 스레드가 동시에 ArrayList에 요소를 삽입하거나 삭제할 때 ArrayList의 데이터가 훼손될 우려가 있다. 하지만 멀티스레드 동기화를 위한 시간 소모가 없기 때문에 ArrayList는 Vector보다 속도가 빨라, 단일 스레드 응용에는 더 효과적이다.

선언 , 생성

ArrayList<String> a = ArrayList<>() ; >> 자료형 선언 후, 생성 시에는 생략 가능.

ArrayList의 크기 알아내기 int len = a.size() //

ArrayList의 값 추가 a.add( (index) , value) >

ArrayList의 요소 전체 삭제 유사. a.clear(); -> 모든 요소를 삭제하는 메소드

ArrayList의 요소 삭제 a.remove(index or value) > 인덱스 또는 값 하나만 삭제

ArrayList의 해당 인덱스의 값 반환 a.get(index)

ArrayList의 해당 인덱스 값 변경 a.set(index, value)

ArrayList의 해당 값의 인덱스 반환하기 a.indexOf(value) >> 해당 인덱스가 없다면 -1 반환

ArrayList의 해당 값 존재 여부 확인 a.contains(value) >> true & false

제네릭 다시 설명

• 어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍 하는 것을 '제네릭(Generic) 프로그래밍' 이라고 한다.

• 여러 참조 자료형이 쓰일 수 있는 곳에 특정한 자료형을 지정하지 않고 클래스나 메서드를 정의한 후 사용하는 시점에 어떤 자료형을 사용할 것인지 지정하는 방식

public class TestGene<T>
{
	public T sample;

	public void showYourType(){
		if(sample instanceof Integer)
			System.out.println("Integer 타입 입니다");
		else if(sample instanceof String)
			System.out.println("String 타입 입니다");
	}
}

위의 코드에서 T 는 현재 타입이 정해져 있지 않습니다 (Type 의 약자)

T 는 TestGene의 인스턴스가 생성 될 때 결정이 됩니다.

public class Main{
	public static void main(String[] args) {
		TestGene<String> stringType = new TestGene<String>();
		TestGene<Integer> integerType = new TestGene<Integer>();

		stringType.sample = "Hello";
		integerType.sample = 1;

		stringType.showYourType();
		integerType.showYourType();
	}
}

<String> , <Integer> 부분이 타입 입니다.

제네릭은 기본 자료형 ( long , int … ) 에 대해서는 지정이 불가능 합니다. 다만 기본 타입을 객체 타입으로 사용하는 Wrapper 클래스 (Integer, Boolean … ) 에는 제네릭 사용이 가능합니다.

public class Data<T>{
	public T data;

	public Data(T data){
		this.data = data;
	}
}

public class Main{
	public static void main(String[] args) {
		Data data = new Data("Hello");
		Data<String> data2 = new Data("Hello World");
	}
}

Data 클래스의 생성자에 매개변수로 자료형을 T (제네릭)으로 설정하게 된다면

Data 인스턴스 생성 시에

여러 참조 자료형을 사용할 수 있다는 것이 장점이라고 하는데, ArrayList 사용시 한정으로 가급적이면 상속 관계를 가지고 있는 클래스들로 제한해서 사용하는 것이 좋을 듯 하다 (내 생각)

 

'더존 노션 필기 옮기기 > Java' 카테고리의 다른 글

Java 아직 미작성한 챕터  (1) 2022.08.30
Java 7일차 다형성  (1) 2022.08.30
Java 6일차 객체배열, 상속  (0) 2022.08.30
Java 5일차 객체  (0) 2022.08.30
Java 4일차 배열  (0) 2022.08.30

클래스 형변환 ( Animal , Rabbit , Tiger ) = 여러 타입의 클래스를 하나의 클래스로 관리가 가능하다

동적 바인딩 = 컴파일 당시에는 해당 타입의 메소드와 연결 되어 있다가 런타임 시에는 실제 객체가 가진 오버라이딩 된 메소드로 바인딩이 바뀌어 동작하는것을 의미한다

( 점심 먹고 졸다가 주석이 휴먼졸림체로 적혀버렸습니다 )

추상클래스와 인터페이스

추상클래스 = 구현부가 없는 클래스

추상클래스를 인스턴스로 만들 수 없음

추상클래스를 사용하려면 다형성을 이용하여 추상클래스를 상속받은 하위클래스를 이용하여 인스턴스 생성.

추상클래스의 추상메소드는 오버라이딩에 의한 강제성이 부여됨.

장점 : 필수 기능을 정의하여 강제성을 부여해 개발 시 일관된 인터페이스를 제공함

abstract class : 추상 클래스

abstract void abstractMethod() : 추상 메소드

extends Product : 추상 클래스(Product) 를 상속 받음

@Override public void abstractMethod() : 구현을 해도되고 안해도 됨.

구현 안함 = 다음 상속 받을 놈 한테 책임 전가

인터페이스 = 모든 메소드가 추상메소드인 클래스

인터페이스를 상속받는 클래스는

인터페이스에 정의된 추상 메소드를 반드시 반드시 절대로 절대로 구현 해야하는 책임이 있다.

API ( Application Programming Interface )

Book 클래스 Object 함수인 toString, equals , hashcode 오버라이딩(재정의)

 

'더존 노션 필기 옮기기 > Java' 카테고리의 다른 글

Java 아직 미작성한 챕터  (1) 2022.08.30
Java 8일차 제네릭, 컬렉션  (1) 2022.08.30
Java 6일차 객체배열, 상속  (0) 2022.08.30
Java 5일차 객체  (0) 2022.08.30
Java 4일차 배열  (0) 2022.08.30

일반 배열 만드는 형식, 초기화 방식

int[] intArr = new int[5];
int[] intArr2 = new int[] { 11, 22,  33, 44, 55 }

객체 배열 만드는 형식, 초기화 방식

Car[] carArr = new Car[5]
carArr[0] = new Car("차1",30);
carArr[1] = new Car("차2",60);
carArr[2] = new Car("차3",90);
carArr[3] = new Car("차4",120);
carArr[4] = new Car("차5",150);

배열 : 동일한 자료형의 모음

객체 배열 : 동일한 객체의 모음

객체배열에서 인덱스 하나에 접근하면 객체 이다.

carArr[0].information()
carArr[0].setName() , getName() ...  인덱스 하나를 지정해서 접근가능.

상속 ( inheritance )

/*상속(inheritance)
* 부모가 가지고 있는 재산(자바에서는 클래스가 가지는 멤버)을 자식이 물려받는 의미
* 자바에서의 상속은 부모클래스의 확장(extend)의 개념
* 물려받아서 자신의 것 처럼 사용하는 것 뿐 아니라 추가적인 멤버도 작성이 가능
* 특히 메소드 재정의(overriding)라는 기술을 이용해서 부모가 가진 메소드를 재정의 하는 것도 가능
* 
* 메소드 재정의(overriding)이란 부모가 가지는 메소드 선언부를 그대로 사용하면서
* 자식클래스가 정의한 메소드대로 동작하도록 구현 몸체 부분을 새롭게 다시 작성하는 기술이다.
* 메소드 재정의를 하면 메소드를 호출할 시 재정의한 메소드가 우선적으로 동작하게 된다.
 * */
부모 클래스의 성질을 물려받는다. ( 필드, 메소드 )

/* 상속이라는 기술을 사용하게 되면 얻게되는 이점은 크게 두 가지로 볼 수 있다.
* 1. 새로운 클래스를 작성할 시 기존에 작성한 클래스를 재사용할 수 있다.
 *  1-1. 재사용 시 생산성을 크게 향상시킬 수 있다. (코드가 줄어듬 ,새롭게 작성하는거보다 빠르다)
 *  1-2. 공통적으로 사용하는 코드가 부모클래스에 존재하면 수정사항이 생길 시 부모 클래스만 수정해도
 *       전체적으로 적용된다. (유지보수성 증가)
 * 2. 클래스간의 계층 관계가 형성되며 다형성의 문법적인 토대가 된다.
*/

상속 사용 방법

Car.java

public class Car{ // 모든 종류의 차는 자동차라고 대분류 할 수 있다. 부모 역할을 하는중
	private String brand;

	Car(String brand){  // 생성자
		this.brand = brand;
	}

	public void soundHorn(){ // 경적
		System.out.println("일반 자동차 경적")
	}
}

FireCar.java

public class FireCar extends Car{  // Car의 성질을 물려받아서 쓰겠다 부모를 상속받은 자식클래스
	private String color;

	FireCar(String brand, String color){   // 부모의 생성자를 이용해서도 초기화가 가능하다
		super(brand);   // 부모의 생성자(Car ) 를 호출
		this.color = color;
	}

	@Override
	public void soundHorn(){
	// super.soundHorn();  // 부모의 soundHorn 함수를 실행함
  // 부모에도 똑같은 이름의 함수가 있는데, 자식에서 재정의(오버라이딩) 함
	System.out.println("소방차의 경적")   
	}

}

 

super : 부모클래스의 인스턴스 주소를 보관하는 레퍼런스 변수

super() : 부모클래스의 생성자를 호출하는 함수

'더존 노션 필기 옮기기 > Java' 카테고리의 다른 글

Java 8일차 제네릭, 컬렉션  (1) 2022.08.30
Java 7일차 다형성  (1) 2022.08.30
Java 5일차 객체  (0) 2022.08.30
Java 4일차 배열  (0) 2022.08.30
Java 3일차 함수 조금, 스캐너, 제어문, 반복문  (1) 2022.08.30

클래스의 구조

필드, 행위

public class 클래스명 {

필드
( 필드부의 접근제한자는 private 로 지정해주는것이 객체지향설계원칙 중의 하나이다. 캡슐화 )

생성자
생성자란, new로 새로운 객체가 생성될때 자동으로 실행되는 함수로써 
( 함수의 이름이 클래스 명과 일치해야한다 )
객체를 초기화할 때 편하다.

setter , getter
필드 변수가 private 이기 때문에 getter 와 setter 로 접근해야한다.

사용자 정의 함수
public String information(){
	return "객체정보";
}

}

필드 변수만 개발자가 작성해두면 이클립스 단축키 (Alt + Shift + S ) 로 생성자, 매개변수를 필요로 하는 생성자, setter ,getter 를 자동으로 만들어줍니다.

생성자의 호출 시점

main(){
	Car c = new Car()  //  바로 여기가 생성자가 호출되는 곳
}

/*
Car() >> 기본생성자 호출
Car(매개변수1, 매개변수2 ... ) >> 매개변수를 필요로 하는 생성자 호출
해당 인스턴스의 필드변수의 값을 매개변수로 저장하게 됨.

*/

/* 생성자를 이용한 초기화와 설정자를 이용한 초기화는 각각의 장단점이 존재한다.
   * 
   * 1. 생성자를 이용한 초기화
   * 장점 : setter 메소드를 여러 번 호출해서 사용하지 않고 단 한번의 호출로 
인스턴스를 생성 및 초기화 할 수 있다.
   * 단점 : 필드를 초기화할 매개변수의 갯수를 경우의 수 별로 모두 만들어둬야 한다.
   *      호출 시 인자가 많아지는 경우 어떠한 값이 어떤 필드를 의미하는지 한 눈으로 보기 힘들다.
   *      예) 아이디, 비밀번호, 이름이 모두 ohgiraffers인 경우
   *          new User("ohgiraffers", "ohgiraffers", "ohgiraffers"); 
몇 번째 인자가 아이디인지 이름인지 알 수 없다.
   * 
   * 2. 설정자를 이용한 초기화
   * 장점 : 필드를 초기화하는 각각의 값들이 어떤 필드를 초기화하는지 명확하게 볼 수 있다.
   *      예) 아이디, 비밀번호, 이름이 모두 ohgiraffers인 경우
   *          User user = new User();
   *          user.setId("ohgiraffers");
   *          user.setPwd("ohgiraffers");
   *          user.setName("ohgiraffers");
   *         호출하는 코드만 봐도 어떤 값이 어떤 필드를 초기화하는 내용인지 쉽게 알 수 있다.
   * 단점 : 하나의 인스턴스를 생성할 때 한 번의 호출로 끝나지 않는다.      
   *  */

오버로딩 ( 상속과 관련이 없음 !!! )

생성자나 함수를 선언할 때 (사실 둘 다 함수긴 하지만) 매개변수의 개수, 타입, 순서를 다르게 작성하면 서로 다른 생성자나 함수로 인식하게 된다.

이것을 오버로딩 이라고 한다.

오버로딩의 사용 이유 매개변수의 종류별로 메소드 내용을 다르게 작성해야 하는 경우들이 종종 있다. 이 때, 동일한 기능의 메소드를 매개변수에 따라 다르게 이름을 정의하면 복잡하고 관리하기가 매우 어려울 것이다. 규모가 작은 프로그램의 경우는 정도가 덜 하지만, 규모가 거대해지면 메소드 또한 관리하기가 매우 어려워진다. 따라서 동일한 이름으로 다양한 종류의 매개변수에 따라 처리해야 하는 여러 메소드를 동일한 이름으로 관리하기 위해 사용하는 기술을 오버로딩이라고 한다.

배열이란??

동일한 자료형의 묶음이다.

Heap 메모리에 new 연산자를 이용하여 할당한다.

배열의 인덱스는 0번부터 시작한다 ( 중요 )

자료형 별 배열 선언 형식

// 자료형에 []를 붙이던  변수명에 []를 붙이던 상관없다.
int[] intArr;  // 저는 이 형식을 더 선호합니다
int intArr[];

// 선언과 동시에 초기화를 할 수 있다.
int[] intArr = new int[5]; // 크기만 지정 할 경우 초기값으로 5칸이 채워진다.
int intArr[] = new int[5]; // 정수형의 초기값 : 0

// 선언만 하고 나중에 초기화를 할 수도 있다.
int[] intArr;
intArr = new int[5];

// 크기를 지정하지 않고 초기화도 가능하다. 중괄호를 사용한다.
int[] intArr = {11, 22, 33, 44, 55 }; 
int[] intArr = new int[] {11, 22, 33, 44, 55 };

				/* 값의 형태 별 기본값
	       * int        정수 : 0
	       * double     실수 : 0.0
	       * boolean    논리 : false
	       * char       문자 : \\u0000
	       * String     참조 : null
	       * */

// 문자열(String) 을 charAt() 함수를 사용하여 한 글자씩 잘라서 char 배열에 저장할 수 있다.
// char[i] chArr = sc.nextLine().charAt(i)     // i 는 반복문 인덱스 

// 배열을 초기화하거나 출력하는 등의 작업에는 반복문 사용이 필수적이다.

// 배열명.length = 배열의 길이 값 리턴.

2차원 배열

// 1차원 배열이 이렇게 생겼다면,
int[] intArr = new int[5]
[  ][  ][  ][  ][  ]
// 2차원 배열의 형태
int[][] intArr2 = new int[2][3]   // [행][열]
[  ][  ][  ]
[  ][  ][  ]

// 각각의 위치 , 배열의 시작 인덱스는 0 번
[ int[0][0] ][ int[0][1] ][ int[0][2] ]
[ int[1][0] ][ int[1][1] ][ int[1][2] ]

for(int i = 0; i < inrArr2.length; i++){   // 조건식 i < 행의 개수
	for(int j = 0; j < inrArr2[i].length; j++) {  // 조건식 j <열의 개수
	    		System.out.print(inrArr2[i][j] + " ");    		// 해당 위치 값출력 + 공백
	}
}

//수행결과    정수형 배열의 초기값 = 0
0 0 0 
0 0 0 

 

정변배열, 가변배열의 선언, 할당

2차원배열 하나씩 접근하기

array_copy app2 얕은복사 다시보기 ㅡㅡ;;

Math 클래스

Math 클래스는 기본적인 산술연산을 제공해주는 클래스로써 java.lang 패키지에 포함되어있다.

Math 클래스의 함수는 모두 static 으로 정의 되어있어서 인스턴스를 만들지 않아도 사용할 수 있다.

확인하고 싶으면

Ctrl 누르고 Math 부분 클릭

제가 알아볼 수 있는건....  PI가 상수로 정의되어있네요~ 역시 산술연산 클래스 클라쓰 🍷

스캐너

Scanner sc = new Scanner(system.in);

java.util 패키지에 있는 Scanner 클래스를 import 해야 정상적으로 사용할 수 있다.

알맞는자료형 변수 = sc . next 자료형 ();

예시) int num = sc.nextInt();

해석) int 자료형 변수 num에 사용자로부터 콘솔에서 입력 받은 정수를 저장한다.

예시) String str = sc.next();

해석) String 자료형 변수 str에 사용자로부터 콘솔에서 입력 받은것 중 공백을 만나기 전 까지의 문자열 전부를 저장한다.

예시) String str = sc.nextLine();

해석) String 자료형 변수 str에 사용자로부터 콘솔에서 입력 받은 엔터 치기 전 까지의 문자열 전부를 저장한다.

import java.util.Scanner;

/* 1. Scanner 객체 생성 */
/* 1-1. 원래 이렇게 Scanner 객체를 만들어야 함 */
//java.util.Scanner sc = new java.util.Scanner(java.lang.System.in);
		
		
		Scanner sc = new Scanner(System.in);
		
// 2. 자료형 별 값 받기
// 2.1 문자형 /* nextLine() : 입력받은 값을 문자열로 반환해줌 */

// 2.2 정수형
// nextInt() : 입력받은 값을 Int로 변환 한다.
/* nextLong() : 입력받은 값을 long 형으로 반환한다.*/

/* 2-3. 실수형 값 입력 받기 */
/* nextFloat() : 입력받은 값을 float 형으로 반환한다. */
/* nextDouble() : 입력받은 값을 double 형으로 반환한다. */

/* 2-4. 논리형 값 입력받기 */
/* nextBoolean() : 입력받은 값을 boolean형으로 반환한다.
* true or false 외에 다른 값을 입력하게 되면 InputMismatchException 발생함
* */

/* 2-5. 문자형 값 입력받기 */
/* 아쉽게도 문자를 직접 입력 받는 기능을 제공하지는 않는다.
* 따라서 문자열로 입력을 받고, 입력받은 문자에서 원하는 번째 문자를 분리해서 사용해야 한다.
* java.lang.String에 charAt(int index)를 사용한다.
* index를 정수형으로 입력하면 문자열에서 해당 인덱스에 있는 한 문자를 문자 형으로 반환해주는 기능을 한다.
* 
* index는 0부터 시작하는 숫자 체계
* 만약 존재하지 않는 인덱스를 입력하게 되면 IndexOutOfBoundsException이 발생한다.
* */

System.out.println("아무문자나 입력해주세요 : ");
char ch = sc.nextLine().charAt(0);    // charA(n)   n 번째 인덱스 가져오는 함수

System.out.println("입력하신 문자는" + ch + "입니다.");

next() , nextXXX() 사용시 주의점

만약 두 가지 데이터를 받기 위해서 next함수를 연이어서 사용해야 하는 경우.

예시)

int num1 = sc.nextInt();
Sring num2 = sc.nextLine();

두 번째 데이터를 입력받을 때 nextLine() 함수 사용 시,

첫 번째 데이터 입력하고 난 뒤 ‘엔터’ 값이 두 번째 데이터에 바로 입력되는 문제가 발생한다

이를 방지하기 위해서는 nextLine 함수를 한 줄 추가해주면 해결이 된다.

int num1 = sc.nextInt();
sc.nextLine();                   // 추가 
Sring num2 = sc.nextLine();

제어문 if , if-else , switch

// 제어문 형식

if (조건식) {
	// 조건식에 맞으면 발동되는 코드
}else {
	// 조건식에 맞지 않으면 발동되는 코드
}

if (조건식1){
		//조건식1 에 맞을 때 발동되는 코드
} else if(조건식2){
		//조건식2 에 맞을 때 발동되는 코드
}else if ... {
		//조건식3 에 맞을 때 발동되는 코드
}else{
	//아무 조건에도 해당되지 않을 때 발동되는 코드
}

switch(변수)
	case (변수값1):
		// 행위
		break;  // 행위를 그만두고 switch 문을 끝내려면 break;
	case (변수값2):
		// 행위
		// 만약 break; 를 사용하지 않았다면, case가 연속되어서 실행된다.
	default:
		//switch의 인자인 변수가 아무값도 해당 되지 않을 때 발동되는 코드

if(조건식){
	if(조건식){
			if(조건식){
				....
			}
		}
}

반복문 for

// for 문 표현식
for(초기식; 조건식; 증감값;){
	하고싶은 일;
}

// 아래에서 사용되는 int i 는 지역번수이므로 , 반복문 안에서만 사용 할 수 있다.
for(int i = 0; i < 10; i++){

}

// 기존에 있는 변수를 이용 할 수도 있다.
int index = 0;
for(index = 0; index < 10; index++){

}
// 반복문이 끝나면 index는 10 인채로 남아있다.

반복문 while

// while 문 표현식
while(조건식){  // 조건식이 만족되는 동안 반복
	하고싶은 일;
	한 번의 반복 마다 조건식의 증감에 영향을 주는 코드;  // 없으면 무한 반복 하게 된다.
}

while(life != 0){  // life가 0이 아닌 동안 반복  >> life가 점점 줄어들다가 0이되면 종료 됨
	야구 게임;
	life--;  // 한 번 반복할 때 마다 life 가 1씩 감소함.
}

슬슬 내용 정리를 할 여유가 없네요

산술 연산자

복합 대입 연산자 ( +=, -= , *= … )

a+= >> a = a + 1

a-= >> b = b - 1

개인적으로 오른쪽 식이 저는 더 보기 좋습니다

코드는 자기가 알아보기 좋게 작성하는게 이득

증감 연산자 ( 전위 후위 )

비교 연산자 ( == . != )

논리 연산자 ( && || )

삼항 연산자 조건식 ? ‘true 값’ : ‘false 값’ >> 대입연산자로 바로 변수에 값 초기화도 가능

메소드(함수)

함수를 설명하기에 가장 친숙한 그림 마법의 함수 상자 입니다.

사과를 한 개 넣으면 막 세 개가 나오고… ㅋㅋ 😆

x 값을 넣으면 y 값으로 나온다 (일반인의 생각)

매개변수 x 를 넣으면 y값이 리턴 된다 (개발자의 생각) 😎

static stack heap ???

함수를 설명하기 전에 조금 심화 단계 일 수도 있지만

자바 프로그램의 동작 원리를 알아보겠습니다

이걸 설명하기 위해선 ‘메모리’라는 개념이 등장하는데요

컴퓨터 부품 중에 RAM 이라는게 있죠? Random Access Memory 의 약자인데 이것도 메모리입니다

음악 프로그램, 크롬, 게임 등등 무언가 프로그램을 실행하려면 운영체제에게 메모리를 할당 받아서 실행을 하게 되는데 자바 프로그램 또한 똑같습니다.

우리가 Application을 만들어서 ▶️ RUN 버튼을 누르면 프로그램에 메모리가 할당이 되는데 총 3가지 종류의 메모리가 있습니다.

Static ( 정적 데이터 저장 공간 )

이는 전역 변수와 정적 멤버 변수 static이 붙은 자료형을 저장합니다. 문제는 한 번 선언된 전역 변수는 언제 어디서든 꺼내 쓸 수 있습니다. 덕분에 개발시에 편리하지만 메모리가 계속 상주해 있습니다. 그래서 사이트가 느려지고 서버가 다운되는 경우가 발생하기도 합니다. 그래서 스태틱 메모리 영역은 정말 잘 사용해야 합니다.

Stack ( 메소드(함수) 의 생명주기, 기본 자료형 )

기본 자료형을 생성할때 저장되는 공간이 스택 메모리 영역입니다. 데이터 값이 저장되는 공간이라고 보면 됩니다. 메소드가 실행될때 할당 되고 메소드가 종료하면 함께 종료됩니다.

추가) main 메소드도 이 저장공간 가장 첫 스택으로 실행됩니다. main이 스택에서 꺼내질 때, 
프로그램이 종료 됩니다.

*생명주기 = 시작부터 종료 까지의 기간

Heap ( 동적 데이터 저장 공간, new 인스턴스 )

인스턴스 생성할때 생성되는 메모리 형식입니다. new를 사용하여 객체를 생성하면 저장됩니다. 참조형 자료도 힙 메모리 영역으로 저장됩니다. 힙 참조 값은 스택 메모리 영역에서 가지고 있고 해당 객체를 통해서만 힙 메모리에 있는 인스터스들을 핸들링 할 수 있습니다.

 

▲ 더블 클릭하면 확대 되네요 ( 노션에서는 됐는데 티스토리 이 쓰레기 블로그 ㅠㅠ )

메소드의 형식

//   *접근제한자 : 아직 배우지 않았지만. public , private 등등 이 있음.
// static 함수인 경우
접근제한자 static 반환자료형 함수이름 (매개변수, ...){
	작업하고싶은 행위 마음껏 입력

	return (반환자료형에 맞는 데이터);
}

// static 함수 아닌경우
접근제한자 반환자료형 함수이름 (매개변수, ...){
	작업하고싶은 행위 마음껏 입력

	return (반환자료형에 맞는 데이터);
}

// 반환자료형이 void 인 경우   >> return이 없음
접근제한자 void 함수이름 (매개변수, ...){
	작업하고싶은 행위 마음껏 입력

}

//   *매개변수의 개수는 없어도되고, 여러개여도 됨

예시) 
public static void main(String[] args){

}

/*1 */public class Application{
/*2 */	public static void main(String[] args){
/*3 */		Application app = new Application();
/*4 */		System.out.println(app.plusMethod(3,5);
/*5 */	}
/*6 */	
/*7 */	public int plusMethod(int a, int b){
/*8 */		return a + b
/*9 */	}
/*0 */}

메소드의 형식을 알았으니 이제 일반적인 사용 방법입니다.

형식에 맞게 자기가 선언하고싶은 클래스에서 메소드를 정의하면 되는데요 !!!

( 위 예시에서 7행 부분 )

정의는 했지만 이 함수에 접근하기 위해서는 (메모리 개념)

객체 인스턴스를 생성(new) 해야 접근할 수 있습니다.

( 위 예시에서 3행 부분 )

Application 객체의 app 인스턴스에 . (점 ) 연산자를 이용하여 접근해서

plusMethod 메소드를 사용할 수 있습니다.

( 위 예시에서 4행 app.plusMethod(3,5) 부분 )

위에 설명 했던 메모리의 개념으로 코드 예제를 한 행 씩 컴파일러에 빙의해서 해석해볼까요 ~~

2행 : main을 찾았으니 Stack 메모리에 넣어둡니다.

3행 : new 를 찾았으니 Heap 메모리에 Application 클래스의 인스턴스 app 을 넣어둡니다.

4행 : 인스턴스 app이 가지고 있는 plusMethod 함수를 출력 하는 문장이구나

 app 인스턴스니까 Application클래스에 가보면 정의된 plusMethod 이름의 함수를 찾을수 있겠네

7행에 있구나 7행으로 가자

7행 : 함수 실행과 종료 → 4행으로 복귀

5행 : main 함수의 닫히는 중괄호 } 를 만나서 main 함수 종료. 스택 메모리에서 main 사라짐.

⚠️non static 과 static

//메소드의 형식 에서 가져옴

// static 함수인 경우
접근제한자 static 반환자료형 함수이름 (매개변수, ...){
	작업하고싶은 행위 마음껏 입력

	return (반환자료형에 맞는 데이터);
}

// static 함수 아닌경우
접근제한자 반환자료형 함수이름 (매개변수, ...){
	작업하고싶은 행위 마음껏 입력

	return (반환자료형에 맞는 데이터);
}

같은 패키지 안에 있는 다른 클래스 입니다. ( Application9 , Calculator )

Calculator

non static 함수 minNumberOf , static 함수 maxNumberOf

Application9

min 변수에 값을 담을 때, Calculator 클래스의 calc 인스턴스를 생성해서 Calculator의 함수에 접근함

max 변수에 값을 담을 때, 인스턴스를 만들지 않고 클래스에서 바로 함수에 접근함

굳이 인스턴스를 만들어서 static 함수에 접근하면 컴파일러가 노란줄을 긋고 경고한다.

정처기 실기에도 가끔 출제가 되는 static 개념

⚠️다른 클래스( Calc ), 다른 패키지의 함수에 접근하기( import )

아직 정리 못했음 !

package com.uni.section02.method;

public class Application1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/* 패키지와 임포트 */
	      /* 패키지 : 서로 관련 있는 클래스 또는 인터페이스 등을 모아 하나의 묶음(그룹)으로 단위를 구성하는 것을 말한다.
	       *        같은 패키지 내에서는 동일한 이름의 클래스를 만들 수 없지만, 패키지가 다르면 동일한 이름을 가진 클래스를 만들 수 도 있다.
	       *        클래스명은 원래 패키지명을 포함하고 있기 때문이다.  예)com.uni.section01.method.Calculator (이게 클래스명이다.)
	       *        지금까지 클래스명에 패키지명을 함께 사용하지 않은 이유는 동일한 패키지 내에서 사용했기 때문이다.
	       *        그렇기 때문에 서로 다른 패키지에 존재하는 클래스를 사용하는 경우에는 클래스명 앞에 패키지명을 명시해서 풀 클래스 이름으로 사용해야 한다.
	       * */
		
		// non static 메소드
		com.uni.section01.method.Calculator calc = new com.uni.section01.method.Calculator();
		
		int min = calc.minNumberOf(30, 20);
		System.out.println(min);
		
		// static 메소드
		int max = com.uni.section01.method.Calculator.maxNumberOf(30, 20);
		
		System.out.println(max);
	}

}

패키지 경로명을 import 하지 않으면 손으로 일일이 타자로 입력 해야 한다.

package com.uni.section02.method;
import com.uni.section01.method.Calculator;      // 추가된  코드

public class Application2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	      /* 패키지와 임포트 */
	      /* 임포트 : 서로 다른 패키지에 존재하는 클래스를 사용하는 경우 패키지명을 포함한 풀 클래스 이름을 사용해야 한다.
	       *        하지만 매번 다른 클래스의 패키지명까지 기술하기에는 번거롭다.
	       *        그래서 패키지명을 생략하고 사용할 수 있도록 한 구문이 import 구문이다.
	       *        import는 package 선언문과 class 선언문 사이에 작성하며
	       *        어떠한 패키지 내에 있는 클래스를 사용할 것인지에 대해 미리 선언하는 효과를 가진다.
	       * */
		
		Calculator calc = new Calculator();
		
		int min = calc.minNumberOf(30, 20);
		System.out.println("두 수중 최소값은 " + min);
		
		int max = Calculator.maxNumberOf(30, 20);
		System.out.println("두 수중 최대값은 " + max);
	}

}

상단부에 패키지 경로를 import 하게 된다면 편하게 사용할 수 있다 !

복합 대입 연산자 ( +=, -= , *= … )

a+= >> a = a + 1

a-= >> b = b - 1

개인적으로 오른쪽 식이 저는 더 보기 좋습니다

코드는 자기가 알아보기 좋게 작성하는게 이득

증감 연산자 ( 전위 후위 )

비교 연산자 ( == . != )

논리 연산자 ( && || )

삼항 연산자 조건식 ? ‘true 값’ : ‘false 값’ >> 대입연산자로 바로 변수에 값 초기화도 가능

컴파일 : 인간이 작성한 코드를 컴퓨터가 알아듣게 번역하는 작업

컴파일러

자바 언어를 해석하는놈은 자바컴파일러 ( javac )

이놈의 특징 >> 컴파일 하고 나면 class 파일이 생성 된다.

두 가지 파일을 직접 열어보시면 감이 오실거에요.

.java 파일 >> notepad++ 로 실행하면 인간의 언어가 보인다. ( 컴퓨터의 입장에서 이해 불가능)

.class 파일 >> notepad++ 로 실행하면 기계어가 보인다. ( 컴퓨터의 입장에서 이해 가능 )

JDK ( Java Development Kit )

여러가지 종류가 있는데 제일 대표적인 JDK는

OpenJDK , Oracle JDK 1.8 (일점팔) , Oracle JDK 11 (십일)

작업 경로 : C\Workspace

개발 도구 : 이클립스 설치

  1. 6월 버전

https://www.eclipse.org/downloads/packages/release/2021-06/r

 

2021-06 R | Eclipse Packages

517 MB 519,828 DOWNLOADS Tools for developers working with Java and Web applications, including a Java IDE, tools for JavaScript, TypeScript, JavaServer Pages and Faces, Yaml, Markdown, Web Services, JPA and Data Tools, Maven and Gradle, Git, and more. Cli

www.eclipse.org

설치 끝났으면

window - preference

🔎

spelling , workspace UTF-8 인코딩 설정 (필 수 )

01_firstproject > 아무것도 건들지 말고 Finish

모듈 Dont Create 클릭

우클릭 - new - class

 

 

 

 

 

패키지 : 유사한 클래스를 묶어주는 역할, 항상 맨위에 선언 해주어야 함

main 메소드 ( 메소드 = 함수 같은뜻입니다 )

public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Hi~~~~");
	}

함수 이름이 main 인 놈을 말합니다 ( 함수가 무엇이냐… 그것은 다음에 알아봅시다 )

한 프로젝트에 반드시 이 녀석(메인 함수) 한 개 는 있어야 프로젝트가 실행이 됩니다

주석 사용 방법 ( 매우 매우 매우 매우 매우 중요 )

코드가 지저분 하게 보이긴 하지만 거의 매 함수, 매 변수마다 주석을 해주는게

기억하기도 편하고 아무튼 유용합니다 !!!!!!!!!

무조건 주석 많이 하세요

주석 안하는 개발자는 멍청한 개발자 입니다 ~

//한줄 주석하기
/*
  통째로
  주석
  하기
*/

한 줄 주석 단축키 
Ctrl + /

여러줄 주석 단축키  (드래그 해서 블록지정 한 코드만)
Ctrl + Shift + /


변수

자료형

논리 boolean

문자 char, String

정수형 int

실수형 double

새 프로젝트 생성

사진은 없는데 프로젝트 이름 02_variable

새 클래스 생성

Application2

package com.uni.section01.literal;

public class Application2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		   /* 값을 직접 연산하여 출력할 수 있다. 
	       * 값의 형태에 따라 사용할 수 있는 연산자의 종류와 연산의 결과가 달라진다. 
	       * */
	      
	      /* 1. 숫자와 숫자의 연산 */
	      /* 1-1. 정수와 정수의 연산 */
	      /* 수학적으로 사용하는 사칙연산에 추가로 나머지를 구하는 연산(mod)을 사용할 수 있다. */
	      System.out.println("================ 정수와 정수의 연산 =================");
	      System.out.println(123 + 456); // 579
	      System.out.println(123 - 23); // 100
	      System.out.println(123 * 10); // 1230
	      System.out.println(123 / 10); // 12
	      System.out.println(123 % 10); // 3

	      /* 1-2. 실수와 실수의 연산 */
	      /* 실수끼리의 연산도 수학에서 사용하는 사칙연산에 나머지를 구하는 연산(mod)을 사용할 수 있다. */
	      System.out.println("================ 실수와 실수의 연산 =================");
	      System.out.println(1.23 + 1.23); // 2.46 
	      System.out.println(1.23 - 0.23); // 1.0
	      System.out.println(1.23 * 10.0); // 12.3
	      System.out.println(1.23 / 10.0); // 0.123
	      System.out.println(1.23 % 1.0);   // 0.2299999999
	      
	      /* 1-3. 정수와 실수의 연산 */
	      /* 정수와 실수의 연산도 수학에서 사용하는 사칙 연산에 나머지를 구하는 연산(mod)을 사용할 수 있다. */
	      /* 정수와 실수 연산의 결과는 항상 실수가 나온다. */
	      System.out.println("================ 정수와 실수의 연산 =================");
	      System.out.println(123 + 0.5); // 123.5
	      System.out.println(123 - 0.5); // 122.5
	      System.out.println(123 * 0.5); // 61.5
	      System.out.println(123 / 0.5); // 246.0
	      System.out.println(123 % 0.5); // 0.0
	      
	      /* 2. 문자의 연산 */
	      /* 2-1. 문자와 문자의 연산 */
	      /* 문자끼리의 연산도 사칙연산에 mod 연산까지 가능하다. */
	      /* 지금은 계산 결과가 왜 이렇게 나왔는지 보다 연산이 사용 가능하다는 것에 집중하자!! */
	      
	      // ASCII CODE (아스키코드) 라는 2바이트 문자들을 숫자로 표현한 국제적인 표준이 있습니다.
	      // 있다는것만 알아두세요 !!
	      System.out.println("================ 문자와 문자의 연산 =================");
	      System.out.println('a' + 'b'); //195
	      System.out.println('a' - 'b'); //-1
	      System.out.println('a' * 'b'); //9506
	      System.out.println('a' / 'b'); //0
	      System.out.println('a' % 'b'); //97
	      
	      /* 2-2. 문자와 정수의 연산 */
	      /* 문자에 정수를 연산하는 것도 가능하다. */
	      /* 이 쯤 되면 문자 'a'는 숫자 97과 같다라는 것을 알 수 있다. */
	      /* 컴퓨터는 문자를 인식하지 못하고 숫자로만 인식할 수 있기 때문에, 모든 문자에 대응되는 숫자들이 매칭이 되어 있다.*/
	   
	      
	      System.out.println("================ 문자와 정수의 연산 =================");
	      System.out.println('a' + 1); // 98
	      System.out.println('a' - 1); // 96
	      System.out.println('a' * 2); // 194
	      System.out.println('a' / 2); // 48
	      System.out.println('a' % 2); // 1
	      
	      /* 2-3. 문자와 실수의 연산 */
	      /* 실수도 숫자이기 때문에 정수의 연산처럼 모든 연산이 가능하다. */
	      /* 단, 결과는 실수 형태로 나오게 된다. (아까 위에서 했던 정수와 실수의 연산 결과를 생각해보자) */
	      System.out.println("================ 문자와 실수의 연산 =================");
	      System.out.println('a' + 1.0); // 98.0
	      System.out.println('a' - 1.0); // 96.0
	      System.out.println('a' * 2.0); // 194.0
	      System.out.println('a' / 2.0); // 48.5
	      System.out.println('a' % 2.0); // 1.0
	      
	      /* 여기서 결론은 문자는 내부적으로 숫자 취급을 한다는 것이다! */
	      /* 결국 지금까지 연산은 숫자끼리의 연산을 본 것이고, 숫자(정수 혹은 실수) 형태의 값은 
수학의 사칙연산과 mod연산이 전부 가능하다. */
	      
	      /* 3. 문자열의 연산 */
	      /* 3-1. 문자열과 문자열의 연산 */
	      /* 문자열과 문자열의 '+' 연산 결과는 문자열 합치기(이어 붙이기)가 된다. */
	      /* 문자열은 '+' 연산 외에 다른 연산을 사용하지 못한다. */
	      System.out.println("================ 문자열과 문자열의 연산 =================");
	      System.out.println("hello" + "world"); //helloworld
	      //System.out.println("hello" - "world");         //에러 발생
	      //System.out.println("hello" * "world");         //에러 발생
	      //System.out.println("hello" / "world");         //에러 발생
	      //System.out.println("hello" % "world");         //에러 발생
	      
	      /* 3-2 문자열과 다른 형태의 값 연산*/
	      /* 문자열과의 연산은 '+' 연산만 가능하다. */
	      /* 연산 결과는 다른 형태의 값들도 문자열로 취급하여 문자열 이어붙이기(문자열 합치기) 결과가 나오게 된다. */
	      
	      // 문자열과 무언가를 더하면 모두 문자열로 취급이 된다 !!!
	      System.out.println("================ 문자열과 다른 형태의 값 연산 =================");
	      /* 3-2-1. 문자열과 정수의 연산 */
	      System.out.println("helloworld" + 123); // helloworld123
	      /* 3-2-2. 문자열과 실수의 연산 */
	      System.out.println("helloworld" + 123.456); // helloworld123.456
	      /* 3-2-3. 문자열과 문자의 연산 */
	      System.out.println("helloworld" + 'a'); // helloworlda
	      /* 3-2-4. 문자열과 논리값의 연산 */
	      System.out.println("helloworld" + true); // helloworldtrue
	      
	      /* 주의사항 : 숫자로 된 문자열 형태의 값은 '+' 연산의 결과가 문자열 합치기 결과가 되는 것에 주의하자! */
	      System.out.println("================ 문자열 형태의 숫자 값 '+' 연산 =================");
	      System.out.println("123" + "456"); // 123456
	      
	      /* 4. 논리값 연산 */
	      /* 4-1. 논리값과 논리값 연산 */
	      /* 논리값 끼리의 연산은 모든 연산자 사용이 불가능하다. */
	      //System.out.println(true + false);            //에러 발생
	      //System.out.println(true - false);            //에러 발생
	      //System.out.println(true * false);            //에러 발생
	      //System.out.println(true / false);            //에러 발생
	      //System.out.println(true % false);            //에러 발생
	      
	      /* 4-2. 논리값과 정수의 연산 */
	      /* 논리값과 정수의 연산은 모든 연산자 사용이 불가능하다. */
	      //System.out.println(true + 1);            //에러 발생
	      //System.out.println(true - 1);            //에러 발생
	      //System.out.println(true * 1);            //에러 발생
	      //System.out.println(true / 2);            //에러 발생
	      //System.out.println(true % 2);            //에러 발생
	      
	      /* 4-3. 논리값과 실수의 연산 */
	      /* 논리값과 실수의 연산은 모든 연산자 사용이 불가능하다. */
	      //System.out.println(true + 1.0);            //에러 발생
	      //System.out.println(true - 1.0);            //에러 발생
	      //System.out.println(true * 1.0);            //에러 발생
	      //System.out.println(true / 2.0);            //에러 발생
	      //System.out.println(true % 2.0);            //에러 발생
	      
	      /* 4-4. 논리값과 문자의 연산 */
	      /* 논리값과 문자의 연산은 모든 연산자 사용이 불가능하다. */
	      /* 이유는, 문자는 내부적으로 숫자 취급을 하기 때문에 결국 논리값과 숫자의 연산과 동일한 의미이다. */
	      //System.out.println(true + 'a');            //에러 발생
	      //System.out.println(true - 'a');            //에러 발생
	      //System.out.println(true * 'a');            //에러 발생
	      //System.out.println(true / 'a');            //에러 발생
	      //System.out.println(true % 'a');            //에러 발생
	      
	      /* 4-5. 논리값과 문자열의 연산 */
	      /* 논리값과 문자열의 연산은 '+'연산만 사용 가능하다. */
	      /* 이유는, 위에서 테스트 해 본 문자열 합치기가 되는 원리와 동일하다. */
	      System.out.println("================ 논리와 문자열의 연산 =================");
	      System.out.println(true + "a");   // truea         //문자열 합치기 됨
	      //System.out.println(true - "a");            //에러 발생
	      //System.out.println(true * "a");            //에러 발생
	      //System.out.println(true / "a");            //에러 발생
	      //System.out.println(true % "a");            //에러 발생
	      
	}

}

허허

변수의 선언

int age; // 선언만 하는 것은 의미 없음

변수의 초기화

int age;

age = 100; // 무언가 값을 담는 행위를 ‘초기화’라고 한다.

변수의 명명 규칙

실제로 개발자들에게 가장 어려운 일이 무엇이냐? 라고 물어보는 설문조사가 있었습니다

https://www.cio.com/article/220287/the-9-hardest-things-programmers-have-to-do.html

(영어 주의)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

그 중 1위가 바로 ‘변수명 작명 하기’ 였습니다

그 만큼 변수든 뭐든 이름을 처음 지을때 잘 지어놓는게 정말 정말 정말 중요한데요

그래서 개발자들은 이름 짓기에 대한 최소한의 규칙을 만들었습니다.

Camel Case ( 낙타 규칙 )

매 단어 단어 마다 첫 번째 글자를 대문자로 작성하는 방식입니다.

(단, 첫 번째 글자는 소문자 !!!)

예시)

iAmVariable

resultSum

goToCentumStudyCafe

마치 변수의 이름이 낙타 등처럼 꾸불꾸불 하죠?? 그래서 낙타 규칙이라는 이름이 붙었답니다.

✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️

Snake Case ( 뱀 규칙 )

모든 글자를 소문자로 작성하는 대신 단어 사이를 ( _ : 언더바 ) 를 붙여서 표기하는 방식입니다.

예시)

i_am_variable

eatting_launch

i_am_very_sleepy

이것도 뱀 처럼 생겻다고 해서 뱀 규칙 ~

가끔 괴짜 개발자들은 자기가 만든 변수에 자기 이름을 넣는 괴상한 행동을 하기도 한다네요

ldy_i_want_to_go_home

그러지 맙시다 !!!!!!!!!

🤧🤧🤧🤧🤧🤧

상수

/* 상수란?

  • 변수가 메모리에 변경될 값을 저장하기 위한 공간을 나타낸다면, 상수는 이와 상반되는 개념이다.
  • 변하지 않는 값을(항상 고정된 값을) 저장해두기 위한 메모리상의 공간을 상수라고 한다.
  • 상수의 사용 목적
  • 변경되지 않는 고정된 값을 저장할 목적으로 사용한다.

상수도 명명규칙이 있습니다

/* 상수의 명명 규칙 / / 상수의 명명 규칙은 변수의 명명규칙과 컴파일 에러를 발생시키는 규칙은 동일하다.

  • 단, 개발자들끼리의 암묵적인 규칙에서 일부 차이를 보인다.

⭐ 1. 모든 문자는 영문자 대문자 혹은 숫자만 사용한다.
⭐ 2. 단어와 단어 연결은 언더스코어(_)를 사용한다.

상수 명명 예시)

FINAL DOUBLE PI = 3.141592 // π (파이 , 원주율)

FINAL INT SECPERHOUR = 3600 // 1시간당 초

형 변환

. 작은 자료형에서 큰 자료형으로는 ‘자동 형 변환’ 된다.

. 큰 자료형에서 작은 자료형으로 변경 시 ‘강제 형 변환’ 이 필요하다.

형 변환도 꽤나 중요한 개념입니다.

지금은 자료형이라는 좁은 범위에서 고무 찰흙 놀이를 하고 있지만

나중에는 여러가지 자료형(자신이 직접 만드는 경우도 다수 = 클래스)을 관리할 때,

엄청나게 많은 형 변환을 해야 하기 때문에 …

위에 두 문장만 알고 넘어가십쇼 !!!!!!!!

 

 

INNER JOIN 과 OUTER JOIN - 두 개 이상의 테이블을 조인할 때, 일치하는 값이 없는 행은 조인에서 제외된다. 이것을 INNER JOIN이라고 하며, 

명시적으로 사용하지 않을 시에는 기본적으로 INNER JOIN 이다. 

 

하지만 일치하지 않은 값 또한 JOIN에 포함 시킬 수도 있다. 이것을 OUTER JOIN이라고 하며, 반드시 OUTER JOIN임을 명시해야 한다. 

 

꽤 중요한 문장들이 많습니다

 

 

 

조인 완벽 이해가능한 예제 ( 일반적인 INNER JOIN , 다중조인 )

 

-- 직급이 대리이면서 아시아 지역에 근무하는 직원조회   EMPLOYEE  JOB  LOCATION  + DEPARTMENT

-- 사번, 이름 , 직급명, 부서명, 근무지역명, 급여를 조회하세요 

-- (조회시에는 모든 컬럼에 테이블 별칭을 사용하는것이 좋다. )

 

 

 

 

 

 

실행 결과

 

 

 

 

여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터 

여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터여기부터 

여기부터여기부터여기부터여기부터여기부터여기부터여기부터 

 

서브쿼리 시작   서브쿼리 시작   서브쿼리 시작   서브쿼리 시작   서브쿼리 시작   서브쿼리 시작    

--@서브쿼리(SubQuery)

/*하나의 SQL 문안에 포함되어있는 또다른 SQL 문

알려지지 않은 조건에 근거한 값들을 검색하는 SELECT 문장을 작성하는데 유용함

메인쿼리가 서브쿼리를 포함하는 종속적인 관계

서브쿼리는 반드시 소괄호 로 묶어야함

-> (SELECT...) 형태*/

 

 

 

※ 전 직원의 급여 평균

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

--서브쿼리의 유형

--단일행 서브쿼리 : 서브쿼리의 조회 결과값이 1개 행일때

--다중행 서브쿼리 : 서브쿼리의 조회 결과값의 행이 여러개일때

--다중열 서브쿼리 : 서브쿼리의 조회 결과값의 컬럼이 여러개일때

--다중행 다중열 서브쿼리 : 조회경로가 행 수와 열수가 여러개일때

--상(호연)관서브쿼리 : 서브쿼리가 만든 결과값을 메인쿼리가 비교 연산할때 

--                  메인쿼리의 값이 변경되면 서브쿼리의 결과값도 바뀌는 서브쿼리 

--스칼라 서브쿼리 : 상관쿼리이면서 결과값이 하나인 서브쿼리 

 

--* 서브쿼리의 유형에 따라 서브쿼리 앞에 붙은 연산자가 다름 

 

 

 

--1. 단일행 서브쿼리 

-- 단일행서브쿼리앞에는 일반비교 연산자사용

-- >,<,>=,<=,=, !=,<>,^= (서브쿼리)

 

--노옹철 사원의 급여보다 많이 받는 직원의 

--사번, 이름 , 부서, 직급, 급여를 조회하세요           

 

-- 가장 적은 급여를 받는 직원의

-- 사번, 이름, 직급, 부서, 급여, 입사일을 조회하세요 

 

-- 서브쿼리는 SELECT, FROM, WHERE, HAVING, ORDER BY에도 사용 가능             

-- 부서별 급여의 합계가 가장 큰 부서의 부서명, 급여 합계를 구하세요   

 

--부서별 최고 급여를 받는 직원의 이름, 직급, 부서 , 급여 조회 
 
1 단계  ( 서브 쿼리 먼저 작성 )

 

 

 

2 단계 ( 메인 쿼리 작성 )

 

 

 

 

 

 

 

 

 

 

 

 

3 단계  :    1, 2단계 합체

다중행 서브쿼리 라서 IN 사용

메인 쿼리에서  WHERE    급여  IN   부서별 최고 급여

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-- 관리자에 해당하는 직원에 대한 정보와 관리자가 아닌 직원의 정보를 추출하여 조회 

-- 사번, 이름 , 부서명 , 직급명, '관리자' AS 구분 / '직원' AS 구분

 

 

 

 

풀이 방법 : 서브쿼리문 부터 천천히 해석 해야 한다.

 

 

 

 

1. (EMPLOYEE 에서 MANAGER_ID가 NULL이 아닌 중복 없이 MANAGER_ID 출력 )  = 서브쿼리 부분  ( AND EMP_ID IN 뒤 괄호 )

 

2. EMP_ID 와  1. (EMPLOYEE 에서 MANAGER_ID가 NULL이 아닌 중복 없이 MANAGER_ID 출력 ) 들 중 일치하는 EMP_ID 들의 사번, 이름, 부서명, 직급명, 구분을 출력하라 !!

 

 

 

 

 

 

UNION

 

 

 

 

-- ANY : 서브쿼리의 결과중에서  하나라도 참이면 참 

/*  > ANY : 최소값 보다 크면

   >= ANY : 최소값보다 크거나 같으면

   < ANY : 최대값보다 작으면

   <= ANY : 최대값보다 작거나 같으면

   = ANY : IN과 같은 효과

   != ANY : NOT IN과 같은 효과 */

 

 

 

--ALL : 서브 쿼리의 결과중에서 모두 참이면 참 (ANY 와는 약간 다른 개념 ) 

/*  > ALL : 최대값 보다 크면

   >= ALL : 최대값보다 크거나 같으면

   < ALL : 최소값보다 작으면

   <= ALL : 최소값보다 작거나 같으면

   = ALL : SUBSELECT의 결과가 1건이면 상관없지만 여러건이면 오류가 발생

   != ALL : 위와 마찬가지로 결과가 여러건이면 오류 발생

*/

 

--EXISTS : 서브쿼리의 결과 중에서 만족하는 값이 하나라도 존재하면 참

-- 참, 거짓 서브쿼리안에 값이 있는지 없는지 

-- 서브쿼리 결과가 참이면 메인쿼리를 실행, 서브쿼리 결과가 거짓이면 메인쿼리를 실행하지않는다.

 

 

-- 다중열 서브쿼리 

--> 서브쿼리의 조회결과 컬럼의 개수가 여러개일때 (다중행하고는 다르게 결과값이 컬럼이 여러개!!)

 

 

-- 퇴사한 여직원과 같은부서, 같은 직급에 해당하는 사원의 이름 , 직급코드 ,부서코드, 입사일을 조회              

 

 

 

SUBSTR   EMP_NO    = 2   주민번호 뒷자리 2 (여직원) 인거 비교

 

 

 

 

 

 

-- 상[호연]관 서브쿼리

-- 일반적으로는 서브쿼리가 만든 결과값을 메인쿼리가 비교 연산

-- 메인쿼리가 사용하는 테이블의 값을 서브쿼리가 이용해서 결과를 만듬

-- 메인쿼리의 테이블 값이 변경되면, 서브쿼리의 결과값도 바뀌게 됨

 

--메인쿼리에 있는것을 서브쿼리에서 가져다쓰면 상관 서브쿼리

--서브쿼리가 독단적으로 사용이 되면 일반서브쿼리 

 

 

 

 

 

 

 

-- 스칼라 서브쿼리 = 단일행 서브쿼리 + 상관쿼리(-> 상관쿼리 이면서 결과값이 1개인 서브쿼리)

-- ( 행이 1개만 필요로하는 ) SELECT절, WHERE절, ORDER BY절 사용 가능

 

 

-- WHERE절에서 스칼라 서브쿼리 이용

 

-- 동일 직급의 급여 평균보다 급여를 많이 받고 있는 직원의

-- 사번, 직급코드, 급여를 조회하세요

 

-- 동일 직급의 급여 평균

 

 

 

 

-- 동일 직급의 급여 평균보다 급여를 많이 받고 있는 직원의

-- 사번, 직급코드, 급여를 조회하세요

 

 

 

 

 

 

 

 

 

--SELECT 절에서 스칼라 서브쿼리 이용 

-- 모든 사원의 사번, 이름, 관리자 사번, 관리자명 조회

 

 

 

-- ORDER BY 절에서 스칼라 서브쿼리 이용 

 

-- 모든 직원의 사번, 이름 , 소속 부서코드 조회

-- 단 부서명 내림차순 정렬 

 

 

 

 

 

 

 

-- 서브쿼리의 사용 위치 : 

-- SELECT절, FROM절, WHERE절, HAVING절, GROUP BY절, ORDER BY절

-- DML 구문 : INSERT문, UPDATE문

-- DDL 구문 : CREATE TABLE문, CREATE VIEW문

 

-- FROM 절에서 서브쿼리를 사용할 수 있다 : 테이블 대신에 사용

-- 인라인 뷰(INLINE VIEW)라고 함

-- : 서브쿼리가 만든 결과집합(RESULT SET)에 대한 출력 화면

 

 

 

--JOB 코드별 월급 평균(TRUNC(AVG(E2.SALARY), -5))을 구하고 

--월급이 이와 일치하는 사원정보 이름, 직급명,월급 구하기

 

 

 

 

 

 

 

-- 부서명이 인사관리부인 사원명  , 부서명, 직급이름 을 구하시오 (인라인뷰사용) 

 

 

 

 

 

 

 

 

/*우선 TOP-N 분석에 대해 알아보자

# TOP-N 분석이란?

   TOP-N 질의는 columns에서 가장 큰 n개의 값 또는 가장 작은 n개의 값을 요청할 때

   사용됨

   예) 가장 적게 팔린 제품 10가지는? 또는 회사에서 가장 소득이 많은 사람 3명은?

*/

-- 인라인뷰를 활용한 TOP-N분석

-- ORDER BY 한 결과에 ROWNUM을 붙임

-- ROWNUM은 행 번호를 의미함 (ROWNUM 은 출력되는 SELECT 된 행마다 자동으로 순차적인 번호를 붙여주는 값)

 

 

--ex) --TOP-N 분석 : 회사에서 연봉이 가장 높은 사람 5명은? 

 

 

 

인라인 뷰로 먼저 정렬한 뒤 ROWNUM을 붙인다. 

인라인 뷰를 안 썼다면 ROWNUM이 붙여진 뒤 정렬을 하기 때문에 뒤죽박죽이 되었을 것

 

 

-- 급여 평균 3위안에드는 부서의 부서코드와 부서명 , 평균급여를 조회하세요 (인라인뷰를 활용한 TOP-N분석 사용 ) 

 

 

 

 

위 문제 인라인 뷰만 따로 

 

 

 

 

 

-- RANK() OVER(정렬기준) / DENSE_RANK() OVER(정렬기준)

--    보다 쉽게 순위 매기는 함수

-- RANK() OVER : 동일한 순위 이후의 등수를 동일한 인원 수 만큼 건너뛰고 순위 계산

--               EX) 공동 1위가 2명이면 다음 순위는 2위가 아니라 3위

-- DENSE_RANK() OVER : 동일한 순위 이후의 등수를 무조건 1씩 증가시키는

--              EX) 공동 1위가 2명이더라도 다음 순위는 2위

 

 

-- 직원 테이블에서 보너스 포함한 연봉이 높은 5명의 RANK() OVER

-- 사번, 이름, 부서명, 직급명, 입사일을 조회하세요

 

 

 

 

 

 

-- WITH 이름 AS (쿼리문)

-- 서브쿼리에 이름을 붙여주고 사용시 이름을 사용하게 됨

-- 인라인뷰로 사용될 서브쿼리에서 이용됨

-- 같은 서브쿼리가 여러번 사용될 경우 중복 작성을 줄일 수 있다.

 

 

 

 

 

WITH << 꼭 함수 처럼 생겼다 

 

 

 

-- 부서별 급여 합계가 전체 급여의 총 합의 20%보다 많은

-- 부서의 부서명과, 부서별 급여 합계 조회

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

/*@ 데이터 딕셔너리 (Data Dictionary)

-> 자원을 효율적으로 관리하기 위한 다양한 정보를 저장하는 시스템 테이블

-> 데이터 딕셔너리는 사용자가 테이블을 생성하거나 사용자를 변경하는 등의

작업을 할 때 데이터베이스 서버에 의해 자동으로 갱신되는 테이블

-> 사용자는 데이터 딕셔너리의 내용을 직접 수정하거나 삭제할 수 없음

-> 데이터 딕셔너리 안에는 중요한 정보가 많이 있기 때문에 사용자는 이를 활용하기 위해

데이터 딕셔너리 뷰를 사용하게 됨

   

   ※ 뷰(VIEW)는 뒤에 배우겠지만 미리 말씀 드리면 원본 테이블을 

   커스터마이징해서 보여주는 원본테이블의 가상의 TABLE 객체

 

 

@ 3개의 데이터 딕셔너리 뷰 (Data Dictionary View)

 

 

1. DBA_XXXX : 데이터 베이스 관리자만 접근이 가능한 객체 등의 정보 조회

   (DBA는 모든 접근이 가능하므로 결국 디비에 있는 모든 객체에 대한 조회가 됨) 

 

2. ALL_XXXX : 자신의 계정이 소유하거나 권한을 부여받은 객체 등에 관한 정보 조회

 

3. USER_XXXX : 자신의 계정이 소유한 객체 등에 관한 정보 조회

 

*/

 

 

 

 

 

SQL에서 정해진 예약어 !!!  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

FROM절 연산에서 ROWNUM 이 먼저 정해지고  그다음 ORDER BY 가 수행되기 때문에 ROWNUM 순으로 정렬이 되어있지 않다 ( 4번 5번)

 

 

 

 

 

 

 

이렇게 수정해야 한다

FROM 에도  서브쿼리가 적용이 되는군요 !!

SELECT

리터럴 ( 큰따옴표 : 컬럼에 별칭 , 작은 따옴표 : 데이터로 사용가능)

DISTINCT

 

 

비교 연산자

연산자         설명

   =         같다

   >,<         크다/작다

   >=,=<         크거나 같다/작거나 같다

   <>,!=,^=      같지 않다

   BETWEEN AND      특정 범위에 포함되는지 비교

 

   LIKE / NOT LIKE      문자 패턴 비교

 

 

LIKE 연산자: 문자 패턴이 일치하는 값을 조회 할때 사용 

--컬럼명 LIKE '문자패턴'

--문자패턴  : '글자%'(글자로 시작하는 값)

--           '%글자%'(글자가 포함된 값)

--           '%글자'(글자로 끝나는 값)

 

'%' 와 '_' 와일드 카드 로 사용할수있다 

와일드 카드 : 아무거나 대체해서 사용할수 있는 것 

_: 한문자

%:모든것

 

 

--EMPLOYEE 테이블에서 _앞글자가 3자리인 이메일 주소를 가진 사원의

--사번, 이름, 이메일 주소를 조회 

--ESCAPE 

--LIKE '%[문자][실제문자로인식시킬문자]%' ESCAPE '[문자]

-- _ << 이 키워드를 문자로 인식시키기 위해서 임의로 특수문자 (#)을 지정했다. 

-- # 뒤에있는 키워드는 글자로 처리해주세요~ 라는 뜻 .

SELECT EMP_ID, EMP_NAME, EMAIL

FROM EMPLOYEE

WHERE EMAIL LIKE '___#_%' ESCAPE '#';

 

 

   IS NULL / IS NOT NULL   NULL 여부 비교

   IN / NOT IN      비교 값 목록에 포함/미포함 되는지 여부 비교

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

함수를 사용할수 있는 위치 : SELECT 절, WHERE 절, GROUP BY 절, HAVING절, ORDER BY 절 

 

INSTR =  문자열 속에서 문자/문자열 찾기        리턴 값 = 좌표 (숫자)

 

INSTR('문자열' | 컬럼명,'문자', 찾을 위치의 시작값 ,[빈도])

파라미터         설명

STRING         문자 타입 컬럼 또는 문자열

STR         찾으려는 문자(열)

POSITION      찾을 위치 시작 값 (기본값 1)

       (양수)  POSITION > 0 : STRING의 시작부터 끝 방향으로 찾음

       (음수)  POSITION < 0 : STRING의 끝부터 시작 방향으로 찾음

OCCURRENCE      검색된 STR의 순번(기본값 1), 음수 사용 불가

 

 

 

 

 

뒤에서 부터 'o' 를 찾는다. (마지막 파라미터 기본값이 1이므로 제일 처음 나오는 'o' 의 인덱스를 리턴 한다. )

INSTR(EMAIL, 'O', -1 , 1 ) 인셈 

 

뒤에서 찾긴 하지만 인덱스를 세는건 앞에서부터 센다.

 

 

 

 

 

 

 

앞에서 부터 두 번째로 나오는 'o' 의 인덱스를 리턴 한다.

 

 

 

 

 

 

LTRIM , RTRIM , TRIM

 

 

 

 

 

 

 

 

★ 

SUBSTR 

 

--SUBSTR: 컬럼이나 문자열에서 지정한 위치로 부터 지정한 문자열을 잘라서 리턴하는 함수  

리턴 값 : 문자열

--SUBSTR('문자열', 시작 위치, 자를 길이)

 

 

 

출력 결과

 

THEMONEY

 

THE

 

 

 

 

--LOWER/UPPER/INITCAP : 대소문자 변경해주는 함수

--LOWER(문자열| 컬럼) : 소문자로 변경해주는 함수

 

 

--CONCAT : 문자열 혹은 컬럼두개를 입력받아 하나로 합친후 리턴 

 

 

 

-- REPLACE : 컬럼혹은 문자열을 입력받아 변경하고자 하는 문자열을 변경 

 

 

 

 

 

-- 숫자 처리 함수 : ABS, MOD, ROUND, FLOOR, TRUNC , CEIL

-- ABS(숫자 | 숫자 로 된 컬럼명 ) :절대값 구하는 함수

 

-- MOD(숫자 | 숫자로된 컬럼명, 숫자 | 숫자로된컬럼명) : 두 수를 나누어서 나머지를 구하는 함수 

-- 첫 인자는 나누어지는 수, 두 번째 인자는 나눌 수

 

-- ROUND( 숫자 | 숫자로된 컬럼명, [위치]) : 반올림해서 리턴하는 함수

-- 소수점의 첫 번째 자리가  0번 인덱스다.   -1 은 정수 첫 번째 자리이다.

 

-- FLOOR(숫자 | 숫자로된 컬럼명)

--: 내림처리 하는 함수 (인자로 전달받은 숫자 혹은 컬럼의 소수점 자리수를 버리는 함수)

 

 

-- TRUNC(숫자 | 숫자로된 컬럼명 , [위치])

--: 내림처리 (절삭) 함수(인자로 전달받은 숫자 혹은 컬럼의 지정한 위치 이후의 소수점 자리수를 버리는 함수 )

 

 

-- CEIL (숫자 | 숫자로된 컬럼명): 올림처리함수(소수점 기준으로 올림처리) 

 

 

 

-- 날짜 함수 : SYSDATE, MONTHS_BETWEEN, ADD_MONTH

--            , NEXT_DAY, LAST_DAY, EXTRACT

 

-- SYSDATE : 시스템에 저장되어있는 날짜를 반환하는함수 

-- MONTHS_BETWEEN(날짜, 날짜) : 두날짜의 개월수 차이를 숫자로 리턴하는 함수 

-- ADD_MONTHS(날짜, 숫자): 날짜에 숫자만큼 개월수를 더해서 리턴 

 

-- NEXT_DAY(기준날짜, 요일(문자|숫자)) : 

-- 기준날짜에서 구하려는 요일에 가장가까운 날짜리턴

 

5 : 목요일

SYSDATE     NEXT_DAY

22/07/26      22/07/28

 

 

--LAST_DAY(날짜 ) : 해당월의 마지막 날짜를 구하여 리턴

 

LAST_DAY(SYSDATE)     LAST_DAY(200910)

22/07/31                        20/09/30

 

 

 

 

-- EXTRACT : 년, 월,일 정보를 추출하여 리턴 하는 함수 

-- EXTRACT(YEAR FROM 날짜) : 년도만 추출

-- EXTRACT(MONTH FROM 날짜) : 월만추출

-- EXTRACT(DAY FROM 날짜) : 날짜만 추출

 

 

 

출력 결과

 

 

 

 

--형변환 함수 

--TO_CHAR(날짜, [포멧]) : 날짜형데이터를 문자형 데이터로 변환

--TO_CHAR(숫자, [포멧]) : 숫자형데이터를 문자형 데이터로 변환 

 

 

--Format       예시         설명

--,(comma)   9,999      콤마 형식으로 변환

--.(period)   99.99      소수점 형식으로 변환

--0      09999      왼쪽에 0을 삽입

--$      $9999      $ 통화로 표시

--L      L9999      Local 통화로 표시(한국의 경우 \)

--9:자릿수를 나타내며 ,자릿수가 많지않아도 0으로채우지않는다

--0:자릿수를나타내며, 자릿수가 많지 않을 경우 0으로 채워준다.

--EEEE 과학 지수 표기법 

 

 

 

 

 

 

 

 

 

-- RR과 YY의 차이

-- RR은 두자리 년도를 네자리로 바꿀 때

-- 바꿀 년도가 50년 미만 2000년을 적용, 

-- 50년 이상이면 1900년 적용

 

-- 년도 바꿀 때(TO_DATE 사용시) Y를 적용하면

-- 현재 세기(2000년)가 적용된다.

-- R은 50년 이상이면 이전 세기(1900년),

-- 50년 미만이면 현재 세기(2000년) 적용

-- * TO_CHAR 를 이용하여 뽑아오는것은 동일

 

 

 

 출력 결과

 

YY

 

 

RR

 

 

 

-- 오늘 날짜에서 일만 출력  

 

 

 

 

 

 

 

 

--NULL처리 함수

--NVL(컬럼 명, 컬럼 값이 NULL일 때 바꿀 값)

 

--NVL2(컬럼 명, 바꿀 값1, 바꿀 값2)

-- 해당 컬럼이 값이 있으면 바꿀 값 1로 변경

-- 해당 컬럼이 값이 NULL일 경우 바꿀 값 2로 변경 

 

 

-- 선택함수 

-- DECODE(계산식 | 컬럼명, 조건값1, 선택값1, 조건값2, 선택값2...,[DEFAULT])

 

 

주민등록번호 8번째 자리로부터 1글자를 잘라내서 (뒷자리 첫 번째 자리) 1이면 남자, 2면 여자를 리턴

 

 

 

 

 

조건값 - 결과값   대응되는거 없는 맨 마지막 인자는 디폴트값이 된다

 

 

 

 

 

-- CASE문

/* CASE

        WHEN 조건식 THEN 결과값

        WHEN 조건식 THEN 결과값

    ELSE 결과값

    END

*/

 

 

 

 

 

 

 

 

--그룹함수 : SUM, AVG, MAX, MIN, COUNT         

 

-- SUM(숫자가 기록된 컬럼명 ): 합계를 구하여 리턴

-- AVG(숫자가 기록된 컬럼명): 평균을 구하여 리턴 

-- MIN(컬럼명): 컬럼에서 가장 작은 값 리턴 (자료형 ANY TYPE) 

-- MAX(컬럼명): 컬럼에서 가장 큰값 리턴 (자료형 ANY TYPE) 

 

 

--COUNT(* |컬럼명 ): 행의 갯수를 리턴

--COUNT([DISTINCT] 컬러명):중복을 제거한 행 갯수 리턴 

--COUNT(*) :NULL 을 포함한 전체 갯수 리턴 

--COUNT(컬럼명): NULL 을 제외한 실제값이 기록된 행의 갯수 리턴

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

03_ ORDER BY , HAVING

 

/*ORDER BY  절: SELECT 한 컬럼을 가지고 정렬을 할때 사용함

ORDER BY 컬럼명| 컬럼별칭 | 컬럼나열 순번 [ASC] | DESC 

ORDER BY 컬럼명 정렬방식, 컬럼명 정렬방식, 컬럼명 정렬방식.....

첫번째 기준으로 하는 컬럼에 대해서 정렬하고, 같은 값들에대해 두번째 기준으로 하는 컬럼에 대해 다시 정렬, 

SELECT 구문 맨마지막에 위치하고, 실행순서도 맨 마지막에 실행됨.*/

 

 

/*

 5 : SELECT 컬럼명 AS 별칭, 계산식, 함수식..

 1 : FROM 참조할 테이블

 2 : WHERE 컬럼명 | 함수식 비교연산자 비교값 (조건)

 3 : GROUP BY 그룹으로 묶을 컬럼명

 4 : HAVING 그룹함수식 비교연산자 비교값 ( 그룹핑된 대상에 대한 조건 )

 6 : ORDER BY 컬럼명| 컬럼별칭 | 컬럼나열 순번 [ASC] | DESC  |[NULLS FIRST | LAST]

 */

 

 

 

--GROUP BY 절 : 같은 값들이 여러개 기록된 컬럼을 가지고 하나의 그룹으로 묶음 

--GROUP BY 컬럼명 | 함수식 ....

--GROUP BY 에 명시된 값 이 SELECT 절에 명시되어있어야한다. 

 

 

--HAVING 절 : 그룹 함수로 구해올 그룹에 대해 조건을 설정할때 사용

--HAVING 컬럼명 | 함수식 | 비교연산자 |비교값

 

 

 

-- EMPLOYEE테이블에서  부서별 그룹의 급여 합계중 9백만원을 초과하는 부서코드와 급여합계를 조회 

 

 

 

 

GROUP BY 만 했을 때

 

 

 

 

 

HAVING 으로 GROUP 에 대한 조건 설정을 했을 때

 

 

 

 

 

--집계함수 

 

--ROLLUP 함수 : 그룹별로 중간 집계 처리를 하는 함수 

--CUBE 함수 : 그룹별 산출한 결과를 집계하는 함수이다.  

--GROUP BY 절에서만 사용 

-- 그룹별로 묶여진 값에 중간집계와 총집계를 구할때 사용

-- 그룹별로 계산된 값에대한 총집계가 자동으로 추가된다. 

-- 인자로 전달한 그룹중에서 가장 먼저 지정한 그룹(컬럼)별 합계와 총합계 

 

 

 

 

 --GROUPING  함수 : ROLLUP이나 CUBE 에 의한 산출물이 

-- 인자로 전달받은 컬럼집합의 산출물이면 0

-- 아니면 1을 반환하는 함수

 

 

 

 

 

 

 

 

 

 

 

--@SET SPERATION(집합연산)

-- 두개이상의 테이블에서 조인을 사용하지않고 연관된 데이터를 조회하는 방법

-- 여러개의 질의 결과를 연결하여 하나로 결합하는 방식 

-- 각테이블의 조회결과를 하나의 테이블에 합쳐서 반환함 

 

-- 조건 : SELECT 절의 "컬럼수가 동일"해야함 ★★★★★★

--       SELECT 절의 동일 위치에 존재하는 "컬럼의 데이터 타입이 상호호환"가능해야함.

 

-- UNION, UNION ALL, INTERSECT, MINUS

 

-- UNION : 여러개의 쿼리결과를 하나로 합치는 연산자이다. 

--         중복된 영역의 제외하여 하나로 합친다.

 

 

-- UNION ALL : 여러개의 쿼리결과를 하나로 합치는 연산자

            -- UNION 과의 차이점은 중복영역을 모두 포함시킨다.

 

 

--INTERSECT : 여러개의 SELECT 한 결과에서 공통된 부분만 결과로 추출

-- 수학에서 교집합과 비슷 

 

 

--MINUS : 선행 SELECT 결과에서 다음 SELECT 결과와 겹치는 부분을 제외한 나머지 부분만추출

-- 수학에서 차집합과 비슷 하다

'더존 노션 필기 옮기기 > SQL' 카테고리의 다른 글

MySQL 튜토리얼  (1) 2022.12.07
Oracle EMPLOYEE DDL DML  (0) 2022.11.22
SQL 3일차 오라클 DB3 조인, 서브쿼리  (0) 2022.08.30
SQL 1일차 오라클DB 설치 및 설정  (0) 2022.08.30

1. https://www.oracle.com/database/technologies/xe-prior-release-downloads.html

2. Products – Oracle Database – Oracle Database 11g Express Edition 다운로드 

3. 설치 및 관리자 계정 암호 설정 

4. DB 접속확인 및 SQLplus 실행 

5. 관리자 계정 로그인 

 

안되면 ORACLE_HOME , PATH 환경 변수 설정

 

관리자 계정 : SYSTEM

비밀번호 : 다운로드 할 때 설정한 비밀번호 ( 강의실에는 ORACLE로 설정해 둠 )

 

 

 

SQL Developer 설치

1. www.oracle.com 접속 

2. Products – Oracle Database – SQL Developer 다운로드 

3. 압축 해제 후 바로 실행 

 

 

- CREATE USER GREEDY IDENTIFIED BY GREEDY;   -- 아이디 / 비밀번호

- GRANT RESOURCE, CONNECT TO GREEDY;   

 

- CREATE USER EMPLOYEE IDENTIFIED BY EMPLOYEE;

- GRANT RESOURCE, CONNECT TO EMPLOYEE;

 

 

EMPLOYEE.sql

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

DROP TABLE EMPLOYEE;

DROP TABLE DEPARTMENT;

DROP TABLE JOB;

DROP TABLE LOCATION;

DROP TABLE NATIONAL;

DROP TABLE SAL_GRADE;

 

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

--  DDL for Table DEPARTMENT

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

 

  CREATE TABLE "EMPLOYEE"."DEPARTMENT" 

   ( "DEPT_ID" CHAR(2 BYTE), 

"DEPT_TITLE" VARCHAR2(35 BYTE), 

"LOCATION_ID" CHAR(2 BYTE)

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."DEPT_ID" IS '부서코드';

   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."DEPT_TITLE" IS '부서명';

   COMMENT ON COLUMN "EMPLOYEE"."DEPARTMENT"."LOCATION_ID" IS '지역코드';

   COMMENT ON TABLE "EMPLOYEE"."DEPARTMENT"  IS '부서';

REM INSERTING into EMPLOYEE.DEPARTMENT

SET DEFINE OFF;

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D1','인사관리부','L1');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D2','회계관리부','L1');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D3','마케팅부','L1');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D4','국내영업부','L1');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D5','해외영업1부','L2');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D6','해외영업2부','L3');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D7','해외영업3부','L4');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D8','기술지원부','L5');

Insert into EMPLOYEE.DEPARTMENT (DEPT_ID,DEPT_TITLE,LOCATION_ID) values ('D9','총무부','L1');

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

--  DDL for Index 엔터티1_PK2

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK2" ON "EMPLOYEE"."DEPARTMENT" ("DEPT_ID") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table DEPARTMENT

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

 

  ALTER TABLE "EMPLOYEE"."DEPARTMENT" ADD CONSTRAINT "DEPARTMENT_PK" PRIMARY KEY ("DEPT_ID")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."DEPARTMENT" MODIFY ("LOCATION_ID" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."DEPARTMENT" MODIFY ("DEPT_ID" NOT NULL ENABLE);

 

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

--  DDL for Table EMPLOYEE

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

 

  CREATE TABLE "EMPLOYEE"."EMPLOYEE" 

   ( "EMP_ID" VARCHAR2(3 BYTE), 

"EMP_NAME" VARCHAR2(20 BYTE), 

"EMP_NO" CHAR(14 BYTE), 

"EMAIL" VARCHAR2(25 BYTE), 

"PHONE" VARCHAR2(12 BYTE), 

"DEPT_CODE" CHAR(2 BYTE), 

"JOB_CODE" CHAR(2 BYTE), 

"SAL_LEVEL" CHAR(2 BYTE), 

"SALARY" NUMBER, 

"BONUS" NUMBER, 

"MANAGER_ID" VARCHAR2(3 BYTE), 

"HIRE_DATE" DATE, 

"ENT_DATE" DATE, 

"ENT_YN" CHAR(1 BYTE) DEFAULT 'N'

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_ID" IS '사원번호';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_NAME" IS '직원명';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMP_NO" IS '주민등록번호';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."EMAIL" IS '이메일';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."PHONE" IS '전화번호';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."DEPT_CODE" IS '부서코드';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."JOB_CODE" IS '직급코드';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."SAL_LEVEL" IS '급여등급';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."SALARY" IS '급여';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."BONUS" IS '보너스율';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."MANAGER_ID" IS '관리자사번';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."HIRE_DATE" IS '입사일';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."ENT_DATE" IS '퇴사일';

   COMMENT ON COLUMN "EMPLOYEE"."EMPLOYEE"."ENT_YN" IS '재직여부';

   COMMENT ON TABLE "EMPLOYEE"."EMPLOYEE"  IS '사원';

REM INSERTING into EMPLOYEE.EMPLOYEE

SET DEFINE OFF;

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('200','선동일','621235-1985634','sun_di@uni.or.kr','01099546325','D9','J1','S1',8000000,0.3,null,to_date('90/02/06','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('201','송종기','631156-1548654','song_jk@uni.or.kr','01045686656','D9','J2','S1',6000000,null,'200',to_date('01/09/01','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('202','노옹철','861015-1356452','no_hc@uni.or.kr','01066656263','D9','J2','S4',3700000,null,'201',to_date('01/01/01','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('203','송은희','631010-2653546','song_eh@uni.or.kr','01077607879','D6','J4','S5',2800000,null,'204',to_date('96/05/03','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('204','유재식','660508-1342154','yoo_js@uni.or.kr','01099999129','D6','J3','S4',3400000,0.2,'200',to_date('00/12/29','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('205','정중하','770102-1357951','jung_jh@uni.or.kr','01036654875','D6','J3','S4',3900000,null,'204',to_date('99/09/09','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('206','박나라','630709-2054321','pack_nr@uni.or.kr','01096935222','D5','J7','S6',1800000,null,'207',to_date('08/04/02','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('207','하이유','690402-2040612','ha_iy@uni.or.kr','01036654488','D5','J5','S5',2200000,0.1,'200',to_date('94/07/07','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('208','김해술','870927-1313564','kim_hs@uni.or.kr','01078634444','D5','J5','S5',2500000,null,'207',to_date('04/04/30','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('209','심봉선','750206-1325546','sim_bs@uni.or.kr','0113654485','D5','J3','S4',3500000,0.15,'207',to_date('11/11/11','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('210','윤은해','650505-2356985','youn_eh@uni.or.kr','0179964233','D5','J7','S5',2000000,null,'207',to_date('01/02/03','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('211','전형돈','830807-1121321','jun_hd@uni.or.kr','01044432222','D8','J6','S5',2000000,null,'200',to_date('12/12/12','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('212','장쯔위','780923-2234542','jang_zw@uni.or.kr','01066682224','D8','J6','S5',2550000,0.25,'211',to_date('15/06/17','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('213','하동운','621111-1785463','ha_dh@uni.or.kr','01158456632',null,'J6','S5',2320000,0.1,null,to_date('99/12/31','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('214','방명수','856795-1313513','bang_ms@uni.or.kr','01074127545','D1','J7','S6',1380000,null,'200',to_date('10/04/04','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('215','대북혼','881130-1050911','dae_bh@uni.or.kr','01088808584','D5','J5','S4',3760000,null,null,to_date('17/06/19','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('216','차태연','770808-1364897','cha_ty@uni.or.kr','01064643212','D1','J6','S5',2780000,0.2,'214',to_date('13/03/01','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('217','전지연','770808-2665412','jun_jy@uni.or.kr','01033624442','D1','J6','S4',3660000,0.3,'214',to_date('07/03/20','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('218','이오리','870427-2232123','loo_or@uni.or.kr','01022306545',null,'J7','S5',2890000,null,null,to_date('16/11/28','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('219','임시환','660712-1212123','im_sw@uni.or.kr',null,'D2','J4','S6',1550000,null,null,to_date('99/09/09','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('220','이중석','770823-1113111','lee_js@uni.or.kr',null,'D2','J4','S5',2490000,null,null,to_date('14/09/18','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('221','유하진','800808-1123341','yoo_hj@uni.or.kr',null,'D2','J4','S5',2480000,null,null,to_date('94/01/20','RR/MM/DD'),null,'N');

Insert into EMPLOYEE.EMPLOYEE (EMP_ID,EMP_NAME,EMP_NO,EMAIL,PHONE,DEPT_CODE,JOB_CODE,SAL_LEVEL,SALARY,BONUS,MANAGER_ID,HIRE_DATE,ENT_DATE,ENT_YN) values ('222','이태림','760918-2854697','lee_tr@uni.or.kr','01033000002','D8','J6','S5',2436240,0.35,'100',to_date('97/09/12','RR/MM/DD'),to_date('17/09/12','RR/MM/DD'),'Y');

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

--  DDL for Index 엔터티1_PK

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK" ON "EMPLOYEE"."EMPLOYEE" ("EMP_ID") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table EMPLOYEE

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

 

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" ADD CONSTRAINT "EMPLOYEE_PK" PRIMARY KEY ("EMP_ID")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("SAL_LEVEL" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("JOB_CODE" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_NO" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_NAME" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."EMPLOYEE" MODIFY ("EMP_ID" NOT NULL ENABLE);

 

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

--  DDL for Table JOB

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

 

  CREATE TABLE "EMPLOYEE"."JOB" 

   ( "JOB_CODE" CHAR(2 BYTE), 

"JOB_NAME" VARCHAR2(35 BYTE)

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."JOB"."JOB_CODE" IS '직급코드';

   COMMENT ON COLUMN "EMPLOYEE"."JOB"."JOB_NAME" IS '직급명';

   COMMENT ON TABLE "EMPLOYEE"."JOB"  IS '직급';

REM INSERTING into EMPLOYEE.JOB

SET DEFINE OFF;

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J1','대표');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J2','부사장');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J3','부장');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J4','차장');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J5','과장');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J6','대리');

Insert into EMPLOYEE.JOB (JOB_CODE,JOB_NAME) values ('J7','사원');

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

--  DDL for Index 엔터티1_PK1

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK1" ON "EMPLOYEE"."JOB" ("JOB_CODE") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table JOB

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

 

  ALTER TABLE "EMPLOYEE"."JOB" ADD CONSTRAINT "JOB_PK" PRIMARY KEY ("JOB_CODE")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."JOB" MODIFY ("JOB_CODE" NOT NULL ENABLE);

 

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

--  DDL for Table LOCATION

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

 

  CREATE TABLE "EMPLOYEE"."LOCATION" 

   ( "LOCAL_CODE" CHAR(2 BYTE), 

"NATIONAL_CODE" CHAR(2 BYTE), 

"LOCAL_NAME" VARCHAR2(40 BYTE)

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."LOCAL_CODE" IS '지역코드';

   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."NATIONAL_CODE" IS '국가코드';

   COMMENT ON COLUMN "EMPLOYEE"."LOCATION"."LOCAL_NAME" IS '지역명';

   COMMENT ON TABLE "EMPLOYEE"."LOCATION"  IS '지역';

REM INSERTING into EMPLOYEE.LOCATION

SET DEFINE OFF;

Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L1','KO','ASIA1');

Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L2','JP','ASIA2');

Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L3','CH','ASIA3');

Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L4','US','AMERICA');

Insert into EMPLOYEE.LOCATION (LOCAL_CODE,NATIONAL_CODE,LOCAL_NAME) values ('L5','RU','EU');

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

--  DDL for Index 엔터티1_PK3

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK3" ON "EMPLOYEE"."LOCATION" ("LOCAL_CODE") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table LOCATION

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

 

  ALTER TABLE "EMPLOYEE"."LOCATION" ADD CONSTRAINT "LOCATION_PK" PRIMARY KEY ("LOCAL_CODE")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."LOCATION" MODIFY ("NATIONAL_CODE" NOT NULL ENABLE);

  ALTER TABLE "EMPLOYEE"."LOCATION" MODIFY ("LOCAL_CODE" NOT NULL ENABLE);

 

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

--  DDL for Table NATIONAL

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

 

  CREATE TABLE "EMPLOYEE"."NATIONAL" 

   ( "NATIONAL_CODE" CHAR(2 BYTE), 

"NATIONAL_NAME" VARCHAR2(35 BYTE)

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."NATIONAL"."NATIONAL_CODE" IS '국가코드';

   COMMENT ON COLUMN "EMPLOYEE"."NATIONAL"."NATIONAL_NAME" IS '국가명';

   COMMENT ON TABLE "EMPLOYEE"."NATIONAL"  IS '국가';

REM INSERTING into EMPLOYEE.NATIONAL

SET DEFINE OFF;

Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('KO','한국');

Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('JP','일본');

Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('CH','중국');

Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('US','미국');

Insert into EMPLOYEE.NATIONAL (NATIONAL_CODE,NATIONAL_NAME) values ('RU','러시아');

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

--  DDL for Index 엔터티1_PK4

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티1_PK4" ON "EMPLOYEE"."NATIONAL" ("NATIONAL_CODE") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table NATIONAL

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

 

  ALTER TABLE "EMPLOYEE"."NATIONAL" ADD CONSTRAINT "NATIONAL_PK" PRIMARY KEY ("NATIONAL_CODE")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."NATIONAL" MODIFY ("NATIONAL_CODE" NOT NULL ENABLE);

 

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

--  DDL for Table SAL_GRADE

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

 

  CREATE TABLE "EMPLOYEE"."SAL_GRADE" 

   ( "SAL_LEVEL" CHAR(2 BYTE), 

"MIN_SAL" NUMBER, 

"MAX_SAL" NUMBER

   ) SEGMENT CREATION IMMEDIATE 

  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

 

   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."SAL_LEVEL" IS '급여등급';

   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."MIN_SAL" IS '최소급여';

   COMMENT ON COLUMN "EMPLOYEE"."SAL_GRADE"."MAX_SAL" IS '최대급여';

   COMMENT ON TABLE "EMPLOYEE"."SAL_GRADE"  IS '급여등급';

REM INSERTING into EMPLOYEE.SAL_GRADE

SET DEFINE OFF;

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S1',6000000,10000000);

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S2',5000000,5999999);

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S3',4000000,4999999);

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S4',3000000,3999999);

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S5',2000000,2999999);

Insert into EMPLOYEE.SAL_GRADE (SAL_LEVEL,MIN_SAL,MAX_SAL) values ('S6',1000000,1999999);

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

--  DDL for Index 엔터티2_PK

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

 

  CREATE UNIQUE INDEX "EMPLOYEE"."엔터티2_PK" ON "EMPLOYEE"."SAL_GRADE" ("SAL_LEVEL") 

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM" ;

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

--  Constraints for Table SAL_GRADE

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

 

  ALTER TABLE "EMPLOYEE"."SAL_GRADE" ADD CONSTRAINT "엔터티2_PK" PRIMARY KEY ("SAL_LEVEL")

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE "SYSTEM"  ENABLE;

  ALTER TABLE "EMPLOYEE"."SAL_GRADE" MODIFY ("SAL_LEVEL" NOT NULL ENABLE);

 

 

COMMIT;

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

rpm 설치  

rpm -ivh [rpm파일명]  :  설치만 함 
 

★★★★ rpm -Uvh [rpm파일명]  :  업데이트 및 설치  

rpm - e [패키지이름]   :   패키지 삭제 

 

rpm 여러가지 명령어

rpm -q [패키지이름]  :  설치된 패키지 정보, 설치 여부 확인

★★  rpm -qa [패키지이름]   /  grep [패키지이름]   :   리눅스에 설치된 모든 패키지 확인

 

rpm -qf [파일이름]   :   어떤 파일이 어떤 패키지에 속하는지 검색

rpm -qf /bin/passwd

rpm -qip [파일이름]   :   rpm 파일의 상세 정보 보기 

 
 

★★ rpm -qi [패키지명]   :   해당 패키지의 상세 정보 보기

rpm -qi mc

 

rpm -qif   :   해당 파일이 속한 패키지의 상세 정보 보기

rpm -qif /bin/passwd
  

 

rpm -ql [패키지이름]   :   해당 패키지가 설치한 파일 목록 보기

rpm -qR [패키지이름]   :   해당 패키지의 의존성 확인하기 ( 이 패키지들이 있어야 사용 가능 > 의존성 )

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

yum ( yum -> dnf 최근 이름이 바뀌고 있는 중 )

 

yum list   :   

 

yum list installed   :   설치된 패키지 확인  

yum list update   :    업데이트 가능한 목록 확인  

yum info [패키지이름]   :   패키지 정보 확인  

yum deplist [패키지이름]   :   의존성 확인

 

yum install [패키지이름] -y :   패키지 설치, 의존성이 필요한 경우 해당 패키지도 같이 설치

-y 붙이면 질문에 모두 수락

 

yum remove [패키지이름]

yum erase [패키지이름]

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

파일 아카이브 ... . ... .. 압축과는 다르다. 그냥 파일을 묶는 느낌? .

 

tar -cvf [아카이브 파일][파일명]   :  [파일명] 들로 아카이브 만들기  

 

tar -xvf [아카이브 파일]   :   아카이브 해제

 

tar -tvf [아카이브 파일]   :   아카이브 풀지 않고 내용 확인

-z 옵션  :  압축까지 함께

 

 

압축 :  용량을 줄이는 기술

gzip / gunzip          gz파일

 

gzip   :  gz파일로 압축

gunzip   :   gz파일을 압축 해제

 

중요한 것
tar cvf     아카이브
tar czvf    아카이브 및 gzip 압축
tar xvf      아카이브 해제      압축 및 아카이브 된 파일 해제

압축 : gzip / gunzip

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

10장  

 

사용자 계정 관련 파일

 

 

 

 

 

 

 

이거를 저희가 공부하는게 맞나요 ????


 

 

 

 

사용자 계정의 설정과 관련된 기본 값을 정의

/etc/login.defs

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

사용자 계정 관리 명령   

여기 파트는 암기보단 책 보고 다시 복기 할 수 있을 정도로만 알아두기

 

계정 생성하기 useradd

계정 수정하기 usermod

 

계정명           uid       주그룹   보조그룹    홈디렉터리              기본쉘
user02          2000      2000      wheel        /home/user             /bin/sh

useradd -u 2000 -G wheel -m -d /home/user -s /bin/sh user02
 

계정명           uid       주그룹     홈디렉터리              기본쉘
user03       uid 1400     10      /home/guest/user03   /bin/sh

useradd -u 1400 -g 10 -m -d /home/guest/user03 -s /bin/sh user03
-u  UID
-g  GID
-m  -d 랑 같이 붙여서 써주면 좋다고 하네요
-d  홈디렉토리
-s  기본 쉘
계정명

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
UID  :  사용자가 로그인할 때 사용한 계정의 UID
EUID  :  현재 명령을 수행하는 주체의 UID

6장 프로세스
데몬 프로세스 : 특정 서비스를 제공하기 위해서 24시간 백그라운드에서 동작하는 프로세스
고아 프로세스 : 자식보다 부모가 먼저 종료된 프로세스.
좀비 프로세스 : 자식 프로세스가 실행을 종료 했는데도 프로세스 테이블 목록에 남아있는 프로세스.

ps [옵션] : 현재 실행 중인 프로세스의 목록을 보여줌
UNIX 옵션( 자주 사용 ) -ef  :  -e 와 -f 를 합친 옵션,   프로세스의 자세한 정보를 출력한다.
BSD 옵션  -aux  :  프로세스의 자세한 정보를 출력한다.


ps -ef grep | 문자열   >>  실행중인 프로세스의 자세한정보 출력. ( PID를 확인한다 )
프로세스 종료하기  kill -9 PID   ( 9번은 강제 종료이기 때문에 최후의 수단으로 사용하자 )
kill 기본값 : 15 ( 정상적인 마무리 )

백그라운드 작업 하는법  :  [명령어] &
Ctrl + Z  :   현재 포그라운드 작업을 정지 시킨 후 백그라운드로 전환
jobs  :  백그라운드 작업 정보
bg %작업 번호  :   해당 작업을 백그라운드로 전환
fg %작업 번호  :  해당 작업을 포그라운드로 전환

nohup [명령어] &  :  로그아웃 후에도 백그라운드 작업 계속 하게 하기
결과 출력은 nohup.out 에 저장된다.
nohup [명령어] > [파일명] 2>&1 &   :   nohup.out 말고 다른 파일에 저장하기


at   :   실행 예약
at -l  :  실행 예약중인 목록 보기
at -d [작업번호]  :  예약 취소 하기

과제 : ps -ef 명령어를 실행해서 /root/at/psfile01에 저장하게 하라
           2분이나 3분뒤에 저장되게 하라
at now +3min     
ps -ef > /root/at/psfile01 
ctrl+d

 

 

 

crontab  :  지정 시간마다 반복적으로 명령 실행
crontab -e : 편집 (생성, 삭제 등)
crontab -l : 예약작업 리스트 출력
crontab -r : 현재 계정의 crontab 내용 모두 삭제(일부만 삭제는 -e로 편집)
* 11 21 7 * ls -al > /tmp/crontab.out

* 기호를 입력한 필드에서는 모든 값에서 cron이 수행된다.  위 예제에서는 매 분마다.

예시

매년 1월 첫번째 일요일에 재부팅이 되도록 설정

0 0 1-7 1 0 reboot

매월 오후 1시부터 5시까지 10분마다 date 명령어를 실행해서 date01에 이어쓰기로 저장하도록 설정

*/10 13-17 * * * date >> date01

------------------------------------------------------
test 사용자가 매년 크리스마스에 메리크리스 메시지를 /tmp/christmas 파일에 덮어쓰기를 하게 해보자
root계정에서 
crontab -e -u test
0 0 25 12 * echo "Merry Christmas" > /tmp/christmas

엑세스 제어 설정 파일
<Centos7 기준> -> 다른 리눅스, 유닉스는 다를 수 있음

at
/etc/at.deny
/etc/at.allow

crontab
/etc/cron.deny            
/etc/cron.allow

1. *.allow 파일은 존재하지 않고 *.deny 파일만 존재하면 *.deny 파일에 등록된 사용자는 스케쥴링 명령 사용불가
2. *.allow 파일과 *.deny 파일이 둘다 존재하면 *.allow에 등록된 사용자만 스케쥴링 명령 사용 가능
3. 둘다 존재하지 않으면 root만 스케쥴링 명령 사용가능
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
8장 리눅스의 부팅
바이오스 단계
pc에 장착된 기본적인 하드웨어 (키보드 디스크) 의 상태를 확인한 후 부팅 장치를 선택하여 디스크의 첫 섹터에서
512바이트를 로딩 ( master boot record , MBR )

init 프로세스에서 사용하던 런레벨 ( Run Level )의 개념에 대한 이해 필요.
init 프로세스 = systemd으로 바뀌기 전의 1번 프로세스

 

 

 

init 5  :  GUI 모드 ( 지금 실습 중인 모드 )
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
systemd 서비스
systemd 를 기반으로 서비스를 시작하거나 종료할 때 사용하는 명령어는 systemctl
systemctl start httpd    http 서비스를 위해서 서버 시작 ( 아파치 인듯 )
systemctl status httpd   httpd 서비스 상태 확인

cd /var/www/html    >> 웹 서버 기본 홈 디렉토리 
vi index.html
<marquee>hello world </marquee>
파이어폭스 > 127.0.0.1 접속


-----------------
80 포트 열기    ( 포트 개방을 하면 윈도우 브라우저에서 ip주소로 접속 가능 )

firewall-cmd --add-service=http    -> 재부팅하면 다시 닫힘
firewall-cmd --add-port=80/tcp

firewall-cmd --permanent --add-service=http           https(443),telnet,ftp.....
firewall-cmd --reload

firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload

firewall-cmd --permanent --remove-service=http 
firewall-cmd --reload

firewall-cmd --permanent --remove-port=80/tcp
firewall-cmd --reload
-----------
systemd 와 런레벨    근데 target 이 뭐죠 ?? 컴퓨터가 부팅할 때 불러들이는 타겟 ??? 부팅 모드인것 같습니다.
종료
복구모드 ( 안전모드 )
CLI 
GUI
재부팅

 

셸 환경설정

 

 

 

변수 출력하기   echo $PATH

 

변수 설정하기 export [변수] = [값]

 

에일리어스 ( 별명 )  

alias 이름 = '명령'  

 

별명 해제

unalias

 

접근 권한의 표기 방법

d ( 디렉터리 여부 )

 

소유자 3글자 / 그룹 3글자 / 기타 사용자 3글자

r = 읽기 권한  w = 쓰기 권한   x = 실행 권한

 

 

 

 

 

권한 변경 명령어

chmod

 

 

 

chmod u+x 파일명   =    파일 소유자 ( u ) 에게 실행 ( x ) 권한을 부여 ( + )

 

 

 

새 터미널 실행

su - centos 

centos 계정으로 로그인

 

chown 계정명 파일명     소유자 바꾸는 명령어

chown centos file1        file1의 소유자가 centos 계정이 됨

chown :centos file1        file1의 소유 그룹이 centos그룹이 됨

chown centos1:centos2 file1       file1의 소유자가 centos1계정이 되고
                                                     소유 그룹이 centos2그룹이 됨
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

8진수 모드

r  100  4
w  010  2 
x  001  1
소유주  /  그룹  /  기타사용자
7           7            7
 

예제

touch p1 p2 p3 p4             /tmp 같은 디렉터리에서 작업

 p1 8진수 방식으로 소유주 읽기 실행, 소유 그룹 실행 권한만, 기타 사용자에게는 쓰기 권한만
chmod 512 p1

 p2 8진수 방식으로 모든 사용자 모든 권한 삭제
chmod 000 p2

 p3 8진수 방식으로 소유그룹만 읽기, 쓰기 권한 줄 것
chmod 060 p3

 p4 8진수 방식으로 모든 사용자에게 실행 권한만 줄 것
chmod 222 p4

 /root/filea 디렉토리에 기타 사용자가 들어올 수 없도록 권한을 변경하시오. ( 실행 권한 제거 )   
chmod o-x /root/filea

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

<기본 퍼미션>
일반 사용자     664
                    775

root             644
                   755

파일은 생성 될때 기본값이 666
디렉터리는 생성될때 기본값이 777

일반사용자는 마스크값이 0002             664( 일반 )            775( 루트 )
root는 마스크값이 0022                   644( 일반 )            755( 루트 )  
기본값 - 마스크값 = 변경된 기본값 .  단, 쉘을 다시 시작하면 설정 값이 사라짐

 

마스크값 변경 명령어 umask [숫자]

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

특수 접근 권한

접근 권한은 원래 4자리

setUid  앞자리 4

setGid  앞자리 2

sticky bit  앞자리 1

 

setuid 는 파일에만 설정한다.

sticky bit 는 디렉터리에만 설정한다.

setgid는 파일에 설정 가능 하면서 디렉터리에도 설정이 가능하다. 만약 디렉터리에 setgid를 설정하면 해당 디렉터리에서 생성한 파일의 
소유 그룹은 해당 디렉터리 소유 그룹으로 자동 설정된다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
6장 프로세스
데몬 프로세스 : 특정 서비스를 제공하기 위해서 24시간 백그라운드에서 동작하는 프로세스
고아 프로세스 : 자식보다 부모가 먼저 종료된 프로세스.
좀비 프로세스 : 자식 프로세스가 실행을 종료 했는데도 프로세스 테이블 목록에 남아있는 프로세스.

ps [옵션] : 현재 실행 중인 프로세스의 목록을 보여줌
UNIX 옵션( 자주 사용 ) -ef  :  -e 와 -f 를 합친 옵션,   프로세스의 자세한 정보를 출력한다.
BSD 옵션  -aux  :  프로세스의 자세한 정보를 출력한다.


ps -ef grep | 문자열   >>  실행중인 프로세스의 자세한정보 출력. ( PID를 확인한다 )
프로세스 종료하기  kill -9 PID   ( 9번은 강제 종료이기 때문에 최후의 수단으로 사용하자 )
kill 기본값 : 15 ( 정상적인 마무리 )

 

입력 모드 , 명령 모드 가 있다.

 

입력 모드로 전환하기 위해선   ESC >  i a o

g -> 첫 행으로 이동한다.
G   -> 마지막 행으로 이동한다.

x -> 1글자 삭제
dd -> 1행 삭제
u  -> 취소
:e!  -> 초기화(저장상태 처음부터)

dd -> 행 잘라내기
yy -> 행 복사하기
p -> 아랫줄에 붙여넣기

/텍스트      -> 검색        n누르면 다음검색으로 이동

/%s/텍스트1/텍스트2/      -> 전체 텍스트에서 텍스트1을 텍스트2로 바꾼다.

:set [값]        -> 환경설정

:set nu          -> 행에 번호 매기기
:set nonu         -> 행에 번호 매기기 취소

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

셸의 특수문자

주요 특수문자   *   ?   [ ]   ~   | (쉬프트 \) 

* , ?   SQL 에서 활용하는것과 동일하다.'

 

[ ]   [ ] 안에 포함된 문자 중 하나를 나타냄.  예시) ls tmp[135].txt  tmp1.txt    tmp3.txt    tmp5.txt 해당 파일이 있으면 출력한다.

 

;  연결된 명령을 왼쪽부터 차례로 실행한다.    예시)  pwd;  ls /tmp;   

 

| (쉬프트\)  왼쪽 명령의 실행 결과를 오른쪽 명령의 입력으로 전달한다. 

 

'  ' (작은따옴표)    모든 특수 문자의 기능을 없애고 문자를 감싸서 문자열로 만들어줌

 

"  " (큰따옴표)    $,  ``,  \  를 제외한 모든 특수 문자의 기능을 없애고 문자를 감싸서 문자열로 만들어줌

 

`  ` (홑따옴표)   `  ` 로 감싸인 문자열을 명령으로 해석함   예시  echo  "Today is   `date`   "

 

\  바로 뒤의 특수 문자의 효과를 없애고 일반 문자처럼 처리한다.

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

리다이렉션  셸 스크립트를 작성할 때 유용하다고 한다.

 

>  <   >>   입출력의 방향을 바꾼다.   

예시)   ls -l > res     명령의 실행 결과를 res파일에 저장한다

예시) cat >> test  명령 이후 사용자가 작성하는 입력을 파일로 저장한다.  종료는 Ctrl + D

 

>   덮어쓰기    >>  기존 파일의 내용 뒤에 결과를 추가   

 

 

기본값은  1과 동일했다.   명령 > 파일명  =  명령 1> 파일명

 

 

 

 

1 2 3 빈 파일을 만들었다

ls 1 2 3 4 5 6 > A  2> B     =  파일 정보 정상 출력은 A파일에 저장하고 오류 출력은 B에 저장하라는 명령

cat A = 정상 처리된 1 2 3 이 나온다

cat B = 존재 하지 않는 4 5 6 오류 결과가 나온다

 

 

 

표준 출력과 표준 오류를 한 파일로 리다이렉션 하기

 

ls 1 2 3 4 5 6 > ls.out 2> &1  =  1 2 3 4 5 6 파일 목록의 정상 출력(>)을 ls.out 에 저장하고 오류 정보를 표준 출력 파일(&1)으로 리다이렉션(2>)

 

 

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

셸 환경설정

 

 

 

변수 출력하기   echo $PATH

+ Recent posts