필기 정리 - java

조형찬·2023년 3월 1일
0

필기 정리

목록 보기
8/11
  • java 참고

cf.자바의 정석 남궁성 깃허브
https://github.com/castello/javajungsuk_basic


  • 자바 다운로드

자바 1.11버전이 무난하게 자주 쓰인다.
최신 버전들은 안정성이 떨어질 가능성이 있으므로 검증된 버전을 사용하는 것이 좋다.

java설치 후 bin폴더 경로를 복사한다.

제어판 - 시스템 - 고급 시스템 설정- 환경변수 - 시스템 변수에서 path 부분 클릭 후 편집 - 새로만들기 주소 넣고 맨 위로 하고 확인

cmd -> java -version 쳐서 나오는지 확인
버전 정보나오면 자바가 설치 된것.


  • 이클립스 다운로드

다운로드 패키지로 들어가서
Eclipse IDE for Enterprise Java and Web Developers
Windows x86_64 를 다운받는다.
다운 받을 때 mirror 눌러서 korea쪽에서 다운 받으면 더 빠르게 받을 수 있다.(기본 나라 설정이 일본으로 되어있었기 때문)

이클립스는 압축만 풀어도 (별도의 다운없이도) 사용 가능하다.
각각의 언어에 맞는 이클립스를 사용하는 것이 좋다(섞어서 쓰는서 지양)(예) eclipse_java, eclipse_jsp

자바와 관련된거는 알집으로 압축을 풀지말것
(세븐집 권장) 경로의 문제가 생길 수 있기 때문이다.
이클립스 압축은 workpspce의 jsp,java 폴더에 풀기 (용도별로 분리한것)


  • 이클립스 환경설정

우측 상단
open perspective 누르고 java 누르기(처음은 java EE버전이 켜져있음)

중간 상단 window-preference클릭-(이클립스 개발도구 환경설정)
(cf.프로젝트 각각의 환경설정도 있음)

  • preference 설정들

1) 한글 설정(encoding) => 5~6곳에 대한 한글 설정을확인한다.

1-1. general-workspace- 왼쪽 하단 Text file encoding 에 UTF-8로 되어있는지 확인
1-2.general -editor-text editor-spelling-encoding을 UTF-8로 바꾸기
(default로 잡든 other로 잡든 상관은 없고 UTF-8면 됨)
1-3. WEB-CSS files -encoding -utf-8
1-4. WEB-HTML files -encoding - utf-8
1-5. WEB-jsp files -encoding -utf-8
+1.6. WML-Wml files- encoding -utf-8

2) 서버 설정 (EE일때)

3) 자바 실행환경 설정
Java -install JREs-add- jre home에서 - directory - c에자바 폴더 위치 넣고(c~~jdk) finish - 추가한 그 폴더를 체크해줌


  • 이클립스에서 프로젝트 만들기

이클립스에서 create java project
JRE 텝에서 javaSE-11로 잘 되어 있는지 확인 후 finish(next 눌러서 확인해도 무방)

jre library에 내용이 다 있는지 확인
src안에 module파일은 삭제해도 됨
src안에- new - package - name에-com.hyeongchan.exam01 - 이거적는건데 도메인을 거꾸로 적는거라 생각하면 됨(com폴더 안에 hyeongchan폴더 안에 exam01폴더 안에 프로젝트가 생성되는 것) - finish
cf)이런걸 네임스페이스라고 함. 같은 파일에 있어도 구분할 수 있다. 패키지는 폴더명이라 생각하면 된다.

만들어진 com.hyeongchan.exam01 package에서
우클릭 new- class - class 이름은 반드시 대문자로 만들것
(에러가 나는것은 아니나 약속이다)
(c언어에서의 구조체 이름은 대문자로 하는 것임 의사소통을 위함)

cf)낙타 등처럼 대문자를 중간에 넣어주는거를 카멜 표기법이라고 함. 자바는 이걸씀. 예) 카멜표기법 workSpace 스네이크표기법 work_space


  • 문자와 문자열

java는 엄격한 언어다.

" " -> 문자열 :문자의 묶음 , 문자열에는 n개의 데이터가 들어가서 ""는 오류가 나지 않는다.
' ' -> 문자 : 하나의 데이터,데이터가 없는 ''가 들어가면 에러가 난다. 단, ' '이렇게 공백이 들어가면 오류가 나지 않는다.


  • 클래스의 접근한정자 종류, 메서드 기본 구조
)
package com.hyeongchan.exam02;

public class SungJukData { 
	//클래스의 접근 한정자는 public 또는 안붙이기(package) 두가지만 가능하다.
    
  //자료부
    
	// (필드(멤버) 변수 : 변수인데 함수 밖에 있는 변수를 필드라 부른다)
	public int bunho; 
    String iname; //"홍길동" package = 프랜들리 = 디폴트
	private int kor; //예 100점 
	int eng; //예 80점
	int mat; //예 90점
	
    //필드의 접근한정자는 (public, package, private, [protected](몰라도 무방) 4가지가 있다) 
    //public 은 어디서든 class사용가능하다.
    //private는 이 클래스 안에서만 사용가능하다.
    //package는 이 패키지 안에서만 사용가능하다.
	//간단한건 public이지만 보안에 취약해질 수 있다.

  //메서드부(함수부)
	public int total() {   
		int rtnValue = 0;
		rtnValue=kor+eng+mat;
		return rtnValue;
	}
     /*
      만약 필드에서 int total;을 했다면 위의 예와 달리 반환을 안해줘도 됨.
	예)
    	public void total(){
		total=kor+eng+mat;
		return;
    }
    이렇게만 해도 가능해진다. 이러한 차이가 있음을 인지한다.
    */
    
	
	public double average() {
		double rtnValue = total()/3.0;
		return rtnValue;
	}

	/*
    메서드를 만들 때 기본적으로
	public void total(){
    
		return;
    } 
    이렇게 틀을 만들고 시작한다. void는 반환값이 없는거라서 return;으로 받는다.

  • data를 만드는 방법

자료는 사용하기 위해 만든다.
한 번만 사용할 때는 보관해둘 필요가 없다.
여러번 사용해야 할 경우에는 변수에 보관해둘 필요가 있다.

  1. 단일(기본타입)의 자료
    숫자: 그대로 사용
    문자: ''안에 넣어 사용
    논리: true, false라는 언어에서 약속된 키워드를 사용

  2. 묶음(참조타입) 자료
    배열: {}또는 new 타입명
    문자열:""또는 new 타입명
    복합(클래스):new 타입명


  • 지역 변수 필드 변수

데이터는(변수)는 선언되는 위치에 따라서 사용되는 범위가 결정이 된다.

지역변수
-메서드 안에 생성된 데이터(또는 변수)를 지역데이터 (지역 변수)라고 하며 메서드가 종료되면 사라진다. =>또한 지역변수는 생성이 되고 값이 초기화 되지 않는다. 즉, 반드시 값을 할당한 후 사용한다.

필드변수 (멤버 변수)
-메서드 밖에 생성된 데이터(또는 변수)를 필드데이터 (필드,멤버변수)라고 한다.
묶음 데이터 생성시 만들어지고 자바가 알아서 소멸시킨다.
=>지역변수와 달리 필드는 생성과 동시에 값을 할당하지 않으면 기본값으로 할당이 된다.
(0 또는0.0 또는 false 또는 null)


  • 참고내용들

예)
(cf.반복(함수, 반복문 등)에서 조기리턴 개념이 있다.)
(cf. http: //www.naver.com 이렇게 있을 때//는 이름을 알려주는 표시다.
즉 여기서 www는 컴퓨터의 이름이라고 생각하면 된다.)
자료를 먼저만든다. =>그 후에 필요에 따라 변수에 담는다.
외부에서 결정을 한다. => 호출하는 곳에서 결정을 한다. =>유연하게 동작한다는 것을 의미한다.

)
	public int sum() { //1부터 100까지의 합만 구할 수 있다
		int sum=0;
		for(int i=1; i<101; i++) {
			sum+=i;
		}
		return sum;
	}
	
	public int sum(int startNum, int endNum,int incre) { //모든 합을 구할 수 있다.
		int sum=0;
		for(int i=startNum; i<(endNum+1); i=i+incre) {
			sum+=i;
		}
		return sum;
	}
	
	//sum(1,10,1)  1~10까지 합을 구하라. 이처럼 호출하는 쪽에서 결정을 할 수 있다.1)
for(int i=startNum; i<(endNum+1); i=i+incre) //for문을 돌릴 때마다 1을 더해야 함2)
for(int i=startNum; i<=(endNum); i=i+incre) //같거나 같다 두번 연산3)
endNum=endNum+1  //미리 1을 더해주면
for(int i=startNum; i<endNum; i=i+incre) // for문을 돌릴 때 더해진 변수를 가져오기만 하면 된다.1,2,3은 같은 결과가 나오지만 연산과정이 차이가 크다.

  • 자바 main class에서 실행하는 법
)
package com.hyeongchan.exam02;

public class UseTest {

	public static void main(String[] args) {
    	//main함수는 하나만 있어야 한다.
        //main에서는 직접 동작을 수행하는게 아니라 동작을 수행하는 class를 호출하는 역할을 한다.
		//사용하고자 하는 클래스 데이터를 만들고(new)변수에 저장한다.
		GroupDataOne obj;   //클래스 이름이 변수 타입으로 들어간다.obj는 변수 이름
		obj = new GroupDataOne(); //()=객체생성자(클래스이름과 같은 메서드), 호출연산자
		obj.dataPrn();
	}

}

패키지 안에 GroupDataOne()라는 클래스가 있을 때
main class에서 GroupDataOne 변수명;으로 선언을 하고 변수명 =new GroupDataOne();로 불러온다.
그러면 GroupDataOne()안에 dataPrn()이라는 메서드가 있을 때
변수명.dataPrn()으로 실행시킬 수 있다.


  • 배열을 만드는 방법
)

	public void arrExam() { //배열 만드는 법들
		int[] arrNum1= new int[5];//new를 사용하면 필드 데이터가 만들어짐= 초기값을 지정안해줘도 값이 들어감
		int[] arrNum2= {1,2,3,4,5}; //방법으로만 보면 가장 편하지만 가장 않좋은 방법이긴함
		int[] arrNum3= new int[] {1,2,3,4,5,6}; //이게 가장 좋은 방법

  • 메모리 저장 장소
)
Member obj = new Member(); 
class Member의 필드에 String id;, String password;,String phoneNumber;가 있을 때

메모리에는 static , stack, heap영역이 있다.
stack영역에 obj라는 4byte짜리 내용이 있다.
여기에는 값이 아니라 주소값이 들어가 있다.
만약 int k =1000;이라는게 있었다면 여기에는 숫자값이 들어가 있다.

heap영역에는 
id = null password=null phoneNumber=null 이렇게 값이 들어가 있다. 이를 객체라 부른다. 
(여기에는 메서드도 있다.)
stack영역의 obj 주소값이 heap영역의 값의 위치를 가리키는 것이다.


데이터를 부를 때 스택영역의 주소값을 보고 힙영역의 데이터를 불러오는 것이다.

  • 생성자 함수
)
public class Member {
} //클래스 Member가 있을 때
public Member() { //생성자 함수
	}
생성자 함수는 class의 이름과 완벽히 동일하다.(첫글자 대문자사용) 반환되는 타입이 없다.
클래스를 정의하면 기본 생성자가 자동으로 생성된다.(만들지 않아도 되기는 함)
없어도 무방하긴 하지만 적어주는 습관이 좋다.
우클릭-source-constructor superclass해주면 기본 생성자를 만들어준다.(그냥 컨트롤 스페이스바 눌러서만들어도 됨)
우클릭-source-constructor using field해주면 사용자(개발자) 정의 생산자를 만들어준다.
(만들면서 필드의 값을 초기화 함)
-> 생성하면서 필드의 자료를 초기화 하기 위한 목적으로 만든다.
->사용자 정의 생성자를 만들면 기본 생성자는 자동으로 만들어지지 않는다.
	
    //매개변수가 없어서 기본 생성자
	public Member() {
		super();
	}
	//사용자(개발자) 정의 생성자, 만들면서 필드의 값을 초기화 하는 용도
	public Member(String id, String password, String phoneNumber) {
		super();
		this.id = id;
		this.password = password;
		this.phoneNumber = phoneNumber;
	}

//main클래스에서
Member obj = new Member();  //기본 생성자를 가져옴
Member obj2 = new Member("cho","123","0101"); //사용자정의 생성자를 가져옴

  • overloading

메서드의 이름이 같으면서 매개변수가 서로 다를 때 overloading이다.
(cf. 이름, 매개변수는 같은데 안에 내용을 다시 정의할 때 overriding)
생성자의 overloading <= 기본생성자랑 사용자정의 생산자 일때
똑같은 이름일때 매개변수의 수가 다르거나, 타입이 다르거나 해야 둘 다 사용 가능

)
	public Member(String id, String password, String phoneNumber) { //매개변수 3개
		this.id = id; //this = 클래스이름으로 해석하면 이해가 쉽다.
		this.password = password; //즉 Member.password와 같다고 생각
		this.phoneNumber = phoneNumber;
	}
	public Member(String id, String password) { //매개변수 2개
		this.id = id;
		this.password = password;
	}
	public Member(String id, int phoneNumber) { //매개변수 2개지만 하나는 int형 매개변수
		this.id = id;
		this.phoneNumber = phoneNumber+"";
	}

  • 권한이 있을 때만 필드 값을 바꿔줄 수 있도록 할때
)
public class Member {  //데이터를 정의하는 클래스 =>DTO클래스,VO클래스
	private String id;   //필드를 private로 설정
	private String password;
	private String phoneNumber;


public String getId() { //source에서 getter setter를 눌러줌,  private도 상황에 따라 바꿀 수 있도록 적어줌
		return id;  
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

/	public Member(String id, String password, String phoneNumber) {
//	if 권한이 있다면{  //권한이 있다면 바꿀 수 있다는 식으로 적어줌
//		this.id = id;
//		this.password = password;
//		this.phoneNumber = phoneNumber;
//	}}

  • DTO클래스, VO클래스, Bean클래스

필드명 다쓰고 private타입으로

1.기본 생성자, 사용자 생성자
2.getter setter
3.hashtag equals
4.to spring


  • jsp설정, 톰캣 설정, emmet 다운

기본 설정은 java설정과 동일(한글, JREs등)
추가로
먼저 https://tomcat.apache.org/download-90.cgi 여기서
아파치 톰캣 9.0 버전 다운
바이너리 디스트리브션에서 64bit window zip다운 64-bit Windows zip
디드라이브에 저장
server-런타임 환경설정 -아파치 톰캣 9.0 눌러주고 디렉토리에서 다운받은경로 눌러주기

서버를 만들때
java EE에서 그대로하고
1. 파일-뉴-other-아래 server-아파치- 아파치 톰캣 클릭후 다음다음 -만들어지고 난후 - 중앙아래에 servers 누르면 서버 환경설정을 바꾸는 화면 나옴 - ports에 http에 8080을 8888로바꾸고 저장한다.

뉴-other -web-다이나믹 웹 프로젝트로 들어가거나
우클릭 -뉴 - 다이나믹 웹 프로젝트 -예first로 만들고

first에서 src 밑에 webapp에서 우클릭 뉴

이클립스 eclipese emmet 다운 검색해서
http://download.emmet.io/eclipse/updates/
위 코드 복사해서
이클립스 help-인스톨-add-name에 emmet 위치에 복사한 주소 아래 디테일에 왼쪽 1,2,4번이 체크되어있는지 확인 후 피니쉬- 다 선택해서 설치 하고
다시시작해서 윈도우 프리퍼런스 에밋들어가서 ,jsp,jspf 추가해줌


  • 자바에서 로그인 화면 만들기
  1. 이클립스 java EE에서 Dynamic web project 만들기
  2. .dto로 끝나는 package만들기
  3. 그 패키지 안에서 클래스를 만들기
  4. 해당 클래스에서 우리가 받을 값을 필드에 선언한다. (예.private String userId)
  5. 기본생성자, 사용자 생성자를 넣어주고, hashcode and equal, tospring 까지 다 해준다.
  6. src 아래 webapp에서 html파일 생성
  7. 입력 폼을 만들고 자료를 .jsp파일로 보내기.
  8. 받을 자료의 name속성값을 설정한다.
  9. 자료를 받는 jsp파일에서 <% %>으로 묶어서 java코드를 작성한다. request.getParameter("name값")으로 받아서 변수에 저장한다. (예. String userId = request.getParameter("userId") 이때 변수 이름도 name값과 동일할 것)

  • 데이터베이스 다운 및 설정

오라클 11g xe 다운로드
https://www.oracle.com/database/technologies/xe-prior-release-downloads.html
맨위에 거 다운

sql developer
https://www.oracle.com/database/sqldeveloper/technologies/download/
두번째 가운데 거 다운

설치 완료 후
내pc- 우클릭 -관리- 서비스 및 응용 프로그램 - 서비스-oracle에서 상태 '실행'으로 되어있는게 뭔지 확인. OracleServiceXE,OracleXETNSListener 이렇게 두가지가 실행이다. 기본적으로 컴퓨터가 부팅되었을 때 자동으로 돌아가는데 켜져있으면 느려지니까 쓸 때만 켜주고 아니면 중지를 시켜주면 된다.
속성에서 수동으로 켜지게 할 수도 있음(선택)

오라클 설치 완료후
sql.exe 실행 (바로가기 만들고 잘라내기로 홈화면에 붙여넣기(선택))
자바가 깔려있는 위치 적어주기(bin이 보이는곳까지만) -이후 나오는거 아니오 누르면 시작가능(별도 설치 불필요)


  • sql사용

    좌측 상단 초록색 플러스 모양- 이름에 서버 관리자 계정 색 빨간색으로 써주는 편이 좋음.
    사용자 이름은 sys로 정해져있음 롤은 반드시 SYSDBA로 해야함 비밀번호는 아까 오라클 설치할때 비밀번호
    호스트 이름에 ip주소를 적기 (=localhost)
    내 ip주소(192.~~) , localhost, 123.0.0.1 다 똑같은 말이다
    테스트 눌렀을 때 상태 성공이면 접속 누르기.(연결완료된것)
    sql에서 대소문자는 보통 구분안하고 쓴다.


  • sql 사용자 비밀번호 변경

인터넷에서 오라클 사용자 비밀번호 변경검색

1)
alter user hr identified by hr account unlock2)
ALTER USER scott(hr사용자) IDENTIFIED BY tiger123(hr비밀번호); 
--hr 사용자의 비밀번호를 hr비밀번호로 바꾸겠다3)
ALTER USER scott(hr사용자) IDENTIFIED BY tiger123(hr비밀번호) ACCOUNT UNLOCK 
-- 예2) + 계정 잠금도 풀어주겠다.

  • sql 바뀐 사용자 비밀번호로 접속해보기

새접속(초록색 플러스)
name 아무거나 (인사관리 샘플)
사용자 이름 비번 적고 롤은 기본값
인사관리 샘플아래- 테이블 아래 -EMPLOYEES 들어가서 -데이터 보면 여러 데이터 있음 - 접속창에서 접속 해제할수 있고, 삭제누르면 화면에서 안보이게 할 수 있음


  • 데이터베이스 서버관리 업무 순서
  1. 자료를 저장할 물리적인 공간(폴더=디렉토리)을 만든다.
    (예 d드라이브 oraclaDataArea 폴더 생성)

  2. 관리자 계정으로 데이터베이스에 접속(sys) (관리자 계정은 sys로 들어가야 함)

  3. 디폴트 테이블 스페이스를 생성한다.(테이블 스페이스는 디폴트와 템포러리가 있으나 디폴트 테이블 스페이스를 생성한다. 이는 관리자 계정에서만 생성 가능하다)

인터넷 검색을 통해 오라클 테이블 스페이스 생성 검색

	 --테이블 스페이스 생성(주석 --)
	create tablespace mytestsp --(예시이름)
	datafile 'D:\oracleDataArea\mytestspace.dbf' 
    --(디드라이브에 폴더하나 만들고 그 경로 적고\mytestspace.dbf 추가로 적어줌)
	size 4096m --(m또는 g를 쓰지만 호환성 때문에 g보단 m으로 쓰는게 좋다 1g=1024m)
	autoextend on 
		next 512m --(자동증가 용량(예 512m))
	maxsize unlimited; --(제한없이 늘어남)

블록을 잡아서 실행을 시키거나 그냥 실행(ctrl+enter)시키면 d드라이브 폴더에 dbf 파일이 만들어짐(용량 4기가짜리)

인터넷에서 오라클 테이블 스페이스 조회(select) 검색

select * from dba_tablespaces; --(컨트롤 엔터 눌러서 확인해보면 MYTESTSP가 생긴것 확인가능)

4.사용자 생성 및 조회(생성시 테이블 스페이스와 사용량을 지정해주는 것이 바람직하다)
-사용자 생성

	create user chan(아이디) identified by chan(비번)
	default tablespace mytestsp  (여기서 썼으면 좋겠다라고 지정)
	temporary tablespace temp
	quota 0 on system   (이거랑 아래 두부분은 꼭 써야함)
    	quota 0 on sysaux 
          (system, sysaux 는 중요한 부분이라 이곳에는 데이터가 가지 않게 하라는 의미다)
          (오라클 시스템에서 관리하는 테이블 스페이스에 저장 방지하는 것)
    	quota 512m on mytestsp; 
          (만들었던 공간인 mytestsp에 저장하라는 의미)
          (이거는 생략해도 되지만 위에 두개는 없으면 안됨)
          (xe버전은 용량 한계가 있어서 1024m으로 만들면 문제가 생길수 있음)

이렇게 만들어도 연결권한은 아직 없어서 접속이 안된다(lacks CREATE SESSION privilege)

-사용자 조회(select)

select * from dba_users; or select * from all_users; 로 사용자 조회가능

5-1. 사용자 권한 부여
인터넷 오라클 사용자 권한 부여 검색

GRANT RESOURCE, CONNECT, DBA TO [계정이름]; (dba 권한은 함부로 넣지 않는다)

RESOURCE 개체 생성, 변경, 제거 권한
CONNECT DB 연결 권한
DBA DB 관리자 권한

5-2. 사용자 권한 회수
revoke dba(회수할 권한) from chan;(계정이름)

6.사용자 권한 조회

--1. 사용자에게 부여된 시스템 권한 확인 (dba권한이 있는지 확인, 없으면 아무것도 안나옴)
SELECT * FROM DBA_SYS_PRIVS
WHERE GRANTEE = 'CHAN' ; --(여기서 사용자명은 반드시 대문자로 입력)
-- 2. 사용자에게 부여된 롤 확인(시스템 권한이 롤에 포함됨) (무슨 권한 있는지 확인)
SELECT * FROM DBA_ROLE_PRIVS
WHERE GRANTEE = 'CHAN' ; --(여기서 사용자명은 반드시 대문자로 입력)

서버 관리자 계정은 항상 접속해제, 화면상에서 삭제까지 해주어야 함


  • CRUD

객체(자료가 아닌것) D.D.L
만들기create
수정Alter
삭제Drop
조회Select

D.C.L
권한 부여 Grant
권한 회수 revoke

자료(테이블의 내용) D.M.L
만들기Insert
수정update
삭제delete
조회select 조회가 가장 중요함 어떻게 가져오느냐에 따라 나오는 내용이 천차만별이기 때문
C(생성) R(조회) U(수정) D(삭제)


  • 테이블 만들기

실습용 계정으로 접속한 후

CREATE table members(
     col1 number(8),
     col2 varchar2(50),
     col3 date
);

members엑셀 시트 하나를 만들고, col1,2,3이라는 목록을 만든것과 동일하다.
table이름은 보통뒤에 s를 붙인다.
col1의 경우 숫자형 데이터 8개만 들어간다.
co2의 경우 varchar2형 데이터 50개까지만 들어간다. varchar대신 varchar2를 쓴다.
co3의 경우 date(날짜형) 데이터만 들어간다.


  • 테이블에 내용 넣기
1)
insert into members(col1,col2,col3) values(1,'chan',sysdate);
--members라는 테이블의 col1,2,3에 각각 데이터 넣기 (cf, ""대신 ''를 쓴다, sysdate는 현재 날짜)2)
insert into members(col1,col2,col3) values(1,'chan');
--행 숫자와 데이터 숫자가 맞지 않으면 오류가 난다.3)
insert into members values(3,'chan3',sysdate);
--모든 행에 입력하는 경우 col명을 적지 않아도 된다.4)
insert into members values(3,'chan3');
--모든 행에 입력해야 하는데 데이터가 부족해서 오류가 난다.

  • 테이블 자료 업데이트 및 삭제

업데이트(수정)

)
update members
   set col1=1
   where col2='chan3';

해석: members라는 이름의 테이블을 수정을 하는데, col1에 해당하는 부분의 자료를 1로 바꾼다.
단, col2가 chan3인 경우에만 수정을 해준다.
만약 where가 없이 쓰이는 경우 모든 자료의 col부분의 자료가 1로 바뀐다.
따라서 update문을 쓸경우 무조건 where를 먼저 작성해주는 습관을 갖도록 한다.

삭제

delete from members;
delete from members where col2='chan3'

해석 : 첫줄의 경우 members라는 테이블의 모든 자료를 지운다.
두번째 줄의 경우 col2가 chan3인 부분의 자료만 지운다.
delete는 update와 같이 많은 자료가 한번에 소실될 가능성이 있다.
따라서 where문을 먼저쓰는 습관을 들여야 하며 웬만하면 삭제하는 내용은 없는 것이 좋다.


  • sql 목록 부여내용
--회원관리에 필요한 항목들(최소화)
--회원 아이디(필수입력, 중복제거), 비밀번호(필수입력), 회원명(필수입력), 연락처(선택입력),주소(선택입력)

/*
create table members(
    mem_Id      varchar2(25) PRIMARY KEY, 
     --어차피 대문자로 나올거라서 카멜 표기법말고 스네이크 표기법 사용, 중복이 안된다+필수입력이다=primary key 
     --단, 연습용으로는 괜찮지만 실무용으론 비권장, 인라인 제약조건 부여
    password    varchar2(25) not null, 
       --비밀번호는 암호화해서 하는 추세기때문에 10배로 올려서 250 이런식으로 하긴 함.
    mem_name    varchar2(25) not null, 
       --필수입력의 경우 not null을 넣어준다.
       --한국이름중 제일 긴게 7글자가능인데 한글이라 3곱해야 해서 21인데 넉넉하게 25
    phone       varchar2(11),  --전화번호는 11자이지만 국가 코드도 고려하면 더 길어짐
    address     varchar2(180)  --주소는 60자면 충분한데 한글은 3을 곱해야 해서 180으로 줌
);
*/

create table members(
    mem_Id      varchar2(25) , 
    password    varchar2(25) not null, 
      --인라인 제약조건 , not null 제약조건은 인라인으로만 지정할 수 있다.
    mem_name    varchar2(25) not null,
    phone       varchar2(11),
    address     varchar2(180),
    constraint mem_Id_pk PRIMARY KEY (mem_Id) 
     --아웃라인 방식의 제약조건 부여, 실무용 constraint 제약조건이름 제약조건 부여할부분    
);

  • jsp에서 데이터베이스에 넣을 자료 설정
  1. jsp에서 다이내믹 웹프로젝트를 만들고
    javaresourse-src에 패키지, 패키지.dto,패키지.dao 총 3가지 패키지를 만든다.
    예)com.sample.exam01, com.sample.exam01.dto,com.sample.exam01.dao

  2. com.sample.exam01.dto에 class를 만들고
    class이름은 데이터베이스 테이블이름에서 s만 뺀거
    예)테이블이름 members, class이름 Member

class Member에서 필드에 테이블에 들어가는 행들을 선언해준다.

)
public class Member {
private String mem_Id;  //String
private String password;
private String mem_name;
private String phone;
private String address;
}

그리고 기본생성자, 사용자생성자(필수부분만 해도됨), gettersetter, 해쉬태크, to string 다 해주기

  1. com.sample.exam01.dto에 class를 만들고 class이름은 MemberDAO로 해준다.
import java.util.List;

import com.sample.exam01.dto.Member;

public class MemberDAO {
	public int insert(Member member) {
		int result = 0;
		return result;
	}

	public Member selectOne(String mem_id) {
		Member member = null;
		return member;

	}

	public List<Member> selectAll() {
		List<Member> member = null;
		return member;

	}

	public int memCount() {
		int memCount = 0;
		return memCount;
	}

	public int updateOne(Member member) {
		int result = 0;
		return result;
	}

	public int deleteOne(String mem_id) {
		int result = 0;
		return result;
	}

}

insert,update,delete는 값이 변한다. 값이 변하는 경우에 int로 반환해주는 것이 좋다.
select의 경우 반환되는 타입이
1. List<테이블DTO클래스> (모든거 불러와서 조회, list import 필요)
2. 테이블DTO클래스(하나만 불러와서조회), 3. int (몇명인지 조회) 등이 있다.
여기서 자료타입에 클래스 Member를 쓴다는건 클래스 Member안의 내용이 한 사람의 정보 총합이기 때문이다. List는 한사람의 정보총합을 하나하나 List에 넣어서 보여주는 타입이기 때문에 List인것이다.


  • OJDBC 설치

자바 오라클 연동 검색

sql 설치했던 폴더에 -jdbc-lib에 있음
ojdbc8.jar 이 파일을 복사해서
java EE에서 예)exam01 - src - main -webapp -WEB-INF-lib 안에 붙여넣기 해준다
java Resources-Libraies에 Web App Libraies가 들어오면 우선 된것.


  • 자바연동 데이터베이스 CRUD 프로그램 만들기

-선행사항
해당데이터베이스에 맞는 드라이버를 설치한다.(oracle의 경우 ojdbc?.jar ?는 버전)
(mysql의 경우 다름, 따라서 검색을 잘 활용할것 검색-DB명 Jdbc 드라이버 다운)
방법1. 해당프로젝트의 src-main-webapp-WEB-INF-lib에 파일을 넣으면 된다(복사해서 넣어주면 됨)
방법2. 다이나믹 프로젝트 - 우클릭 빌드패스- 컨피규어 빌드-중앙에 라이브러리- 중앙에 클래스패스누르고- 우측 add external jars-jdbc파일 클릭찾아가서 클릭

  1. DBMS(데이터베이스) 클라이언트 프로그램(sql developer)을 이용하여 테이블을 만든다.

DTO 패키지 안에 클래스
2. 해당 테이블의 컬럼들을 하나로 묶는 class를 작성한다. (DTO 클래스라고 함.)
테이블의 컬럼명과 자바클래스의 필드명이 반드시 일치해야 한다. (mem_id 등)
테이블의 컬럼자료 타입과 자바클래스의 필드명의 타입을 알맞게 정의한다.
(varchar2의 경우 String로 받는등)
-생성자(기본생성자, 전체필드 생성자)를 만든다.
-gettersetter메서드를 만든다. 모든 필드를 선택해서 //여기까지는 보통 필수
-hashCode, equals메서드를 만든다.
-toString메서드를 만든다.

DAO 패키지 안에 클래스
3.해당 테이블의 자료를 CRUD하는 기능의 클래스를 만든다.(DAO클래스라고 함.)
3-1.데이터베이스 연결하는 메서드를 만든다.
public Connection getConnection(){
Class.forName("전체드라이버클래스명넣기")(드라이버 로딩작업)
cf.("oracle.jdbc.driver.OracleDriver")(검색해도 나옴)
DriverManager.getConnection("데이터베이스url주소","사용자 계정명","비밀번호")
cf) return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "chan(아이디)", "chan(비번)"); //db연결
}

3-2. 실제 자료를 입력하고 수정하고 삭제하고 / 조회하는 각각의 메서드를 만든다.
-입력과 수정과 삭제 작업은 테이블의 자료가 변경이 된다.
=>executeUpdate메서드를 사용 =>정수를 반환함.
-조회 작업은 어떠한 작업을 하더라도 테이블의 자료가 변경되지 않는다.
=>executeQuery 메서드를 사용 =>ResultSet을 반환함.
-실제 메서드 만들어보기
1.자료 변경작업
1-1. 공통작업
=> 반환타입은 void이거나 int이다. 매개변수는 DTO타입의 자료이다.
=> 필요한 객체(데이터베이스 동작을 위한 자원)는 Connection(DB연결)과 PreparedStatement(쿼리 실행)이다.

1.2. 입력과 수정과 삭제작업시 변경되는 항목
1.2.1. 매서드의 매개변수
1.2.2. 쿼리문
1.2.3. 물음표(데이터)의 개수에 따른 매칭작업

public int insertOne(Member mem){
	int result=0;
	Connection con = null;
	PreparedStatement pstmt = null;	
	con=getConnection();	
	pstmt = con.prepareStatement("insert 쿼리문");	
	  //이부분에 쿼리문의 ?개수만큼 데이터를 매칭시켜주는 작업 필요
	result=pstmt.exexuteUpdate();
	pstmt.close();//자원을 반납하는 구문이 필수임 여는거의 역순으로 닫아줌
	con.close();  //자원을 반납하는 구문이 필수임 여는거의 역순으로 닫아줌
	return result;
}

  • 비트연산자

<< 쉬프트 연산자
예) a 2^n == a<<n , a/2^n == a>>n
예) 4<<2 == 4
2^2 , 4>>2 == 4/2^2 이진수로 변환하여 옮겨주는거라서 연산속도가 더 빠르다.

& 이진수 각각 자리에 and연산자를 해주는 것과 같음
예) 이진수 0101, 0011 이 있을 때 둘 다 1인 것만 1을 출력한다. 따라서 0001이 출력된다.
| 이진수 각각 자리에 or연산자를 해주는 것과 같음
예) 이진수 1001 0001 이 있을 때 둘 중 하나만 1이어도 1을 출력한다. 따라서 1001이 출력된다.

%,| 연산자를 사용할 때 앞에 오는 숫자에 따라 연산속도에 더 차이가 생길 수 있다.
&의 경우 먼저 확인하는 숫자가 1이 아니면 뒤에 오는 숫자를 확인할 필요도 없이 0을 출력하게 된다.
|의 경우 먼저 확인하는 숫자가 1이면 뒤에 오는 숫자를 확인할 필요도 없이 1을 출력할 수 있게 된다.


  • 데이터베이스 암호화

비밀번호를 데이터베이스 테이블에 담을 때 예) 1을 더해서 저장을 해주면 그게 암호화임.


  • 다형성

큰 타입에 작은 타입를 집어 넣을 수 있다.
예) 객체를 생성할 때 매개변수에 부모클래스를 넣으면 더 넓은 범위를 사용할 수 있다.


  • 자바 테스트 라이브러리 추가

프로젝트 우클릭- 빌드 패스 - 컨비규어 패스 - 라이브러리 - 클래스 패스 클릭 후 -우측 애드 라이브러리 junit 누르고 apply 그러면 src에 JUnit5가 생김( 단위테스트 라이브러리)


  • 테스트 패키지 (junit test)

테스트 패키지 하나, src 패키지 하나를 만든다.
테스트 패키지 안에 있는 클래스에는 @Test를 쓰고 public으로 써줘야 한다.
처음 생성되는 모듈을 지우고나서 @Test에서 컨트롤 스페이스바 눌러서 임포트해준다.

import org.junit.jupiter.api.Test; //junit import

	public class ScrTest {
	
		@Test
		public void objTest() {
		}
	}

		@Test
		public void objTest() {
			Scanner scan = new Scanner(System.in); 	//키보드로 부터 입력받겠다.
			String inputData = scan.next(); 		
 		    //문자열 입력받음 입력한 글자수는 반드시 5글자로 이루어져야 한다고 가정하고 테스트를 하고자함.
			assertEquals(inputData.length(),5); 		
  			//junit이 있을 때 테스트 하는 법, 두 데이터의 비교
			assertNotNull(inputData); 			
  			//junit이 있을 때 테스트 하는 법, 데이터가 null이 아닌지 확인

cf)Scanner scan = new Scanner(System.in); 
  //키보드로 부터 입력받겠다. 
  //cf. in은 시스템의 기본 입력장치라서 키보드이다. 
  //그러나 설정변경을통해 다른것으로 바꿀 수도 있긴하므로 무조건 키보드인 것은 아니다.
cf)scan.next(),scan.nextInt(), scan.nexFloat() 등등  //(각각 문자열 , 정수형, 실수형 입력받음)


//@Test가 붙어 있는 부분만 테스트를 할 수도 있고 클래스 전체를 테스트 할 수도있다.
		
		public class ScrTest { //ScrTest를 누르고 테스트 할 수 있음(아래 2가지 테스트)
	
		Big obj = new Big();
		
		@Test
		public void objTest() { //objTest만 테스트 가능 (1가지 테스트)
			
			assertNotNull(obj);
		}
		@Test
		public void rtnValueTest() { //rtnValueTest만 테스트 가능 (1가지 테스트)
			
			assertEquals(obj.getMoney(), 300);
			
		}
}

  • 상속, superclass

class를 만들 때 superclass가 있다. 기본적으로는 object로 되어 있다. (=>모든 클래스는 직, 간접적으로 Object class의 후손이다.)
상속받을 class를 지정해줄 수 있다. 자식class이름 옆에 extesnds 부모 class를 적어서 상속받을 수도 있다.
Middle class를 만들 때 super class에 Big class를 넣어주면 Middle class안에 Big class가 전부 들어있다고 생각하면 된다.


  • 클래스 다이어그램

class다이어그램 class uml에서

부모클래스 <- 자식클래스 형태로 표현한다.

부모클래스에 클래스 이름, 필드, 메서드 순으로 적어준다.
예)
Big
+int money //+는 public 의미
+getMoney() int

<- (화살표 방향은 부모쪽으로 향함)

Middle
+int money2
+setMoney(int) void

자식클래스에도 클래스 이름, 필드, 메서드 순으로 적어줌


  • 객체에서의 형변환

public class ScrTest {
		Object obj = new Small();		
		}
		@Test
		public void rtnValueTest() {			
			assertEquals(((Small) obj).getMoney(), 300) //형변환
			assertEquals(obj.getMoney(), 300); //오류		 
		}
}

Big <- Middle <- Small class로 상속관계가 있을 때
Small을 Object 형으로 만들었다.
이런경우 obj에는 원래 Object에만 들어있는 메서드만 보이고 getMoney라는 메서드는 안보인다.
따라서 메서드를 사용하기 위해서는 형변환을 해줘야한다.
((Small)obj) 로 데이터 타입을 바꾸고 묶어서 불러준다.
Object로 썼을 때는 이런식으로 쓰면 되지만 보통은 Object로 쓰는 경우는 거의 없다.
(cf. 클래스간의 상속은 단일상속만 가능하다. 다중상속이 불가능하다( 여러 클래스를 상속받는것 x)


  • override

상속 관계 Big<-Middle<-Small

Big.java
public class Big extends Object {
	public int money = 300;
	
	public int getMoney() {
		return this.money;}
		
	public void setMoney(int money) {
		this.money=money;

	}

Middle.java
public class Middle extends Big {

	@Override
	public void setMoney(int money) {
		this.money=super.money+money;
		
}}

Small.java
public class Small extends Middle{

}

@Override  // 부모 class에서 쓴 메서드를 물려받는데 내용을 바꿀 때 사용
public void setMoney(int money) {
		this.money=super.money+money;}

public static void main(String[] args) {
		Big obj = new Big();
		printInfo(obj);    //300 출력
		obj = new Middle();
		obj.setMoney(3000); //3300 출력
		printInfo(obj);
		obj = new Small();
		obj.setMoney(12000); //12300 출력
		printInfo(obj);
		
	}
	
	public static void printInfo(Big obj) {  //매개변수에 상위클래스에 해당하는 것을 넣어주는 것이 좋다.
		System.out.println(obj.money);
	}

  • 상속, override
Exsuper.java
public class Exsuper {
	public void prn() {
		System.out.println("맹구~~~없다.");
	}

	public Exsuper() {
		super(); //Object(); 랑 동일한 의미
	}
	
}

Exsub.java
public class Exsub extends Exsuper{
	public void prn() {   //부모가 가진 메서드를 가져오고 변화를 주는거 오버라이드이라고 함.
		System.out.println("영구없다.");
	}

	public Exsub() {
		super(); //Exsub();과 동일한 의미 super는 부모클래스를 의미함
	}

}

UsemExam.java
public class UseExam {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Exsuper obj = new Exsub(); //조상타입으로 쓰는게 좋다
		//ExSub obj2 = new Exsub(); // 안좋은 방법		
	}
	public static void printInfo(Exsuper obj) { 
      //매개변수도 상위타입을 적어줄것( 그러면 하위 타입들의 값도 들어올 수 있다.)
		obj.prn();
	}
}


Exsuper obj = new Exsub();에서
stack영역에 Exsuper obj가 만들어지고
heap영역에 Object라는 객체가 만들어지고 그 위에 Exsuper, 그 위에 Exsub이 겹쳐지면서 만들어진다.

printInfo(new Exsub());   // 영구없다 출력 (오버라이딩 되었기 때문)
printInfo(new Exsuper()); // 맹구없다 출력


  • 오버로딩 오버라이딩

오버로딩 부모거 물려받아서 메서드 이름은 같은데 매개변수가 다를 때
오버라이딩 부모거 물려받아서 메서드 이름 같고 매개변수도 같은데 기능 추가하거나,내용을 추가할 때.

@ <- 주석인데 기계(컴파일러)한테 알려주는 주석임 ,메타데이타
예) @Override

cf) 패키지 이름은 모두 소문자로 쓸 것. 카멜표기법 x


  • static

static은 외부class 앞에는 붙을 수 없음.
중첩클래스 필드,메서드 부분에 붙일 수 있음(지역변수에도 당연히 못붙임).

)
public class StaticExam01 { //클래스(외부 클래스) => static(정적) 사용 불가
	public static int var1; 
     //정적 필드,heap영역이 아니라 static영역(?)에 생성됨 (엄밀하게는 static영역은 없음)
	public int var2; //인스턴스 필드
	public static int method1() { //메서드
		int rtnValue = 0;
		return rtnValue;
	}
	public int insMethod01() { //인스턴스 메서드 => 객체가 생성이 되어야만이 사용할 수 있는 메서드
		return 100;
	}

	public class innerC { //중첩(내부, 멤버 정적)클래스 static 사용가능 //굳이 쓸필요는 없다.
		
	}
}



public class UseExam {

	public static void main(String[] args) {
		System.out.println(StaticExam01.var1);
		System.out.println(StaticExam01.method1()); //생성 없이도 바로 사용 가능
		StaticExam01.insMethod01(); // 생성을 해야지 사용가능
		StaticExam01 obj = new StaticExam01(); //생성
		System.out.println(obj.var2); //사용
		obj.insMethod01(); //사용
	}

}

static은 객체 생성 없이 곧바로 사용가능.
static : 응용프로그램이 실행되기 이전에 먼저 메모리에 생성이 된다.
static은 제일먼저 생성되어서 맨 나중에 사라짐.


  • final
public final class  FinalExam01 { //상속을 금지하는 클래스이다. 최종적인 클래스
								  //final public class로 써도 되기는 함. 
}


public class FinalExam02 {
	 //final이 붙어있는 변수 (필드, 지역변수) : 메모리에 만들어지는 시점에서 반드시 초기 값을 가져야 한다. 
     //=>변경이 불가능하다.
	final int k; 
     //값이 객체를 생성하는 시점에서 만들어지는 필드 변수다, <=생성되는 시점에서 초기화 되어야 한다. 
     //여기까지만 적었을 때는 에러메세지가 나온다. 메서드에서 k에 대한 정의가 필요하다.
	final static double pi=3.1492; 
     //로드되는 시점에서 만들어지는 필드 변수(static영역에) 생성되기도전에 만들어지니까 
     //<= 무조건 초기화를 해야 한다. 
	
	FinalExam02(){
		k=300; //기본적으로는 300의 값을 갖는다
	}
	FinalExam02(int data){
		k=data; //따로 지정한다면 이 값을 갖게 한다.
	}
	
	
	public final int rtnValue() { //상속하는 클래스에서 이 메서드를 오버라이딩할 수 없다.
		return k*30;
	}
	
	public void testMe() {
		final int var;
	}
}

UseFinalTest
	public static void main(String[] args) {
		FinalExam02 obj1=new FinalExam02();
		System.out.println(obj1.k);   //300 출력 기본적으로 값은 300
		FinalExam02 obj2=new FinalExam02(5000);
		System.out.println(obj2.k);
    //5000출력 만약 생성할 때 k의 값을 지정하면서 생성하면 지정해준 값으로 됨
	}

  • interface 사용하여 상수필드 변수 정의 ★

class 각각에 상수필드변수를 정의하지 말고
new-interface- ConstDefine이라는 이름의 interface를 만든 후

 	public interface ConstDefine { 
		double PI=3.141592; // 앞에 final static이 적혀있는 것과 같다.
}

다른 class에서 불러올 때 
ConstDefine.PI 라고하면 3.141592가 불러와짐.

프로젝트에 사용되는 모든 상수필드 변수는
interface에 모아서 정의해두는 것이 중요하다.


  • abstract
AbstractExam01.java
public abstract class AbstractExam01 {//추상 클래스=> 직접 객체 생성을 금지
	public void pt() { //일반적인 인스턴스 메서드
		System.out.println("영구없다.");
	public abstract double calcu(double d1, double d2); //추상메서드를 정의해서 캡슐화 해주는 것
	
	}
}

Sub.java
public class Sub extends AbstractExam01{
	@Override
	public double calcu(double d1, double d2) {  
  //추상메서드는 상속받은 클래스에서 구체화를 시켜야 한다. 
  //메서드의 구체적인 내용을 상속받은 클래스에서 기술하도록 하는 것.
	return d1*d2;   
	}

}

TriCalcu.java
public class TriCalcu extends AbstractExam01 {
	
	@Override
	public double calcu(double d1, double d2) {
	return d1*d2/2;
	}

}

UseabstractExam.java
public class UseabstractExam {

	//추상클래스를 바로 받을 수는 없고 상속받은 클래스로 객체를 생성한다.
	public static void main(String[] args) {
	calResultPrn(new RecCalcu()); // 사각형 계산 출력
	calResultPrn(new TriCalcu()); //삼각형 계산 출력 
	}
	
	public static void calResultPrn(AbstractExam01 obj) {
		System.out.println(obj.calcu(50, 20));
	}	
} 
 이처럼 추상화를 사용하면 병렬식으로 진행할 수 있고, 협업이 편해진다.

추상 메서드가 하나라도 있을 경우 반드시 추상 class여야 한다.
추상 메서드 없이 인스턴스 메서드로만 이루어져도 가능하다.

추상메서드- 상속받은 클래스에서 추상메서드를 일반 메서드처럼 구체화를 시켜야 함


  • 객체 지향 특징

1.캡슐화 (class를 정의하는 것)
-캡슐화가 곧 data의 은닉이 아니라, 캡슐화의 결과가 data의 은닉이다.
-관련성 있는 data끼리 묶어준것. (캡슐안에 어떤 감기약들이 있는지 잘 모르는 것과 같음)
2.상속
3.추상화
4.다형성


  • Interface
  1. java는 설계(design)가 중요한데 설계에 도움이 된다.
  2. 추상화가 가능하다.(Abstract) -통일성 확보, 순차적 개발이 아닌 병렬 개발이 가능하다, 변수 분할이 가능하여 책임소재가 분명해진다.
  3. 일반 인스턴스 메서드가 존재할 수 없다
    (1.8버전부터는 일반 메서드에 default 메서드, static메서드는 있으나 가능하면 쓰지 않는 것이 좋다. 설계가 잘 되었다면 쓰이지 않아도 되기 때문이다.) 모든 메서드가 추상메서드이다. 모든 필드는 상수형 필드이다.
  4. 클래스-> 클래스로 바로 영향을 주기보다, 클래스 -> 인터페이스 -> 클래스로 영향을 주는 방식이 중요하다.
  5. 필드만 따로 지정해주는 인터페이스를 만드는 것이 좋다. (예) ProjectConstData
    인터페이스는 프로젝트에 사용되는 상수형들을 선언한다.
  6. 인터페이스의 모든 필드는 static final이다.인터페이스의 모든 멤버는 public이다. 예) double PI=3.14; //public static final double PI=3.14;와 동일하다. 따로 붙이지 않아도 적용되어 있다.
  7. 인터페이스의 모든 메서드는 abstract이다. 예)void calcu(); //public abstract void calcu();와 동일하다.
  8. 의미론적인 인터페이스 => 내용물이 아무것도 없는 인터페이스(예)Serialize 등)
    함수형 인터페이스(@FunctionalInterface 를 보통 맨 위에 붙여준다. 메서드가 2개 이상이 되면 에러가 나서 일반적으로는 붙여준다.) => 메서드가 한 개만 존재하는 인터페이스 => 화살표메서드(람다식)로 구현한다.
    메서드가 하나인 인터페이스들 (java 1.8) : Supplier, Consumer, Function, Predicate, Operator
  9. 클래스-클래스는 다중상속이 안되지만, 인터페이스-인터페이스는 다중상속이 가능하다. 예) public interface SubInterExam01 extends InterExam01, Serializable{} (cf.여기서 Serializable는 내용이 존재하지 않는 인터페이스)
  10. 인터페이스를 구현하는 class는 클래스이름 뒤에 Impl을 붙여준다. 구체화되는 class라고 표현함. 예)public class SubInterExam01Impl implements SubInterExam01 (구현을 표현하는 방법) (상속은 실선, 구현은 실선으로 표시한다.)
    (SubInterExam01의 메서드를 구체화 한다. )
  11. 구현 테스트 해보기 메인 클래스에서 예) InterExam01 obj = new SubInterExam01Impl(); 를 해준다. 인터페이스는 타입으로 쓰일 수는 있지만 객체를 만드는데에는 사용될 수 없다. 따라서 obj앞에 타입으로는 쓰였지만 new뒤에는 구현해주는 class를 적어준다.
    위의 방법도 괜찮은 방법이지만 더 좋은 방법이 있다.

Factory방식


  방법 1.
  public class ObjectCreateFactory { //새로운 class를 만들고
	public static InterExam01 createObj() { //static형식으로 생성. 
  				//타입은 가장 큰 그릇에 해당하는 InterExam01로 만들어줌
		return new SubInterExam03Impl(); // createObj()를 호출하면 필요한 객체를 호출하도록 함. 
  										//나중에 유지보수를 할 때 여기서만 바꿔주면 됨.
	}
}

//그 후 main 클래스에서 아래와 같이 만들어주면 된다.
  
InterExam01 bestObj = ObjectCreateFactory.createObj();	
bestObj.calcu();  

 방법 2.
main 클래스는 위와 동일

ObjectCreateFactory.java class를 만들고

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ObjectCreateFactory {
	public static InterExam01 createObjText() {
//구체적으로 어떤 클래스를 생성해야 하는지는 알 수 없다.
//=> 외부정보(파일의 내용)를 통해서 구체적인 객체를 생성한다. 
//메모장파일(objectCreateList.txt)에 생성해야 할 클래스 이름을 작성한다.
//1) 메모장 파일에 작성된 클래스 이름을 읽어서(FileReader,Scanner등 방법)
//2) 그 객체를 생성한 후에 3)반환한다.
		Scanner scan=null; //필드에 Scanner 선언
		String readClassNameData=null; //읽어오는 변수 readClassNameData 필드에 선언
		try {
			scan = new Scanner(new File("objectCreateList.txt"));  //txt파일에서 읽어오기
			readClassNameData = scan.nextLine(); 			//파일에서 읽어온 내용 넣기
			Class <InterExam01>t = (Class<InterExam01>) Class.forName(readClassNameData);
  			//<InterExam01> = 선언할 때 바뀔 내용을 알려줌
  
			//return t.newInstance(); 구버전 방법
			return t.getDeclaredConstructor().newInstance(); //신버전방법 , 만든 클래스 반환
		} catch (FileNotFoundException e) {
			e.printStackTrace(); //가져올 내용이 없을 때
		} catch (ClassNotFoundException e) {
			e.printStackTrace(); //가져올 내용이 없을 때
		} catch (InstantiationException e) {
			e.printStackTrace(); //가져올 내용이 없을 때
		} catch (IllegalAccessException e) {
			e.printStackTrace(); //가져올 내용이 없을 때
		}
		/*(cf.  } catch (Exception e) {
			e.printStackTrace(); }
  가져올 내용이 없을 때 모든 거 다 쓸 필요없이 Exception으로 한번에 처리할 수도 있다.)*/
  
		return null; //가져올 내용이 없을 때 null값 반환
	}
}

  
objectCreateList.txt 파일
objectCreateList.txt라는 텍스트 파일을 패키지 밖, src폴더 안에 위치 시킨다.
interfaceExam01.SubInterExam01Impl 내용 : (패키지이름.가져올 클래스이름)

이렇게 적으면 앞으로 유지 보수가 필요할 때 원래 내용을 건드릴 필요없이
새로운 클래스를 만들고 텍스트 파일에 클래스 이름만 바꿔주면 된다.

  • Factory 추가 (txt 파일에 클래스 이름이 여러개 들어갈 때)
Factory Class에서
public class ObjectCreateFactory {

	public static InterExam01 createObjText() {
		Scanner scan=null;
		StringBuffer readClassNameData=new StringBuffer();
		try {
			scan = new Scanner(new File("objectCreateList.txt")); 
			String rData = null;
			while (scan.hasNextLine()) { //내용이 있으면 True 반환함
				rData=scan.nextLine();
				readClassNameData.append("/"+rData); // "/"로 클래스 이름을 구분해줌
			}
			String[] objNameList = (readClassNameData.substring(1).toString()).split("/"); 
  				//substring(1) =인덱스1번부터 시작하기 (맨 앞에 /가 들어가기 때문에 써줌)
			Class <InterExam01>t = (Class<InterExam01>) Class.forName(objNameList[2]); 
  				//objNameList[2]의 인덱스 숫자만 바꾸면 다른 클래스 볼 수 있다.
			return t.getDeclaredConstructor().newInstance(); 

		} catch (Exception e) {
			e.printStackTrace();
		}	
		return null;
	}
}

  • 문자열을 쓸 때 String, String Buffer(or Builder)

String, StringBuffer(or Builder) 등이 있다.
문자열에 추가를 한다고 할 때 String의 경우 기존 문자열이 위치한 곳에 더하는 것이 아니라, 새로운 주소를 만들고 값을 생성한다. 즉, 기존에 있던 데이터는 쓰레기 데이터가 된다.
반면 StringBuffer(or Builder)는 원래 데이터 주소에 문자열을 추가할 수 있어서 메모리 효율이 좋다.
단, 이경우 append를 사용하여 추가해야 한다.


  • 인터페이스 구현체 만드는 방법
구현체 클래스 
MyInterImpmpl.java

public class MyInterImpl implements MyInter{

	@Override
	public int sum(int[] nums) { //몇개를 넣을지 모를 때 배열로 매개변수를 주기
		int result=0;
		for(int i=0; i<nums.length; i=i+1) {
			result +=nums[i];
		}
		return result;
	}

}

main 클래스

public class UseMyInter {

	public static void main(String[] args) {

		//방법 1. 구현체 클래스 만든상태일 때
		MyInter obj=null;
		obj= new MyInterImpl(); //구현체 클래스를 만들고 그 구현체 클래스를 생성
		System.out.println("숫자들의 합"+obj.sum(new int[] {1,23,36,45,87}));
		
		//방법2.
		//따로 클래스를 만들지 않고 사용하는 방법(권장하지는 않음)
        //단,라이브러리 함수형 인터페이스는 이방법 권장
		//익명의 클래스를 직접 만들어서 사용한다.
		MyInter obj2 = new MyInter() {
			
			@Override
			public int sum(int[] nums) {
				int result=0;
				for(int i=0; i<nums.length; i=i+1) {
					result +=nums[i];
				}
				return result;
			}
		};

		System.out.println("숫자들의 합"+obj2.sum(new int[] {1,2,3,4,5})); 
		
		//방법 3. 익명의 클래스를 직접 만들어서 사용한다.
  		// => 람다식을 이용하는 방법(단, 인터페이스는 반드시 함수형이어야 한다.(메소드가 하나))
		MyInter obj3 = (nums) -> {
			int result=0;
			for(int i=0; i<nums.length; i=i+1) {
				result +=nums[i];
			}
			return result;
		};
		
		System.out.println("숫자들의 합"+obj3.sum(new int[] {10,20,30,40,50})); 
}	
}

  • startswith, endswith 효율적으로 사용

실무에서 이를 효율적으로 사용하는 법.
데이터를 배열에 넣어서 startswith, endswith를 활용하여 가져오고 자동화를 한다면 효과적인 데이터를 만들수 있다.


imgfilelist라는 폴더에서 파일을 탐색하는 클래스를 만든다.

public class DirFileList {
	public static String[] dirFileRead(){
		File file = new File("./imgfilelist");
		//문자열 배열로 반환해준다.
		return file.list();
	}
}


main 클래스에서 목록 정리

public class StringLibTest {
	public static void main(String[] args) {
		String[] rtnFileList = DirFileList.dirFileRead();
		List<String> fileFilterList =new ArrayList<String>(); 
  	 	//.png로 끝나는 파일 목록을 저장할 가변 배열
		int fileCount = rtnFileList.length;
		for(int i=0; i<fileCount; i=i+1) {
			if(rtnFileList[i].endsWith(".png")) { //png로 끝나는 파일 배열에 집어 넣기
				fileFilterList.add(rtnFileList[i]);
			}
	}
		
		System.out.println("===결과 출력 ===");
		int filterCnt = fileFilterList.size();
		for(int i=0; i<filterCnt; i=i+1) {
		System.out.println(fileFilterList.get(i)); //.png로 끝나는 파일들만 출력된다.
	}}
}

  • 정규 표현식

\\s+ = 하나 이상의 공백 문자와 동일하다.
예) .split(" ") //이렇게 나눠줄 경우 잘못 나눠서 공백을 두번 주거나 하면 오류가 생긴다.
따라서 .split("\\s+") //이렇게 나눠줄 경우 실수로 여러번 공백을 주고 나눠도 제대로 나눠진다.


  • StringBuffer
1) 기본형
StringBuffer sb01 = new StringBuffer(); 
System.out.println(sb01.capacity()); //16출력, 기본은 16개의 문자가 들어갈 수 있는 용량이 생성됨2) 용량 지정
StringBuffer sb01 = new StringBuffer(20);
System.out.println(sb01.capacity()); //20출력, 20개의 문자가 들어갈 수 있음
sb01.append("qadpajsdghhf");
System.out.println(sb01.capacity()); //20출력, 20개 미만이 들어갈 때는 용량을 늘리는 과정을 생략함3) 용량지정, 추가 용량
sb01.append("qwertysdwdqdqdqdqeqeSqdqqadauiipajsdghhf");
System.out.println(sb01.capacity()); //42 출력, 더 많은 양이 들어오면 용량을 늘리는 과정을 거침
따라서 용량의 크기를 어느정도 잡아주는 것이 권장됨.4) 남는 용량 제거
StringBuffer sb02 = new StringBuffer("qwqqrwegewgewgewgewgge");	 	
System.out.println(sb02.capacity()); //38출력		
sb02.trimToSize(); // 남는 용량 없애줌
System.out.println("trimToSize 후 용량 =>"+sb02.capacity()); //22출력, 알아만 두기5) 출력 예시
System.out.println(sb02); //qwqqrwegewgewgewgewgge출력
System.out.println(sb02.toString()); //위와 동일
System.out.println(sb02.reverse()); //eggwegwegwegwegewrqqwq 반대의 값 출력.
//reverse()는 String에는 없는 method이다. 
//String으로 쓸 때는 직접 뒤집어서 쓸 수 있어야 하고, 혹은 StringBuffer타입을 사용한다. 
//이를 이용하여 암호화를 할 수도 있다.6) 타입 변환 StringBuffer(Builder)타입 문자열을 -> String 타입으로 변환하는 방법들

StringBuffer sb02 = new StringBuffer(); //sb02는 StringBuffer타입
(sb02+"") //모든 데이터타입은 문자열("")을 추가해주면 문자열로 저장된다.
(sb02.toString()); // .toString => String 타입으로 변환해주는 방법
(new String(sb02)); //String(StringBuffer or Builder타입 넣기) => String타입으로 변환해주는 방법7) StringBuffer타입을 이용하여 reverse() method사용
String sourceData = "abcdefg"; // String타입 데이터
String reversData =new StringBuffer(sourceData).reverse()+""; 
//StringBuffer타입을써서 reverse를 사용하고 +""를 해줘서 다시 String형으로 바꿔서 저장함.
System.out.println(reversData); //String타입이고,  gfedcba 출력8)알고리즘을 이용하여 문자열을 뒤집어서 출력하기
int strCnt=sourceData.length(); //문자열의 길이를 strCnt에 저장
for(int i=0;i<strCnt; i=i+1) {
	System.out.println(sourceData.charAt(strCnt-1-i)); 
                    //맨 뒤의 인덱스 번호에 해당하는 문자를 하나씩 출력
	}
	System.out.println();
}

혹은 아래의 방법도 가능하다.

for(int i=strCnt-1;i>=0; i=i-1) { 
	System.out.println(sourceData.charAt(i));
}9)  알고리즘을 이용하여 문자열을 뒤집어서 저장하고 출력하기
String sourceData = "abcdefg";
int strCnt=sourceData.length();
StringBuffer revTarget = new StringBuffer();
	for(int i=0;i<strCnt; i=i+1) {
		revTarget.append(sourceData.charAt(strCnt-1-i));  // 뒤집어서 하나씩 넣어줌
	}
	System.out.println(revTarget.toString()); //gfedcba 출력10)원자료로 복원
	int revLen = revTarget.length();
	StringBuffer recData = new StringBuffer();		
	for(int i=revLen-2; i>=0; i=i-1) {
		System.out.println(revTarget.charAt(i)); //뒤집어서 하나씩 출력
		recData.append(revTarget.charAt(i)); //복원
	}
	System.out.println(recData); //abcdefg

  • 문자열에 특정 문자 반복횟수 확인법
)
String datas = "누구나 한번쯤은 사랑에 속고 누구나 한번쯤은 사랑에 울고 그것이 바로 사랑 사랑이야 철부지
  어렸을 때 사랑을 몰라"
		
/*원하는 단어를 indexof를 이용해서 찾는다 -1이 나올 때까지 <= 반복 while( for문도 가능)
  맨처음에는 0부터, 그다음은 찾은위치 다음부터*/
int startPos =0;
int resultPos=0;
int wordFindCount=0;
while((resultPos = datas.indexOf("사랑", startPos)) != -1) { //없을 때까지 반복
	startPos = resultPos+1;  //찾은 문자 다음 숫자부터 검색 시작
	wordFindCount = wordFindCount +1; //찾으면 하나씩 추가
	}
	System.out.println("사랑 개수 :"+wordFindCount); //찾은 개수 출력
}

  • java util 중 Map

Properties, HashMap가 자주 쓰인다.
Map은 key와 Value 한쌍으로 이루어진 자료형이며, Value는 중복될 수 있지만 key는 고유한 값을 가진다.

Map사용 예)
String datas = "누구나 한번쯤은 사랑에 속고 누구나 한번쯤은 사랑에 울고 그것이 바로 사랑 사랑이야 철부지 
  어렸을때 사랑을 몰라";

String[] words = datas.split("\\s+"); //긴 문장을 이루고 있는 단어들을 분리하여 배열에 저장
Map<String, Integer> wordCountMap = new HashMap<>(); /*Map에서 Key는 문자열이고, 개수는 정수형이라 
  String, Integer를 사용(int가 아님)*/
for(String word : words) {  //String 배열 words안의 값들을 word에 하나씩 대입해보라는 뜻
	int startPos =0;
	int resultPos=0;
	int wordFindCount=0;
	while((resultPos = datas.indexOf(word, startPos)) != -1) {
		startPos = resultPos+1;
		wordFindCount = wordFindCount +1;
	}
		wordCountMap.put(word, wordFindCount);
		System.out.println(word+" 개수 :"+wordFindCount);
	}
		
Set<String> keyset = wordCountMap.keySet(); //key값을 구하는 공식, key값은 중복이 안됨
Iterator<String> iter=keyset.iterator();
while(iter.hasNext()) {  //내용이 있으면 진행
	String wordName = iter.next(); //키값을 저장
	System.out.println( wordName+ "=> 개수:"+wordCountMap.get(wordName));} //중복을 제거하여 출력됨

  • if문을 최소화 하는 방법 참고
)
int jumsu = 84;
//점수를 입력받아서 수,우,미,양,가를 출력하는 프로그램을 작성하시오.
//점수를 입력받아서 A+ A0 B+ B0 ... F학점으로 출력하는 프로그램을 작성하시오
if(jumsu>=90 && jumsu<=100) System.out.println("수");
if(jumsu>=80 && jumsu<90) System.out.println("우");
if(jumsu>=70 && jumsu<80) System.out.println("미");
if(jumsu>=60 && jumsu<70) System.out.println("양");
if(jumsu<60) System.out.println("가");

/*if else else if 등등 쓸 수 는 있으나, 그럴경우 아래와 같은 방식이 떠오르지 않을 수 있다. 
if문으로만 쓰는 것 지향. */

//아래와 같은 방식은 더 간단하게 작성 가능

String pg = "가 가 가 가 가 가 양 미 우 수";
System.out.println(pg.split("\\s+")[jumsu/10]);  //점수에 따라 수우미양가 출력

String pge = "F F F F F F F F F F F F D0 D+ C0 C+ B0 B+ A0 A+";
System.out.println(pge.split("\\s+")[jumsu/5]); //점수에 따라 A+등 출력		

  • 참조 타입의 비교 .equals(), == 상자의 자료(값)를 비교한다.
1)
int k=4; int l =4;  // k==l; =>true2)
String is= "aa" String js="aa" // is==js ==>true
//먼저 heap영역안에 문자열, 상수영역이 있어서 이 영역에 "aa"가 생성됨 (is)
 js를 만들 때 "aa"가 있는지 확인하고 있다면 그 주소를 가르킴. 그래서 서로 같음

예3)
String is= new String("aa") String js= new String("aa") // is==js ==>false  
//먼저 heap영역안에 문자열, 상수영역이 있어서 이 영역에 "aa"가 생성됨 (is)
그 영역안에 있는 aa를 가르키는 주소를 담고 있는 내용을 heap영역에 생성함.
이때 is일때 한번, js일 때 다른 한번 주소를 생성하기 때문에 값이 다른것이다.4)
String is= new String("aa"); //new는 힙영역에 생성
String js= new String("aa"); //new는 힙영역에 생성
System.err.println(is + "       " + js); // aa   aa 출력
System.out.println(is==js);   /* false 출력, 안의 내용 aa끼리 비교한 결과가 아니라 aa를 담고있는 각각의
주소값끼리를 비교한 결과라서 false가 출력된다.*/

이러한 문제들이 있기 때문에 참조형데이터(객체).equals()를 사용하여 비교해준다.5)
System.out.println(is.equals(js)); //true   

public class DataObj {
	int aaa=123;
	int bbb=1200;
	int ccc=300;
	@Override
	public int hashCode() {
		return Objects.hash(aaa, bbb);
	}
	@Override //hashCode()equals 해줘서  equals의 내용을 정의한 후
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DataObj other = (DataObj) obj;
		return aaa == other.aaa && bbb == other.bbb;
	}

DataObj obj1 = new DataObj();
System.out.println(obj1.aaa+ "  , " +obj1.bbb+",   "+ obj1.ccc); //123  ,  1200  ,  300
DataObj obj2 = new DataObj();
obj2.ccc=32580;
System.out.println(obj2.aaa+ "  ,  " +obj2.bbb+ ",   "+ obj2.ccc); // 123  ,  1200  , 32580
System.out.println("==비교결과"+ (obj1==obj2));  //주소값이 각기 다르기 때문에 false
System.out.println("equals비교결과"+ (obj1.equals(obj2))); }

/*위에서 equals를 정의해줬기 때문에 true로 출력된다. ,ccc의 값이 각기 다르지만 같다고 출력이 된 이유는 
위에서 equals를 정의할 때 aaa와 bbb만 같아도 같다고 했기 때문이다. 일반적으로 데이터가 같게 하지만 데이터가 
달라도 equals를 어떻게 정의하느냐에 따라 다르다는 것을 알아야 한다. hashcode()equals를 source에서 고를때 
어떤값이 같으면 같다고 정의할 것인지 각각 선택할 수 있다. 
equals를 정의하지 않으면 Object의 equals로 나온다. 이는 아무런 결과도 내려주지 못한다.*/
	
	

  • List 와 Map
List<String> list = new ArrayList<>(); //키 값은 숫자로 고정, 데이터만 문자열 
list.add("data1");
list.add("data2");
System.out.println(list.get(0)+ "리스트 자료의 개수 :"+list.size() ); //2출력
String[] listArr= {"data1","data2"};
//String[] listArr = new String[2]; listArr[0]="data1";;istArr[2] = "data3";

//리스트 처럼 Map사용

Map<Integer, String> map =new HashMap<>();
map.put(0, "data1"); map.put(1, "data2"); 
System.out.println(map.get(0) + "map 자료의 개수" + map.size()); //2출력
map.put(2, "data1");
System.out.println(map.get(0) + "map 자료의 개수" + map.size()); //3출력
	}

//Map key응용
Map<String, String> phoneInfo = new HashMap<>();
phoneInfo.put("찬", "010-2222-2233");
phoneInfo.put("찬찬", "010-2332-4433");
System.out.println(phoneInfo.get("찬"));
//Map의 형태로 구성된 자료의 활용 => key도 광범위하게 자료로 활용할 수 있다.
	System.out.println(phoneInfo.get("찬"+"찬"));} //	010-2332-4433출력
key에 해당하는 "찬찬"을 연산에도 사용할 수 있다.
key에 "찬찬"이 들어만 가면 값을 가져오니까 문자열처럼 "찬"+"찬"도 가능하고 무궁무진하게 활용할 수 있다.

  • Map을 활용한 file 정리 코드 정리
package libraryExam03;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class RealLibFileListMap {
	public void mapFileList(String rootDirName) { //rootDirName에 폴더 경로 지정 예)"./filelist"
		Map<String, List<String>> mapInfo = new HashMap<>();
		File file = new File(rootDirName); 
		File[] subFiles = file.listFiles();
		for(int i=0; i<subFiles.length; i+=1) {
			if (subFiles[i].isDirectory()) {
				//Map에 key값으로 사용될 목록이다. => subFiles[i].toString().substring(2)
//				System.out.println("key값으로 저장될 문자열"+subFiles[i].toString().substring(2));
				File subDir = new File(subFiles[i].toString()); //subFiles[i]는 파일 타입이라 문자열 형태로 바꿔줌
				String[] subDirList = subDir.list();
//				System.out.println(Arrays.toString(subDirList));
				List<String> list = new ArrayList<>();
				for(int j=0; j<subDirList.length; j=j+1) {
					list.add(subDirList[j]);
				}
				mapInfo.put(subFiles[i].toString(), list);
			}
		}
		
		mapInfoPrint(mapInfo);
		//실제로 출력하는 것이 아니라 클라이언트에게 mapInfo를 네트워크로 넘겨준다.(자바스크립트에서 받을 수 있도록), 여기서는 확인차 출력을 해본것일 뿐. 
	}
	private void mapInfoPrint(Map<String, List<String>> mapInfo) {
		Iterator<String> iter =mapInfo.keySet().iterator();
		while(iter.hasNext()) {
			String keyString = iter.next();
			System.out.println(keyString+"에 저장된 파일목록 : ");
			List<String> list = mapInfo.get(keyString);
			for(int i=0; i<list.size(); i=i+1) {
				System.out.println(list.get(i));
			}
			System.out.println("================================");
		}
	}
}

위 코드를 적용시키기 위한 폴더의 구조
예)
filelist폴더
-1번 폴더
-1번 파일
-2번 파일
-3번 파일

  • ...
    -2번 폴더
    -1번 파일
    -2번 파일
    -3번 파일
    -4번 파일
    -5번 파일
    -6번 파일
    -3번 폴더
    -1번 파일
    -2번 파일
    -3번 파일

  • 비트연산자 ~

비트연산자 ~는 not을 의미한다.

)
System.out.println("정수형 타입의 최대값 :"+ ~(Integer.MIN_VALUE)); //비트연산자~ 는 not을 의미한다.
cf) System.out.println("정수형 타입의 최소값 = (최대값 + 1) :"+ (Integer.MAX_VALUE+1));
cf) ~(음수)+1 => 절대값 도출됨.) ~{-25)+1==25 
cf) ~(25)+1 == -25

  • 문자열을 숫자형으로 바꿔서 계산
)
System.out.println(Integer.parseInt("123")+45); //168
cf) short형은 +계산할때 int형으로 바뀐다.

  • 성능검사할 때 nanoTime() 활용
)
long startTime =System.nanoTime();  //성능테스트 하기전 시간 출력
int sum = 0;
	for(int i=10; i<50; i=i+1) {
		if (i%2==0) {
			sum+=i;
		}
	}
		System.out.println(System.nanoTime()-startTime);//걸린 시간 출력
	}

  • exit()
System.exit(1);  /*문제가 있어서 종료할 때 일반적으로 1적고 문제없이 종료될 때 0 적음.
                   무엇을 적어도 크게 문제되는것은 아님.*/

  • gc()

사용되지 않는 객체(쓰레기 객체)를 제거해달라고 부탁(운영체제에 부탁)는 코드.
여유가 있으면 청소를 해준다.
그러나 굳이 쓸 필요는 없다. 운영체제가 알아서 주기적으로 돌면서 정리하기 때문이다.

StringBuffer sb = new StringBuffer("나일등");
sb.append("맹구");
		
sb=null; //더이상 쓸일이 없다면 null해주는 것이 관리적 측면에서 더 좋긴하다.
sb = new StringBuffer("땡칠이"); 

  • Math 연산자 pow, 비트연산자& 활용
System.out.println(Math.sqrt(4)); //루트를 해주는 연산이지만 아래 방식으로 하는 것 권장함
System.out.println(Math.pow(4,0.5)); //4의 0.5제곱
System.out.println(Math.pow(8,1/3.0)); //8의 1/3 제곱

for(int i=100; i<201; i=i+1) {
	if((i&1)==1) { 
  //홀수를 구할 때 사용 왜냐면 홀수는 이진수 맨마지막이 1이라서 짝수를 구할 때는 i&0==0으로 바꾸면 됨
		System.out.println(i);
	}

  • Random 난수생성
Random rnd = new Random();
	for(int i=0; i<10; i+=1) {
		System.out.println(rnd.nextDouble()); //실수형 난수 생성
		System.out.println(rnd.nextInt());//음수의 난수도 포함하여 생성
		System.out.println(rnd.nextInt(21)+100); 
		//정수형 난수 생성(개수)+시작값 결과)100부터 120까지의 난수 생성
		
		}


Random rnd = new Random(10); /*시드값을 정해줄경우 조건이 같다면 항상 동일한 난수들이 생성된다. 
클라이언트와 같은 난수를 생성하기를 원할 때 사용한다. Math.Random에는 이런 기능이 없다.*/
	for(int i=0; i<10; i+=1) {
		System.out.println(rnd.nextInt(10)+0); 
	}

+cf. 랜덤난수 생성할때 중복되지 않도록 하는 방법 
= > UUID.randomUUID()를 사용한다.

  • Date() , Calendar()

Date now =new Date();
System.out.println("현재 시스템에 설정된 날짜와 시간" + now);
System.out.println(now.getYear()+1900);
System.out.println(now.getMonth()+1+"월");
System.out.println(now.getDate()+"일");
System.out.println(now.getDay()+"일");
	
Calendar cal = Calendar.getInstance(); 
/*Calendar는 protected형이라서 new Calendar()로 불러오진 못한다. 
  대신 static형인 getInstance()를 통해 바로 불러온다.*/
System.out.println("calendar=>" + cal);
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.YEAR)+"년도");
System.out.println((cal.get(Calendar.YEAR) +"년도" +(cal.get(Calendar.MONTH)+1) 
  +"월"+cal.get(Calendar.DATE) +"일"));

  • BufferedFileInputStream, BufferedFileOutputStream

FileInputStream => Byte 단위(txt파일 제외 전부)
FileReader => char 단위 (txt파일)
FileWriter => char 단위 (txt파일)

Byte단위 파일>char 단위 파일 이기 때문에
FileInputStream,FileOutputStream을 주로 쓰고
BufferedFileInputStream,BufferedFileOutputStream를 쓰면 조금 더 빠르다.

cf)서로다른 장치간의 속도차이를 해결하기 위해 중간에서 저장할 수 있는 공간을 buffer라고 한다.

cf) 영문 1byte, 한글 인코딩 방식에 따라 2byte(EUC-KR) or 3byte(UTF-8) 등


  • FileWriter
)
	try {
		FileWriter fw = new FileWriter("test.txt"); //이 파일이 없다면 만들고 있다면 있는 파일을 가져옴
		fw.write("나의 살던 고향은 꽃 피는 산골\n"); 
		  /* \n은 줄을 바로 아래로 이동하는 기능만 있다. 맨앞으로 가는기능이 있지 않다. 
 		     맨 앞으로 간 이유는 텍스트 파일에 있는 설정이 맨 앞으로 보내기 때문이다. */
		fw.write("내가 살아가는 동안에 할일이 또 하나 있지\n",1,3); 
  		 /*인덱스 몇번 부터, 몇글자를 적을것인지 정해준다. 예) 가 살*/
		Scanner scanner = new Scanner(System.in);
			for(int i = 0; i<5; i=i+1) {
				System.out.println("입력하세요");
				String inputString = scanner.next(); 
/*텝키, 공백, 엔터키를 누르기 이전까지 입력받음 띄어쓰기를 하면서 쓰면 5번 띄어쓰기한거까지만 들어감*/
//cf)String inputString = scanner.nextLine(); //엔터키 치기 전까지 입력을 받음 띄어쓰기를 해도 반영된다.
				fw.write(inputString);
			}
fw.write("======문자열 배열로 저장=======");
char[] charArrData = "Chan 형찬 조형찬 찬찬".toCharArray();
fw.write(charArrData);
			fw.close(); //외부자원을 사용했으면 반드시 닫아줘야 함.
		} catch (IOException e) {
			e.printStackTrace();
		}

  • FileReader (수정 필요)
파일 읽기

FileReader fr = null;
	try {
		fr = new FileReader("test.txt");
		int readCheck = -255;
		char[] readData = new char[1024];
		while((readCheck=fr.read(readData))!=-1) {
			for (int i=0; i<readCheck; i=i+1) {
				System.out.print(readData[i]);
					}
				}
			fr.close();	
			} catch (IOException e) { 
  /*exception이 여러개인데 상속관계에 있을 때 상위클래스 하나로 몰아서 한다.*/
				e.printStackTrace();
			}

파일 읽고, 복사하기

FileReader fr = null;
FileWriter fw = null;
		
	try {
		fr= new FileReader("test.txt");
		fw= new FileWriter("testCopy.txt",true); 
  		/* true => 기존거 다음에 추가로적겠다. 아무것도 없으면 기존거 다 지우고 새로 적겠다는 뜻.*/
		int readLen=0;
		char[] readData = new char[20];
			while((readLen=	fr.read(readData))!= -1) {
				fw.write(readData,0,readLen); 
  /*그냥 readData만 적으면 문제가 생김. 읽으려는 공간보다 읽을 값이 적으면 쓰레기 값이 들어가게 됨. 
    따라서 0번째부터 readLen만큼 읽어야 한다는 내용을 같이 적어야 한다.*/
			}
			fw.close(); fr.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

+ 
fr= new FileReader(args[0]); // 파일 이름 자체를 넣기보다 args[0]을 넣어줌
fw= new FileWriter(args[1]); // 파일 이름 자체를 넣기보다 args[0]을 넣어줌
Run Configurations에서 Arguments에 파일이름을 넣어준다.) test.txt copytest.txt
cf. main에서 MainClass를 확인해서 Arguments를 바꿀 class가 맞는지 확인할것

보안을 생각하여 파일을 복사하는 방법

FileInputStream fr = null;
FileOutputStream fw = null;
	
	try {
		fr= new FileInputStream(args[0]);
		fw= new FileOutputStream(args[1]); 
		int readData=0;
		while((readData=fr.read())!= -1) {
		fw.write((readData+1)); /*데이터에 예를들어 1을 더해서 보내면 파일이 보이지 않는다. 
                    하지만 받아서  readData-1로 바꿔주면 원래 데이터가 복원되어 보인다. */
			}
		fw.close(); fr.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

  • <> Generic

예) List list //만들 때 데이터 타입을 결정해주는것


  • java version이름

java SE (Standard edition)
java ME (Micro edition)
java EE (Enterprise edition)(network)


  • java 1.5 이상

packing unpacking 지원을 처음시작
예) 기본 타입의 자료를 알아서 묶어서 참조타입에 넣을 수도 있게함 등..
<> (Generic)기능 지원


  • 개발환경 세팅

개발환경 세팅은 workspace가 바뀌면 처음부터 다시 해줘야 한다.
예) eclipse FIle- Switch Workspace에서 새로운 폴더로 바꿔주는 경우 다시 설정을 해줘야 한다.
(.metadata 폴더에 설정에 대한 내용이 들어있다.)

  • 주요 세팅 순서
  1. 한글 설정
  2. WAS(톰캣)
  3. Emmet
  4. 각종 라이브러리 (선택 설치)
    4-1. Test용 - Junit
    4-2. DB용 - Connection pool or Hikari cp
    4-3. Sql용 - MyBatics or JPA
    4-4. Html,Jsp용 - Tymeleaf or Spring
  • 설치 및 Window설정 완료 후 프로젝트 설정
  1. server 폴더 생성
    File - new - other -server - apache -Tomcat 버전 맞는거 클릭 -Finish

  2. Dynamic Web project 생성
    만들 때 바로 Finish 하지말고 next 눌러가면서 마지막에 Generate web.xml deployment descriptor 체크 꼭 하고 만들기

  • 만든 후 확인사항

src - main -WEB-INF-web.xml 있는지 확인
javaResources - Libraries - JRE System Library, Server Runtime 있는지 확인

  • 권장사항

.controller ,.dao, .service, .domain로 끝나는 4개 package 생성


  • jsp

Jsp = > HTML + 지시어 (<%@ %>) , 표현식 (<%= %>), 스크립트릿(<% %>)

jsp - java의 8개의 객체가 자동으로 생성되어 내장되어있다. (+예외 발생시 exception이 추가되어 9개)
-request,response, session, out 객체 등

지시어 <%@ %> 예) <%@page ...>
표현식 <%= %> 예) <% =변수 %> 자바에서 k="홍길동"이라고 할때 <%=k %>를 하면 홍길동이 불러와짐 cf)요즘은 EL이라고 하는 표현언어를 쓴다. 예) ${k}
스크립트릿<% %> 예) <% 자바 코드 %>


  • Jsp 템플릿 설정

window-preference-web-jspFiles-Editor-Templates - New JSP File(html5) - edit

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="keywords" content="여기에 중요한 키워드 8개 정도 나열" />
<meta name="description" content="이 페이지를 설명하는 키워드를 문장형식으로 나열" />
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>

<script>
	//여기에 jquery 코드 작성
</script>
</body>
</html>

New JSP File(html5) 템플릿을 이런식으로 변경해주면 좋다.
(meta property 및 jquery 등 설정 추가)
cf) trimDirectiveWhitespaces="true" 코드를 읽을 때 맨위에 엔터등 공백을 제거해줌.
meta property=> 검색엔진에게 제공하는 자료들 (title안의 내용을 가장 먼저 읽고 그 다음 keywords(8개까지) description 등을 읽음


  • jsp request 객체

request객체는 browser(client)에서 데이터를 받아오는 역할을 한다.

예)
<%
String gender = request.getParameter("gender"); //한가지 데이터를 받을 때 (문자열로 받음)
String[] hobbys = request.getParameterValues("hobbys");  //여러가지 데이터를 받을 때 (배열로 받음)
%>

//...중간 생략...

<body>
<h1>넘겨받은 성별은 <%= gender %>입니다.</h1>
	<h1>넘겨받은 취미는 <%= hobbys[0] %>입니다.</h1>
	<h1>넘겨받은 취미는 <%= hobbys[1] %>입니다.</h1>
	<h1>넘겨받은 취미는 <%= hobbys[2] %>입니다.</h1>
</body>

cf)jsp에서 <% %>안에서 출력을 하고자할 때 out.print();사용

  • User-Agent

개발자도구 Network탭의 headers에서User-Agent는 사용자의 운영체제를 알수 있는 부분이다.
예) User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36


  • 웹접근성

사용자의 운영체제를 읽어서 그것에 맞는 다운로드 창을 제공해주는 방식이 필요하다.
사용자가 사이트에 접속하여 원하는 정보를 얻기까지 걸리는 행동수를 줄여야 한다.
예) 현대차 홈페이지에서 견적내기 클릭하기까지 스크롤 및, 클릭 등의 행동을 줄일 수 있게 하기(웹접근성)


  • jsp에서 사용자 접근 정보를 얻는 방법 request.get ooo
      

코드 자체보다 어떤 내용을 가져올 수 있는지를 알아두고 필요하면 찾아보는 것이 중요하다.

예)
      
<h3>프로토콜 : <%=request.getProtocol() %></h3>
 // 프로토콜 : HTTP/1.1
  
<h3>서버의 도메인 이름 : <%=request.getServerName() %></h3>
// 서버의 도메인 이름 : localhost
  
<h3>서버의 포트 번호: <%=request.getServerPort() %></h3>
//서버의 포트 번호: 80
  
<h3>요청 방식: <%=request.getMethod() %></h3>
//요청 방식: GET (parameter가 보임)
  
<h3>쿼리 스트링: <%=request.getQueryString() %></h3>
//쿼리 스트링: null
//쿼리 스트링이란 url에서 ?다음에 나오는 것들(parameters)을 의미한다.
예)localhost/webexam01/requestExam04.jsp?aaa=100&bbb=suwon&ccc=music
에서aaa=100&bbb=suwon&ccc=music부분 (단, 이건 GET방식일 때만 보이고 POST방식인 경우 보이지 않는다.)
  
<h3>접속한 클라이언트의 ip 주소: <%=request.getRemoteAddr() %></h3>
//접속한 클라이언트의 ip 주소: 0:0:0:0:0:0:0:1
  
<h3>접속한 경로(ContextPath): <%=request.getContextPath()%></h3>
//접속한 경로(ContextPath): /webexam01
  
<h3>요청 URI: <%=request.getRequestURI()%></h3>
//요청 URI: /webexam01/requestExam04.jsp
  
<h3>요청 URL: <%=request.getRequestURL()%></h3>
//요청 URL: http://localhost/webexam01/requestExam04.jsp
  
<h3>User-Agent헤더 값: <%=request.getHeader("User-Agent")%></h3>
//User-Agent헤더 값: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
  AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36

예)사용자 운영체제가 window인지 확인
  <%
	String userAgentValue = request.getHeader("User-Agent");
	if(userAgentValue.toLowerCase().indexOf("window") != -1){ 
   		//cf)indexof대신 contain을 사용하는 것이 더 좋으나 indexof로도 구현할 수 있다.
		out.print("<h1>접속한 클라이언트의 운영체제는 윈도우를 사용하고 있네요</h1>");
	}
%>


  • jsp response
<body>
<h1>나의 살던 고향은</h1>
<h1>나의 살던 고향은</h1>
<h1>나의 살던 고향은</h1>
<%
	response.sendRedirect("http://www.naver.com");
	//브라우저가 새롭게 지정된 주소로 요청을 하는 것이다.(새로운 요청이다.)
%>
</body>

안에 어떤 내용을 넣어든간에 다 지우고 naver로 이동한다.

  • jsp 기본 객체 pagecontext 의 기능.

(cf.jsp 177p)
1.다른 기본 객체 구하기
2.속성 처리하기
3.페이지의 흐름 제어하기
4.에러 데이터 구하기
cf. 커스텀 태그를 만들 수 있기는 하지만 다른 사람이 공부해야 하기 때문에 그리 권장하지는 않음.


  • jsp session, request영역

session 영역
- 로그인 기록 등이 여기 기록됨.
- 브라우저 창을 끄거나, 일정시간동안 로그인 유지됨
- 하나의 웹 브라우저와 관련된 영역

request 영역
- 클라이언트의 요구에 영역이 생성되고 페이지를 넘어가는 순간 사라짐.


  • 데이터를 넘기는 과정에서 parameter,attribute

.getparameter -문자열만 가능
.getattribute - 모든 형식 가능


  • forward
예)
<jsp:forward page="./to.jsp"></jsp:forward>
<h3>요청 페이지!!!page 영역에 만들어진 속성값 : <%=pageContext.getAttribute("pageAtt") %></h3>
<h3>요청 페이지!!!requeset 영역에 만들어진 속성값 : <%=request.getAttribute("requestAtt")%></h3>
<h3>요청 페이지!!!session 영역에 만들어진 속성값 : <%=session.getAttribute("sessionAtt") %></h3>
<h3>요청 페이지!!!application 영역에 만들어진 속성값 : <%= application.getAttribute("applicationAtt")%>
</h3>

포워드를 하면 이 클래스의 이전에 만들어진 모든 내용은 제거된다.
새로운 내용이 브라우저에 전달된다.
포워드를 해도 주소가 바뀌진 않는다. (response.sendRedirect로 하면 주소가 바뀜)

  • <jsp:include page=""></jsp:include>

<jsp:include page=""></jsp:include>를 넣어주면 지정한 파일의 내용을 보여준다.

예)
main.jsp의 body부분=================

	<h1>고향의 봄</h1> 							  //main 내용 나오고
	<jsp:include page="./sub.jsp"></jsp:include>  //sub.jsp내용 나오고
	<br />========================<br />  		  //main 내용 나오고
	<h2>청아한 사랑</h2> 						      //main 내용 나오고
	<jsp:include page="./sub2.jsp"></jsp:include> //sub2.jsp내용 나오고 
	<h1>메인의 마지막 내용임</h1> 					  //main 내용 나오며 끝

sub.jsp의 body부분==================
  
<p>나의 살던 고향은 꽃피는 산골</p>
<p>나의 살던 고향은 꽃피는 산골</p>
<p>나의 살던 고향은 꽃피는 산골</p>
	
sub2.jsp의 body부분=================
<p>너 내곁에 없으면 나 혼자 설 수 없나니 너 나의 구원이요 난 가늘한 실바람이라</p>

실행결과============================

고향의 봄
나의 살던 고향은 꽃피는 산골

나의 살던 고향은 꽃피는 산골

나의 살던 고향은 꽃피는 산골


========================
청아한 사랑

너 내곁에 없으면 나 혼자 설 수 없나니 너 나의 구원이요 난 가늘한 실바람이라

메인의 마지막 내용임

  • jspf, include 활용하여 코드 중복 방지

<%@include file="./diInsub.jspf"%>를 넣어서 include해줄 수도 있다.
이때 내용을 넣는 위치에 따라 main의 내용이 먼저나오기도 하고 include file의 내용이 먼저 나오기도 한다.
단, 대부분은 jsp파일 맨 위에 넣어준다.

예)

diInsub.jspf 파일에 아래 내용을 넣고======================================
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta property="keywords" content="여기에 중요한 키워드 8개 정도 나열" />
<meta property="description" content="이 페이지를 설명하는 키워드를 문장형식으로 나열" />
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1></h1>

diInsub2.jspf 파일에 아래 내용을 넣는다.=================
<script>
	//여기에 jquery 코드 작성
</script>
</body>
</html>

그후 main.jsp에 아래와 같이 작성하면 간단하게 정리된다=====

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@include file="./diInsub.jspf"%>
<p>나의 살던 고향은 </p>
<%@include file="./diInsub2.jspf"%>

  • <jsp:param value="" name=""/>
예)

main.jsp부분에서 parameter를 추가==================

<jsp:include page="./sub2.jsp"> //sub2.jsp에 parmeter를 추가하는 것
	<jsp:param value="19" name="age"/> 
	<jsp:param value="chan" name="userName"/>
</jsp:include>

sub2.jsp 부분====================================

<%
int age = Integer.parseInt(request.getParameter("age")); 
   //문자열로 받은 age를 정수로 변환하여 age에 저장함
String userName = request.getParameter("userName"); //userName에 저장
%>

<body>
<p>너 내곁에 없으면 나 혼자 설 수 없나니 너 나의 구원이요 난 가늘한 실바람이라</p>
나이는 : <%=age %> <br />
이름은 :<%=userName %>

실행결과==========================================
너 내곁에 없으면 나 혼자 설 수 없나니 너 나의 구원이요 난 가늘한 실바람이라
나이는 : 19
이름은 :chan

cf)
main.jsp에서 requset영역으로 attribute로 넘길 경우
<%
	request.setAttribute("aaaaa", 123456);
%>
sub2.jsp 영역에서 넘겨받을 수 있다.

<%= request.getAttribute("aaaaa") %>

  • errorpage <%@page errorPage="" %>
)
<%@page errorPage="./errorMessage.jsp" %>

//오류가 날 경우 기본 오류페이지가 아닌  지정한 경로의 내용을 보여준다.

오류의 종류에 따라 출력되는 페이지를 다르게 지정할 수 있음.

  • 쿠키 cookie

일반적으로 사용자의 허락없이 서버가 클라이언트에게 어떠한 형태의 데이터도 저장할 수 없다.
유일하게 허락된 것이 쿠키(아주작은 공간)이다.
쿠키는 서버에서 클라이언트에게 필요한 데이터를 저장할 수 있는 공간이다.
예) A사이트에 접속할 때 쿠키 허용했을 때 하드디스크에 저장이 된다.
그 후 나중에 A사이트를 다시 접속할 때 쿠키정보를 A사이트에 자동으로 준다.(로그인 정보 등)
단 B사이트를 들어갈 때 A사이트의 쿠키는 아무런 영향도 주지 못한다.

정적인 문서인 html은 톰캣을 거치지 않고 그냥 보여진다.
따라서 JSESSIONID가 발급되지 않는다.
하지만 jsp 는 웹서버 톰캣으로 거쳐야 하고
JSESSIONID가 발급되고 전달된다.(쿠키생성됨)

	Cookie sangpumInfo =new Cookie("viewsp","Tv"); 
	//상품 정보에 쿠키 이름 viewsp, 쿠키값 Tv로 만든다.
	sangpumInfo.setMaxAge(30); //쿠키 지속시간 30초로 주었음
	Cookie loginInfo =new Cookie("loginInfo","chan"); 
	//로그인 정보에 쿠키 이름 loginInfo, 쿠키 값 chan으로 만든다.
	loginInfo.setMaxAge(60*25); //기본값 -1로 브라우저를 닫으면 사라짐
	//쿠키 지속시간 25분으로 주었음 cf) 60*60*24*365 1년간 저장
	response.addCookie(sangpumInfo);
	response.addCookie(loginInfo);

<%
	//쿠키 이름은 spviewlist, 쿠키값으로는 0001저장하고자 한다. 
	// 쿠키 자체가 있는지 확인한다.
		// 없다면 새로만들어서 0001을 할당한다.
		// 있다면 spviewlist쿠키명이 기존에 존재하는지 확인한다.
			//1. 존재하는 경우 : 기존의 것에 추가한다. 2.없는 경우 : 새로 만들어서 값으로 0001을 저장한다.
	Cookie[] cookies =request.getCookies();
	if(cookies!=null){//쿠키자체가 있는지 따진다.(있는경우)
		boolean isspviewlist= false;
		Cookie getCookie = null;
		for(int i=0;i<cookies.length;i=i+1){
			isspviewlist=cookies[i].getName().equals("spviewlist");
				if(isspviewlist){
					getCookie = cookies[i];
					break;
				}
		}
		if(isspviewlist){
			getCookie.setValue(getCookie.getName()+"/0001");
			response.addCookie(getCookie);
	//방문할때마다 쿠키에/0001이 추가
  //다른 페이지를 클릭하면 /0002,0003,0004...가 추가 된다고 할 때 
  //쿠키에는 0001/0002/0003.. 으로 저장된다.
		}else{
			Cookie cookie = new Cookie("spviewlist","0001");
			cookie.setMaxAge(60*60*24*30);
			response.addCookie(cookie);
		}
	}else{ //쿠키자체가 있는지 따진다. (없는경우)
		Cookie cookie = new Cookie("spviewlist","0001");
		cookie.setMaxAge(60*60*24*30);
		response.addCookie(cookie);
	}
%> 

  • DB

인사관리HR계정 hr/hr
로그인 안될 때 관리자계정으로 alter user hr identified by hr Account unlock; 작성


  • RDBMS

테이블(자료저장 공간, 파일, 엑셀시트 등) 간의 관계에 따라서 구성이 되어있다.
다리쪽에서 화살표 쪽으로 참조한다.(<---E) 화살표 모양


  • sql이해해야 하는 부분

  CREATE TABLE "HR"."EMPLOYEES"  

--HR= 스키마(계정), EMPLOYEE= 테이블 객체(엔티티) 여기서 HR계정명은 지워도 된다.
--따라서 CREATE TABLE EMPLOYEES 로 바꿔준다.( 관례적으로 S를 붙여준다.)
--DB에서 문자열은 ''로 사용한다. 
--단, ""는 공백을 포함할 때 묶어주기 위해서 사용한다 예)"HR 1234"등
--컬럼의 위치에 따라서 성능이 달라진다. (예. 조건절을 앞으로 배치)
(	EMPLOYEE_ID NUMBER(6,0), --첫번째 컬럼은 PRIMARY KEY로 설정한다.
	FIRST_NAME VARCHAR2(20 BYTE), 
	LAST_NAME VARCHAR2(25 BYTE) CONSTRAINT EMP_LAST_NAME_NN NOT NULL ENABLE, 
	EMAIL VARCHAR2(25 BYTE) CONSTRAINT EMP_EMAIL_NN NOT NULL ENABLE, 
	PHONE_NUMBER VARCHAR2(20 BYTE), 
	HIRE_DATE DATE CONSTRAINT EMP_HIRE_DATE_NN NOT NULL ENABLE, 
	JOB_ID VARCHAR2(10 BYTE) CONSTRAINT EMP_JOB_NN NOT NULL ENABLE, 
	SALARY NUMBER(8,2), 
	COMMISSION_PCT NUMBER(2,2), 
	MANAGER_ID NUMBER(6,0), 
	DEPARTMENT_ID NUMBER(4,0),  --여기까지가 컬럼 정의다.

	 CONSTRAINT EMP_SALARY_MIN CHECK (salary > 0) ENABLE, 
	 CONSTRAINT EMP_EMAIL_UK UNIQUE ("EMAIL"),
	 CONSTRAINT EMP_EMP_ID_PK PRIMARY KEY ("EMPLOYEE_ID"),
 	--아래는 참조하는 테이블이 있다.
	-- DEPARTMENTS, JOBS, EMPLOYEES(자기참조) 테이블들을 참조함.
	--참조되어지는 테이블은 부모 테이블이라고 부른다.
	--참조 그림 예)  DEPARTMENTS <---E EMPLOYEES
	--상호 참조의 경우 만들 때 바로 할 수는 없고 만들고 나서 수정해야 한다.
	 CONSTRAINT EMP_DEPT_FK FOREIGN KEY (DEPARTMENT_ID)
	  REFERENCES HR.DEPARTMENTS (DEPARTMENT_ID) ENABLE, 
	 CONSTRAINT EMP_JOB_FK FOREIGN KEY (JOB_ID)
	  REFERENCES HR.JOBS (JOB_ID) ENABLE, 
	 CONSTRAINT EMP_MANAGER_FK FOREIGN KEY (MANAGER_ID)
	  REFERENCES HR.EMPLOYEES (EMPLOYEE_ID) ENABLE
	--NOT NULL을 제외한 제약 조건은 아래에 따로 쓴다.
	--NOT NULL CHECK UNIQUE PRIMARY KEY FOREIGN KEY 등의 제약조건이 있다.
	--제약 조건명은 _ 등을 사용하며 기능을 포함하여 적어주면 좋다. 예) _PK =>PRIMARY KEY
   ) 

  • oracle 제약조건
1) 제약 조건 수정하는 방법(참조 하는방법)
alter table 참조될 테이블명 add foreign key(참조될 컬럼명) references 참조할 테이블(참조할 컬럼명))  alter table EMPLOYEES add foreign key(JOB_ID) references JOBS(JOB_ID);, 이경우 제약조건명을 지정해주지 못해서 제약조건명을 오라클이 임의로 지정하기 때문에 권장하지 않는다.

cf.) 제약조건 수정하는 방법
alter table 참조될 테이블명 MODIFY(참조될 컬럼명) 테이블 설정 제약조건;) alter table samtable MODIFY COL1 NUMBER(6) NULL ; //COL1을 NULL로 바꿔달라
cf) 컬럼명 수정하는 방법
alter table 테이블명 rename column 컬럼명 to 바꿀컬럼명;) alter table samtableone rename column col1 to columnone;
cf) 테이블명 수정하는 방법
rename 기존테이블명 to 바꿀테이블명;) rename samtableone to sampbone;

2) 제약 조건명을 주면서 수정하는 방법 (constraint 제약조건명을 추가하면 됨)
alter table 테이블명 add constraint 제약조건명 primary key(deptno);)alter table EMPLOYEES add constraint JOB_ID_FK foreign key(JOB_ID) references JOBS(JOB_ID); 

3) 제약조건 확인하는 법
SELECT * FROM    USER_CONSTRAINTS WHERE    TABLE_NAME = 'EMPLOYEES'; 
  (cf.'테이블명을 대문자로 적어줄것)')

4) 제약조건 삭제하는 법
ALTER TABLE 테이블명 DROP CONSTRAINT 제약조건 명;
ALTER TABLE EMPLOYEES DROP CONSTRAINT SYS_C007030;

  • oracle 테이블 생성, 복사
1) 서브쿼리를 이용한 테이블을 만드는 방법(복사하는 개념)
CREATE TABLE 만들 테이블 명 AS SELECT * FROM 복사할 테이블명;
CREATE TABLE SAMPLES AS SELECT * FROM JOBS; JOBS테이블과 완전히 같은 SAMPLES테이블이 생성된다. 

  cf. (메인쿼리->)CREATE TABLE SAMPLES AS SELECT (서브쿼리->) * FROM JOBS;
  
이 방식으로 테이블을 만들 경우(NOT NULL을 제외하고 어떠한 제약조건이든 복사가 적용되지 않는다.)

2) 전부다(*)대신 특정 컬럼만 복사하고 싶을 때
CREATE TABLE SAMPLES AS SELECT job_id, job_title FROM JOBS;
(복사할 컬럼명 적기)

3) 구조는 가져오면서 컬럼명은 바꾸고 싶을 때
CREATE TABLE SAMPLES AS SELECT job_id sampleID, job_title sampleTitle FROM JOBS; 
  (컬럼뒤에 한칸 뛰고 바꾸고싶은 컬럼명 적기)

4) 구조만 복사하고 데이터는 복사하고 싶지 않을 때
CREATE TABLE SAMPLES AS SELECT * FROM JOBS where 10=20; 
(where뒤에 말이 안되는 식을 추가해준다.)

  • 테이블에 데이터 값 넣기
) insert into samtbone values(36500,'qwert',sysdate); 
  (3개 열에 한번에 넣을 때, 이경우 값을 모두 넣어야 함)) insert into samtbone(salary, name) values(36500,'qwert'); 
  (2개만 넣은것이고 날짜부분에는 null값이 들어감)

cf) 문자열 자리에 숫자를 넣으면 문자열로 들어간다.
cf) 날짜 넣는 방법 : sysdate, 2023-3-14, 2023/3/14, to_date('2023-03-14') 등

cf) 테이블 데이터 그대로 복사해서 추가하기
예) insert into 추가해줄테이블명 select * from 복사해올테이블명; 
samtbone내용을 samtbone에 다 추가함
cf) insert into samtbone 
select 123, '나이등', to_date('2023-02-28') from samtbone;
(samtbone에 없는 내용이 select뒤에 와도 넣어줄 수 있다.
123, '나이등', 23-02-28 데이터는 원래 없었지만 추가해줄 수 있다.)

  • sql(structured Query Language) 종류

면접에서도 나오는 단어들이다. (cf p26.)
DQL - RDBMS에 저장한 데이터를 원하는 방식으로 조회하는 명령어
DML - RDBMS 내 테이블의 데이터를 저장, 수정, 삭제 하는 명령어
DDL - RDBMS 내 데이터 관리를 위해 테이블을 포함한 여러 객체를 생성, 수정, 삭제하는 명령어
TCL - 트랜잭션 데이터의 영구 저장, 취소 등과 관련된 명령어
DCL -데이터 사용 권한과 관련된 명령어 ( 그랜트 리보크 등 )


  • java session
<%=session.getId() --%> <%--세션 ID 가져옴 --%>
<%=new Date(session.getCreationTime()).toString() %> <%--세션 ID 발급될 때의 시간 정보를 가져옴 --%>
cf)  jsp 에서는 "<br/>"처럼 원래 닫는 형태를 적지 않아도 되는 태그도 적어준다.

날짜 
<% Date sessionDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy년 MM월 dd일 hh시 -mm분-ss초"); %> 
최초 세션 아이디가 발급된 시간 :
<%= dateFormat.format(session.getCreationTime()) %>  <br />
가장 최근에 접속한 시간 : <%= dateFormat.format(session.getLastAccessedTime()) %> 

session.invalidate(); //기존 발행 session초기화

세션 아이디를 최초로 받을 때가 브라우저 처음 켰을 때이다.
세션 아이디는 쿠키에도 적용이된다.
세션은 서버에만 저장된다. (쿠키보다 보안적인 용도가 좋다)


  • java DTO implements Serializable
)
DTO 클래스를 생성할 때
public class MemberBean implements Serializable{
필드 생성 및 기본생성자, 사용자생성자, getter,setter, hashcode,equals,tostring 
다 하고나서 class옆에 implements Serializable를 추가해준다.
}
implements Serializable를 적으면 차례대로 생성되게 해준다.

  • jsp 초기 확인하면 좋은 것

web.xml에서

<welcome-file-list>안에
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>

이정도만 남겨도 무방하다.


  • jsp EL (Expression Language)
)
<% String uriData =request.getRequestURI(); %>
<%= uriData%>	
위 처럼 여러 단계가 필요한 과정을 아래처럼 간단하게 줄일 수 있다.
  
el표기법 사용 
  -자바코드(<% %>) 안에서는 사용 하지 못한다. 
  -일반적인 HTML태그 등 쓸 때 쓰인다.)
 ${pageContext . request.requestURI} <br />

/* 
내장객체의 메서드 값을 얻기 위해서는 표현헌어는 직접 접근이 불가능하다
PageContext객체를 이용해서 해당 내장객체를 얻고 그 얻어진 결과를 이용해서 접근(호출)
내장객체의 메서드가 get으로 시작할 경우 get을 생략하고 첫글자를 소문자로 한다. */

  • MVC의 모델 p625 관련내용 다시 봐야 할듯. 프로젝트 이름 board

서블릿 - 네트워크 기반의 자바 프로그램, controller역할을 한다.
http요청이 들어오면 서블릿은 요청을 분석해서 모델에게 일을 시킨다.
모델이 request영역에 생성된 데이터를 다시 controller에 보내면 서블릿(controller)은 이를 jsp에 보낸다.
jsp(view 역할)는 http에게 보낸다

cf)dao,service는 묶어서 모델로 본다
cf) javaresources안에 java코드 , src안에 jsp코드 저장


  • BoardDAO 예시
public interface BoardDAO {
	int insertBoard(BoardVO vo);
	int deleteBoard(int boardNum);
	int updateBoard(BoardVO vo);
	
	BoardVO getBoard(int boardNum);
	List<BoardVO> getList();
	int getCount(); 
	int getMaxNum();
}

insert delete update는 데이터가 바뀐다. 따라서 int or void를 쓴다.
몇개가 수정되는지 알고 싶으면 int 수정만 할거면 void를 쓴다. (insert는 거의 int)

cf)
insert의 매개변수는 BoardVO의 여러 항목들의 묶음이라 BoardVO vo
delete는 primary key 하나만 받으면 되는건데 int형이라서 boardNum을 받음
update도 매개변수는 BoardVO의 여러 항목들의 묶음이라 BoardVO vo

메서드명을 이렇게 만들고 구현해주는 class.impl 하나 만들어서 정의해주면 된다.


  • cf) DB랑 연결하는 설정 해주는 것
 <Context> 

     <Resource name="jdbc/OracleDB" 

         auth="Container"
         type="javax.sql.DataSource" 
         username="scott"  //필요할 때 바꾸기
         password="tiger" //필요할 때 바꾸기
         driverClassName="oracle.jdbc.driver.OracleDriver"
         factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
         url="jdbc:oracle:thin:@localhost:1521:xe"
         maxActive="500" 
         maxIdle="100"/>  

 </Context>
  

  • board 게시판 만들기 중

cf)
javascript : history 객체 - 브라우저의 뒤로가기 앞으로가기 창 의미
예) javascript : history.go(-1) 뒤로가기 하라는 의미
javascript : location 객체 - 브라우저의 주소창 의미

file을 업로드하기 위해 필요한 것
1. form태그에 enctype="multipart/form-data"를 넣어야 한다.(""안의 내용 고정)
2. input type="file"로 바꾸기.
3. MultipartRequest를 사용해야 하기 때문에 cos.jar lib를 lib에 넣어줘야 한다.


profile
서버개발 공부중

0개의 댓글