JAVA

[Java] 공부 정리 자료 공유

연곰2 2025. 7. 13. 18:42

 

처음 개발 공부를 시작했을 때, 혼자 보기도하고 같이 공부했던 분들한테 공유하기 위해서 정리한 자료인데
누군가에게 또 도움이 되지 않을까싶어서 정리했던 자료들을 올려보려고 합니다 :)
예전에 공부했던 자료라 지금과는 다를 수 있어서 그 부분 참고하셔서 봐주세요!!

 

version : java11, eclipse 2020-12

 

단축키

▶ Window

Ctrl + F11 Run
Alt + ↑, ↓ 줄 이동
Ctrl + Alt + ↑, ↓ 줄 복사
Ctrl + M 선택 창 크게 보기
Alt + Shift + A 그리드 모드
Alt + Shift + R 변수명 전체 변경
Ctrl + I 자동 들여쓰기
 
Ctrl + Shift + O 자동 import
Alt + Shift + S > O Generate Constructor using Fields
Alt + Shift + S > R Generate Getters and Setters
Alt + Shift + Z 감싸는 블록 자동완성 (try/catch)

▶ Mac (개인 설정)

Command + F11 Run
Command + ↑, ↓ 줄 이동
Option + Command +  ↑, ↓ 줄 복사
Command + M 선택 창 크게 보기
Ctrl + Shift + F 자동 정렬
Option + Ctrl + N 프로젝트 생성
 
Option + Space 자동 완성
Shift + Command + S 생성자, Getter, Setter 등
Shift + Command + O 자동 import
Shift + Command + Z 감싸는 블록 자동완성

Day21

▶ API 사용

Jar 파일 추가

1. 프로젝트 우클릭 > Build Path > Configure Build Path

2. Libraries > Classpath > Add External JARS… 

> 사용할 .jar 파일 선택 > apply

3. Order and Export > Select All > Apply and close

 

▶ Object (최상위 부모 클래스)

toString()

항상 객체명을 출력할 때에 toString()이 생략된다. toString()을 통해 출력되는 문자열이 마음에 들지 않는다면, 재정의하여 수정하도록 한다. 클래스의 필드가 초기화 되었는지, 전달받은 값이 어떤 것인지 검사할 때 toString()을 재정의하여, 객체명을 출력함으로써 확인이 가능하다.

 

equals() : 주소값 비교(==)

String 클래스는 값 비교로 재정의되었다.

문자열 비교에서는 반드시 equals()를 사용하고,

null을 비교할 때에는 ==으로 비교한다.

 

// 값이 constant pool에 할당되면 주소가 생긴다.
// 그 주소가 연산 시 먼저 사용된다.
String data1 = "ABC";
String data2 = "ABC";


// 필드의 주소가 연산 시 먼저 사용된다.
String data3 = new String("ABC");
String data4 = new String("ABC");


System.out.println(data1 == data2);
System.out.println(data1.equals(data2));


System.out.println(data3 == data4);
System.out.println(data3.equals(data4));




Random r1 = new Random();
Random r2 = new Random();


System.out.println(r1);
System.out.println(r2);


System.out.println(r1==r2);
System.out.println(r1.equals(r2));


r1 = r2;
System.out.println(r1 == r2);
System.out.println(r1.equals(r2));

true
true

false
true // String 의 equals는 값으로 재정의되어 true라는 결과가 나옴.

java.util.Random@762efe5d
java.util.Random@5d22bbb7

false
false

true
true

 

 

 

hashCode()  * 참고 자료

해당 객체의 주소값(메모리상의 주소가 아닌 hash 값을 통한 중복 없는 값)

* equals를 재정의할 경우, hashCode도 재정의해야한다.

 

String data1 = "ABC";
String data2 = "ABC";
String data3 = new String("ABC");
String data4 = new String("ABC");


Random r1 = new Random();
Random r2 = new Random();


System.out.println(r1.hashCode());
System.out.println(r2.hashCode());


System.out.println(data1.hashCode());
System.out.println(data2.hashCode());
System.out.println(data3.hashCode());
System.out.println(data4.hashCode());
1404928347
1562557367


// String 의 hashCode는 재정의되었다.
// 서로 다른 String 객체도 문자열이 같으면 hashCode가 같다.
64578
64578
64578
64578



▶ Wrapper Class (기본 자료형들의 클래스 타입)

Boxing, Unboxing

- Boxing : 기본 자료형 타입의 변수를 클래스 타입으로 변환하여 사용

- Unboxing : 클래스 타입의 변수를 기본 자료형 타입으로 변환하여 사용

 

// boxing
클래스타입 객체 = new 클래스타입(일반타입의 값); // => 옛날
클래스타입 객체 = 클래스타입.valueOf(일반타입의 값); // => 요즘

 // unboxing
일반타입 변수 = 객체.000Value();

 

- JDK4 버전 이상부터는 auto를 지원한다.

 

// auto boxing
클래스타입 객체 = 일반타입의 값;
// auto  unboxing
일반타입 변수 = 객체; 



Wrapper Class를 사용하는 이유

원시타입(일반타입)을 박싱하면 다양한 메소드를 제공받을 수 있다. 여러 일반 타입을 하나의 타입으로 묶기 위해서는 반드시 클래스타입(Wrapper class)로 사용해야 되고, 이 때에는 박싱을 해준다.

 

Day22

▶ 알고리즘

어떤 문제가 발생되었을 때 해결할 수 있는 절차 혹은 순서

 

▶ 자료구조

의미없는 데이터를 하나의 정보로 만들어주는 알고리즘들의 집합,

수집한 자료를 저장하고 관리하는 방법.

 

▶컬렉션 프레임워크 1 (Collection Framework) : 자료구조

많은 데이터를 쉽고 효과적으로 관리할 수 있는 

표준화된 방법을 제공하는 클래스들의 집합.

 

 * List, Set은 인터페이스

 1) 인터페이스끼리는 상속가능. Collection이라는 인터페이스를 상속받기 때문에

 2) List, Set의 클래스들의 집합 => List, Set이 되기 위해서는 강제성이 필요하기 때문에

 

1. List extends Collection

 - List 구현 클래스

Vector

용량관리, 보안성 강화, 처리량 감소

LinkedList

 FIFO으로 인해 넣을 때는 빨라도 뺄 때에는 상대적으로 느리다.

ArrayList

인덱스로 데이터를 관리한다.

컬렉션 클래스 중 실무에서 가장 많이 사용되는 클래스이다. 

배열의 특징인 인덱스를 이용하여 값을 저장하고 관리한다.

- 사용법

ArrayList<데이터타입> 객체명 = new ArrayList<데이터타입>();

 

1) 값 추가 : add()

2) 값 삭제 : remove()

3) 포함된 값 : contains()

4) 값의 인덱스 : indexOf()

- 배열과 ArrayList의 차이

배열은 길이에 제한을 두어야 할 때 자주 사용되고

ArrayList는 몇 개의 데이터가 들어올 지 알 수 없을 때 사용한다.

▶ Generic 제네릭

<?> : 제네릭(이름이 없는)

 

- 임시로 타입을 선언하여 임시 타입으로 설계한다.

- 다운캐스팅을 할 필요가 없다.

- 지정할 타입에 제한을 둘 수 있다.

ex) ArrayListTest<T extends Number> ==> String을 넣을 수 없다.

 

- 생략하면 Object 타입, 그렇기 때문에 기본 타입 사용 x

- 생성자의 제네릭은 생략도 가능

ex) ArrayList<Integer> datas = new ArrayList<>();

▶빠른 for문, 향상된 for문, foreach …

 

for (int data : datas) {
System.out.println(data);
}

 

▶Collections

컬렉션 프레임워크 객체를 사용하여 미리 만들어진 함수들을 사용할 수 있다.

 

Collections.sort(datas);
Collections.reverse(datas);
Collections.shuffle(datas);

 

Day23

▶ 컬렉션 프레임워크 2

2. Set extends Collection : 집합

- Set 구현 클래스

HashSet

집합에서는 중복되는 원소를 포함할 수 없는 것 처럼

HashSet이라는 자료구조는 중복되는 값을 무시한다.

저장된 값들은 인덱스가 없기 때문에 순서가 없다.

값의 유무 검사에 특화되어 있는 자료구조이고 해쉬코드로 

유무 검사가 진행된다. 검사의 속도가 상대적으로 좋다.

- 사용법

HashSet<데이터타입> 객체명 = new HashSet<데이터타입>();

 

1) 값 추가 : add()

값이 추가됐는지 안됐는지에 따라  true, false가 반환되는데 중복이 되지 않기 때문에 없는 값일 경우 true, 있는 값일 경우 false를 반환한다.

 

- 순서 부여 : .iterator()

Iterator<데이터타입> iter = 객체명.iterator();

 

순서가 없는 객체에 순서를 부여하거나, 순서가 있어도 iterator 방식의 순서로 변경하고자 할 때 사용한다. hasNext()를 통해 다음 값이 있는 지 검사하고, next()를 사용하여 값을 가져온다.

 

Day24

▶ 컬렉션 프레임워크 3

3. Map

- 구현 클래스

HashMap(서버 간 데이터 교환)

Key와 Value 한 쌍으로 저장되며, 검색의 목적을 가지고 있다.

Key는 중복된 값을 넣으면 Value가 최근 값으로 수정되고

중복되지 않는 값을 넣으면 새롭게 추가된다. 

Value는 중복이 가능하다.

- 사용법

HashMap<데이터타입> 객체명 = new HashMap<데이터타입>();

 

1) 값 추가 : put()

2) 값 가져오기 : get(‘key’)

3) key값만 가져오기 : keySet()

4) value값만 가져오기 : values()

5) set으로 key와 value 가져오기 : entrySet()

▶JSON (JavaScript Object Notation)

속성-값 쌍(attribute–value pairs), 배열 자료형(array data types) 또는 기타 모든 시리얼화 가능한 값(serializable value) 또는 "키-값 쌍"으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다.

- 자바객체 JSON 형식으로 변경하는 방법

HashMap<String, Object> userMap = new HashMap<String, Object>();

// JSON 배열 객체
JSONArray userJsons = new JSONArray();

//JSON 객체
JSONObject userJson = null;

// 1번째 JSON 객체
userMap.put("id", "hds");
userMap.put("pw", "1234");
userMap.put("name", "한동석");
userMap.put("age", 20);


userJson = new JSONObject(userMap);
userJson.put("phoneNum","01012341234");


// JSON 배열에 담기
userJsons.add(userJson);

// 2번째 JSON 객체
userMap.put("id", "hgd");
userMap.put("pw", "3333");
userMap.put("name", "홍길동");
userMap.put("age", 25);

// JSON 배열에 추가
userJson = new JSONObject(userMap);
userJsons.add(userJson);


System.out.println(userJsons.toJSONString());
System.out.println(userJson.toJSONString());
[{"name":"한동석","phoneNum":"01012341234","id":"hds","age":20,"pw":"1234"},{"name":"홍길동","id":"hgd","age":25,"pw":"3333"}]

{"name":"홍길동","id":"hgd","age":25,"pw":"3333"}

▶Lambda

함수형 인터페이스로만 사용 가능.

 

forEach() * 참고자료

매개변수에는 컬렉션 객체 안에 들어있는 값들이 순서대로 담기고,

화살표 뒤에서는 구현하고 싶은 문장을 작성한다.

 

HashMap<String,Integer> chinaTown = new HashMap<String, Integer>();


chinaTown.put("짜장면", 4500);
chinaTown.put("짬뽕", 5000);
chinaTown.put("탕수육", 14500);

chinaTown.values().stream().forEach(v -> System.out.println(v));
chinaTown.values().forEach(v -> System.out.println(v));
4500
500
14500

 

소속::메소드명

전달받은 매개변수를 그대로 메소드에 사용할 경우에는 참조형 문법을 사용할 수 있다. 전달받은 값을 메소드의 매개변수로 바로 전달해준다.

ex)

String::toString --> 전달받은 값에 바로 toString 메소드를 사용해준다.

String::toUpperCase --> 전달받은 값을 바로 toUpperCase 메소드에 전달해준다.

 

chinaTown.values().forEach(System.out::println);

 

IntStream.range

1) IntStream.range(start, end) : start부터 end-1 까지

2) IntStream.rangeClosed(start, end) : start부터 end 까지

 

IntStream.range(0, 10).forEach(System.out::print);
0123456789

 

chars() : 문자열을 문자 stream으로 변경

String data = "ABC";
data.chars().forEach(System.out::print);
data.chars().forEach(c -> System.out.print((char)c));
ABC

 

map() : 기존 값을 원하는 값으로 변경

data.chars().map(c -> c + 3).forEach(c -> System.out.print((char)c));
DEF

 

filter() : 조건식을 작성하여 false일 경우 제외시킨다.

IntStream.rangeClosed(1, 10).filter(i -> i % 2 == 0).forEach(System.out::print);
246810

 

오름차순

Integer[] arData = {10, 40, 20, 30};
* Arrays.asList
배열을 ArrayList로 변경해주는 메소드, 값들을 바로 넣어주는 것도 가능.
// ArrayList<Integer> datas = new ArrayList<Integer>(Arrays.asList(arData));
ArrayList<Integer> datas = new ArrayList<Integer>(Arrays.asList(10, 40, 20, 30));
datas.stream().sorted().forEach(System.out::println);
10
20
30
40

 

내림차순

ArrayList<Integer> results = (ArrayList<Integer>)datas.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
System.out.println(results);
40
30
20
10

 

collect() * 참고자료

: 데이터의 중간 처리 후 마지막에 원하는 형태로 변환해 주는 역할을 한다.

stream 요소들을 List, Set, Map 자료형으로 변환(toList(), toSet(), toMap(), toCollection())

stream 요소들의 결합(joining)

stream 요소들의 통계(최대, 최소, 평균값 등…)

stream 요소들의 그룹화와 분할

 

joining("구분점") : 문자열 요소들을 구분점으로 연결하여 문자열로 리턴한다.

 

System.out.println(datas.stream().map(String::valueOf).collect(Collectors.joining(" ")));
10 40 20 30

Day25

▶ 프로그램

실행이 안된 상태.

▶ 프로세스

실행된 프로그램.

운영체제로부터 시스템 자원을 할당받는 작업의 단위.

JAVA는 운영체제가 바로 실행시켜주지 않고 JVM에 의해 실행되기 때문에

JVM으로부터 시스템 자원을 할당받는다.

▶ 쓰레드

프로세스의 처리 경로.

처리 경로는 디폴트로 한 개이다.

멀티 쓰레드를 구현할 때에는 스케줄링 작업이 필요하다.

 

1. 단일 쓰레드

처리 경로를 한 개만 가지고 있기 때문에 직렬적이다.

동시에 많은 양을 처리하기 힘들기 때문에 상대적으로 비효율적이다.

하지만 하나의 작업에 문제가 발생하더라도 다른 작업에는 영향을 끼치지 않는다. 따라서 안정성이 보장되고 설계 시 멀티 쓰레드에 비해 쉽다.

 

2. 멀티 쓰레드

하나의 프로세스를 동시에 처리하는 것처럼 보이지만 사실은 매우 짧은 단위로 분할해서 차례로 처리한다. 여러 개의 처리 경로를 가질 수 있도록 하며, 동시 작업이 가능해진다. 설계하기 굉장히 어려우며, 하나의 쓰레드 문제 발생 시 모든 쓰레드에 문제가 발생하게 된다. JAVA 웹 서버가 대표적인 멀티 쓰레드이다. 멀티 쓰레드로 설계했다면, 처리량 증가, 효율성 증가, 처리비용 감소의 장점이 있기 때문에 단점을 감수하고 설계하는 편이다.

- 멀티 쓰레드 구현 방법

★ 핵심 : run() 메소드 재정의, 구현

 

- run() : 실행할 코드

- start() : 쓰레드 시작, 내부적으로 run()을 실행해준다. (스케줄링 해주는 작업)

- join() : 사용한 쓰레드가 다 끝나야 다른 쓰레드가 동작한다.

 실행 순서를 줄 때는 join()을 사용한다.

join()은 이미 start()된 쓰레드를 막을 수 없다..

 

1) Thread 클래스 상속

package threadTest;

public class Thread1 extends Thread {
String data;


public Thread1() {;}

public Thread1(String data) {
super();
this.data = data;
}


@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(data);
try{
Thread.sleep(1000);
}catch (
InterruptedException e) {;}
}
}
}

 

2) Runnable 인터페이스 지정

Runnable 인터페이스로 지정 후 쓰레드로 객체화하여 사용한다.

자바는 단일상속만 가능하기 때문에 상속받아야 하는 클래스가 있을 경우 인터페이스로 구현한다.

package threadTest;

public class Thread2 implements Runnable {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
try {Thread.sleep(500);} catch (InterruptedException e) {;}
}
}


}

 

package threadTest;
package threadTest;

public class ThreadTest {
public static void main(String[] args) {


Runnable t1 = new Thread2();
Thread2 t2 = new Thread2();

//                                                    String name
//                                                   Thread의 이름 Thread thread1 = new Thread(t1, "?");

/* Tread는 함수형 인터페이스
   람다식으로 표현 가능.
   currentThread() : 현재 실행하고 있는 쓰레드
   getName() : 쓰레드의 이름을 가져온다. */

Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {;}
}
}, "!");

thread1.start();
thread2.start();


try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {;}


System.out.println("main 쓰레드 종료");
}
}

Day26

▶ 동기화 (Synchronized)

하나의 쓰레드가 자원에 접근 중일 때 다른 쓰레드가 동시에 같은 자원을 접근하지 못하게 막는 것. 즉, 자원 공유 문제를 해결할 수 있다.



1. synchronized(mutex){ … }

동기화 블럭이라고 부르며, 일부 소스코드만 동기화를 걸어준다.

 

2. synchronized

영역 전체에 동기화를 걸어주며, 메소드 리턴타입 앞에 작성하면 해당 메소드 전체에 동기화가 걸린다.

 

▶ Thread 종료 방법

1. 필드에 boolean 타입의 변수를 선언하고, 

run() 안에 있는 반복문에 해당 변수가 true일 경우 break를 할 수 있도록 설계한다.

 

2. sleep(), wait(), join() 등의 메소드를 통해 쓰레드가 일시정지 상태가 되면

Thread객체.interrupt()를 사용하여 InterruptedException을 발생시킨다.

이 때 일시정지 시킨 메소드 부분에서 catch를 통해 예외를 잡아주고 원하는 문장을 그 안에 작성하면 된다.

 

3. 쓰레드를 일시정지하는 코드가 없을 경우, Thread.interrupted()의 상태를 확인한다. Thread객체.interrupted()를 사용하면 Thread.interrupted()의 상태는 true로 변경되고, 만약 Thread.interrupted()를 두 번 사용하면 두 번째부터는 false 상태로 리턴된다.

 

4. System.exit(0)를 사용하면 프로세스 종료(전체 쓰레드 종료).

 

Day27

▶ 파일 입출력

Writer(출력)

BufferedWriter : 버퍼를 사용한 출력 클래스

FileWriter : 전달한 경로의 파일을 출력하기 위한 목적으로 열어준다.

    전달한 경로에 파일이 없다면 새롭게 만든 후 열어준다.

File : 전달한 경로에 있는 파일의 정보를 담는 타입

      파일의 유무 검사, 파일 삭제, 경로 가져오기 등

 

Reader(입력)

BufferedReader : 버퍼를 사용한 입력 클래스

FileReader : 전달한 경로의 파일을 입력하기 위한 목적으로 열어준다.

    전달한 경로에 파일이 없다면 오류가 발생한다.

File

 

▶ 인코딩

원본 데이터를 byte로 변환 시킬 때 사용되는 방식

 

각 간 갇 갈 감 ... 갛 : 완성형

ㄱ + ㅏ + ㄱ : 조합형

 

조합형이 더 효율적이고 대표적인 조합형 인코딩 방식은 UTF-8이다.

 

Day28

▶ 소프트웨어 디자인 설계 패턴 * 패턴은 약속!

1) MVC

- M(model) 

: DB에서 조회된 결과 값을 담기 위한 변수들이 선언된 클래스

- 클래스명 뒤에 VO, DTO라는 문자를 붙여준다.

- VO(Value Object)

- DTO(Data Transfer Object)

 

- V(view)

 : 사용자에게 보여질 화면을 구성하는 부분

- Controller에 선언된 메소드를 사용하는 부분

 

- C(controller) 

: DB에 접근할 수 있는 메소드들이 선언된 클래스

- 접근 후 결과값이 있을 경우 Model 객체에 담은 후 처리

- 클래스명 뒤에 DAO라는 문자를 붙여준다.

- DAO(Data Access Object)

 

JDBC * 참고

▶ DB 연결 및 작업 과정

1. 프로젝트에 ojdbc6.jar 파일 추가(링크참고)

- ojdbc6.jar 위치 : C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

- 맥인 경우 따로 ojdbc6.jar 파일을 다운로드

2. Model 생성

vo  package 테이블을 기반으로 class를 생성한다.

ex) User (회원번호, 이름, 비밀번호, 생일, 아이디)

package vo;

public class UserVO {
   // Java는 카멜 표기법 사용, DB는 _ 사용
   // Spring에서 DB의 컬럼명을 자동으로 카멜 표기법으로 바꿔주는 작업을 한다.
   private int userNumber;
   private String userName;
   private String userPassword;
   private String userBirthday;
   private String userId;
   
   public UserVO() {;}

   public int getUserNumber() {
      return userNumber;
   }

   public void setUserNumber(int userNumber) {
      this.userNumber = userNumber;
   }

   public String getUserName() {
      return userName;
   }

   public void setUserName(String userName) {
      this.userName = userName;
   }

   public String getUserPassword() {
      return userPassword;
   }

   public void setUserPassword(String userPassword) {
      this.userPassword = userPassword;
   }

   public String getUserBirthday() {
      return userBirthday;
   }

   public void setUserBirthday(String userBirthday) {
      this.userBirthday = userBirthday;
   }
   
   public String getUserId() {
      return userId;
   }

   public void setUserId(String userId) {
      this.userId = userId;
   }

  // 정보 확인을 위해서 toString() 재정의
  @Override
   public String toString() {
      String str = userNumber
            + ","   + userName
            + "," +   userPassword
            + "," +   userBirthday
            + "," + userId;
      return str;
   }
}



3. Controller 

  - DBConnecter class

쿼리를 실행하여 데이터를 가져오기 위해서 매번 DB를 연결해주어야 한다. 이런 반복적인 작업을 줄이기 위해서 dao package에 DBConnecter class를 생성하여 사용한다.

 

package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnecter {
    public static Connection getConnection() {
        Connection connection = null;

        // 연결에 필요한 정보
        String userName = "hr";
        String password = "hr";
        String url = "jdbc:oracle:thin:@localhost:1521:XE";


       // 연결이 실패할 경우를 대비해 try/catch문 사용
        try {
                // 드라이버를 사용하기 위해서 
                // 드라이버를 메모리에 할당
                Class.forName("oracle.jdbc.driver.OracleDriver");


                // ojdbc6.jar 에 있는 
                // DriverManager class를 이용하여 연결
                connection = DriverManager.getConnection(url, userName, password);

                System.out.println("연결 성공");

        } catch (ClassNotFoundException e) {
                System.out.println("드라이버 로딩 실패");
                e.printStackTrace();
        } catch (SQLException e) {
                System.out.println("연결 실패");
                e.printStackTrace();
        }
        return connection;
    }
}

 

   - DAO class에 메소드 생성

⬥ 메소드의 전체적인 흐름

  1. 쿼리 작성
  2. 쿼리 객체
  3. 쿼리 실행
  4. 결과 객체

 

ex) 아이디 중복검사

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;

import vo.UserVO;

public class UserDAO {

    // 모든 메소드에서
    // 연결 객체. 쿼리 객체, 결과 객체를 사용하기 때문에
    // 인스턴스 변수로 작성한다.
    public Connection connection; // 연결 객체
    public PreparedStatement preparedStatement; // 쿼리 객체
    public ResultSet resultSet; // 결과 객체


    // 아이디 중복검사
    public boolean checkId(String userId) {
        // 중복검사이기 때문에 사용자가 입력한 아이디를 검색했을 때
        // 검색 결과가 있다면 중복이다.
        // 따라서 COUNT()를 이용하여 결과가 1인 경우는 true(중복있음)
        // 0인 경우는 false(중복없음)으로 판단한다.
        // 1) 쿼리문 작성
        String query = "SELECT COUNT(USER_ID) FROM TBL_USER “
            + “WHERE USER_ID = ?";

        // 중복 결과 변수
        boolean check = false;

        // 오류가 날 경우를 대비해 try/catch문 사용
        try {
            // 2) DB에 연결하기
            connection = DBConnecter.getConnection();
            // 3) 쿼리 객체를 가져오고 쿼리문을 넣어준다.
            preparedStatement = connection.prepareStatement(query);


            // 4) ? 자리를 채워준다.
            // ※ DB는 무조건 인덱스가 1부터 시작하기 때문에 1로 한다.
            // set___()  : ___는 ? 의 값의 타입에 따라 결정하면 된다.
            // setString() : ?의 값이 String인 경우
            // setInt() : ? 의 값이 Int인 경우
            preparedStatement.setString(1, userId);
            
            // 5)  execute__()로 결과 객체에 담아준다.
            // executeQuery() : 결과가 나오는 경우
            // executeUpdate() : 결과가 없는 경우
            // query를 실행시켜주는 메소드
            resultSet = preparedStatement.executeQuery();

            // 6) 결과 값을 가져온다.
            // 결과 값은 2차원 배열이므로 행과 열에 접근해서 값을 가져온다.
            // 결과 값의 행과 열의 크기를 알 수 없기 때문에 while문을 이용해야한다.
            // 지금의 경우에는 행과 열이 1 이기 때문에 1번씩만 사용한다.
            // next() : 행을 가져오는 메소드
            // get___() : 열을 가져오는 메소드, 마찬가지로 값의 타입에 따라 __이 정해진다.
            resultSet.next();
            
            // 결과 값이 1인 경우 true(중복), 아니면 false(중복x) 
            check = resultSet.getInt(1) == 1;

        } catch (SQLException e) {
            System.out.println("checkId() SQL문 오류");
            e.printStackTrace();
        } finally {
            // finally : 장치를 닫을 때 사용.
            // 열어준 순서의 반대방향으로 닫아준다.
            try {
                // 열지도 않았는데 닫으면 안되기 때문에 null check를 해준다.
                if(resultSet != null) {
                    resultSet.close();
                }
                if(preparedStatement != null) {
                    preparedStatement.close();
                }
                if(connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                // 강제종료
                // 닫다가 오류나면 문제가 발생할 수 있기 때문에 프로세스를 종료해야한다.
                // 강제로 예외를 발생시키는 것.
                throw new RuntimeException(e.getMessage());
            }
        }
        return check;
    }
}

 

//  회원정보 수정
// 생일은 DBMS에서는 DATE타입, Model에서는 String 타입으로 생성했다.
// 그렇기 때문에 TO_DATE를 이용하여 데이터의 포맷을 맞춰주는 작업해야한다.
public void update(UserVO userVO{
String query = "UPDATE TBL_USER "
    + "SET USER_NAME = ?, USER_PASSWORD = ?”
    + “USER_BIRTH_DAY = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'),”
    + "WHERE USER_NUMBER = ?";

    try {
        connection = DBConnecter.getConnection();
        preparedStatement = connection.prepareStatement(query);

        // 쿼리문의 ? 개수만큼 set___() 사용
        preparedStatement.setString(1, userVO.getUserName());
        preparedStatement.setString(2, userVO.getUserPassword());
        preparedStatement.setString(3, userVO.getUserBirthday());
        preparedStatement.setInt(4, userVO.getUserNumber());

        // 결과 값이 없기 때문에 결과 객체를 사용하지 않는다.
        preparedStatement.executeUpdate();
        
     } catch (SQLException e) {
        System.out.println("update() SQL문 오류");
        e.printStackTrace();
     } finally {
        try {
           // 결과 객체가 없기 때문에 결과 객체를 닫을 필요가 없다.
           if(preparedStatement != null) {
              preparedStatement.close();
           }
           if(connection != null) {
              connection.close();
           }
        } catch (SQLException e) {
           throw new RuntimeException(e.getMessage());
        }
     }
  }

 

 

Eclipse jar 인식 오류

https://www.saichoiblog.com/java_on_mac/

 

Java.pdf
0.99MB