-
유데미 스타터스 취업 부트캠프 3기 - 백엔드 6주차스타터스 백엔드 3기 2022. 12. 30. 10:25
하루입니다.
221226 DML, 제약조건
- INSERT, UPDATE, DELETE, ALTER
- PRIMARY KEY, UNIQUE, FOREIGN KEY, (NOT) NULL
delete truncate DELETE from 테이블명 WHERE 조건; TRUNCATE TABLE employees; 레코드(가로)를 삭제한다. 테이블의 모든 레코드를 삭제한다. 특정 조건에 맞는 레코드를 삭제하는 것이 대부분이라,
where를 많이 사용한다.물리적인 기억 장소도 지우고,
임시영역에 로그도 남기지 않는다.autocommit 상태를 false로 한다면 복구 기회가 있다. 복구 기회 없다. where절 사용 가능하다. where절 사용 불가하다. 테이블까지 삭제하기 위해서는 DROP을 사용하자.
221227 JOIN
내가 가장 좋아하는 JOIN!
테이블의 공통행을 연결하고 연결하고 연결해서 값을 뽑아오자!
주의점
1. JOIN 컬럼명 별칭 ON 연결 = 연결
2. 만약 한 레코드가 NULL인데 출력하고 싶다면 (그 컬럼이 왼쪽에 있다는 전제하에) LEFT OUTER JOIN을 해야 한다.

221228 함수
- 문자열 함수, 날짜 함수, 숫자 함수 ...
- 대부분 다른 데이터베이스에서도 사용 가능하나, 날짜함수는 형식이 다를 수 있다.
- 암기하기보다는 이런 게 있다는 걸 인지하고, 필요할 때 찾아쓰자.
221229 트랜잭션, JDBC
트랜잭션의 특징
1. 원자성 : all or nothing. 송금과 출금을 하나로 묶어 더이상 분해 불가한 원자로 취급한다.
2. 격리성 : 트랜잭션 진행 중에는 중간 상태를 보거나 변경 불가하다
3. 일관성 : 데이터의 무결성을 지킨다.
4. 영속성 : 트랜잭션 성공시 수정된 데이터를 시스템에 영구적으로 적용한다.
트랜잭션 안 하는 경우 : 계좌이체 실패 시나리오
- A가 B에게 5000원을 송금하려 합니다.
- 정상적인 결과라면 A의 잔액은 5000원, B의 잔액은 5000원이 되어야 합니다.
- A의 잔액에서 5000원이 빠집니다.
- B의 잔액에 5000원이 추가되어야 하나, 계좌번호를 'BB'라고 적었기에 오류가 발생합니다.
- 하지만 AUTOCOMMIT이 켜져있기에 A의 계좌에서는 이미 5000원이 빠졌습니다. B의 계좌는 여전히 0원입니다.
- 사라진 5000원 ...

트랜잭션 하는 경우 : 계좌이체 성공 시나리오
- A가 B에게 5000원을 송금하려 합니다.
- 정상적인 결과라면 A의 잔액은 5000원, B의 잔액은 5000원이 되어야 합니다.
- A의 잔액에서 5000원이 빠집니다.
- B의 잔액에 5000원이 추가되어야 하나, 계좌번호를 'BB'라고 적었기에 오류가 발생합니다.
- 하지만 AUTOCOMMIT이 꺼져있기에(COMMIT을 하지 않았기에) A계좌에서 빠진 5000원을 ROLLBACK해 원상복구가 가능합니다.
- 결과는 A가 만원, B가 0원으로 처음과 같은 값입니다.

2. JDBC 관련 api들
https://docs.oracle.com/en/java/javase/19/docs/api/index.html
순서
Connection - DriverManager - createStatement - Statement
ResultSet - next, close, wasNull
public interface Connection extends Wrapper, AutoCloseable
- A connection (session) with a specific database. SQL statements are executed and results are returned within the context of a connection.
- 특정 데이터베이스와의 연결(세션)입니다. SQL 문이 실행되고 연결 컨텍스트 내에서 결과가 반환됩니다.public class DriverManager {
// List of registered JDBC drivers
private static final CopyOnWriteArrayList<DriverInfo>;
private static loginTimeout = 0;
private static PrintWriter logWriter = null;
private static PrintStream logStream = null;
private static final String JDBC_DRIVERS_PROPERTY = "jdbc.drivers";
}
- The basic service for managing a set of JDBC drivers.
- The {@link javax.sql.DataSource} interface, provides
another way to connect to a data source.
The use of a {@code DataSource} object is the preferred means of connecting to a data source.
As part of its initialization, the {@code DriverManager} class will attempt to load available JDBC drivers by using:
- {@link javax.sql.DataSource} 인터페이스, 제공 데이터 소스에 연결하는 또 다른 방법입니다.
- 데이터 소스에 연결할 때는 {@codeDataSource} 개체를 사용하는 것이 좋습니다. 초기화의 일환으로 {@codeDriverManager} 클래스는 다음을 사용하여 사용 가능한 JDBC 드라이버를 로드하려고 시도합니다.public interface Connection extends Wrapper, AutoCloseable {
Statement createStatement() throws SQLException;
}
- Creates a {@code Statement} object for sending SQL statements to the database. SQL statements without parameters are normally executed using {@code Statement} objects. If the same SQL statement is executed many times, it may be more efficient to use a {@code PreparedStatement} object.
- Result sets created using the returned {@code Statement}
object will by default be type {@code TYPE_FORWARD_ONLY} and have a concurrency level of {@code CONCUR_READ_ONLY}.
- SQL 문을 데이터베이스로 보내기 위한 {@codeStatement} 개체를 생성합니다. 매개 변수가 없는 SQL 문은 일반적으로 {@codeStatement} 개체를 사용하여 실행됩니다. 동일한 SQL 문이 여러 번 실행되는 경우 {@codePreparedStatement} 개체를 사용하는 것이 더 효율적일 수 있습니다.
- 반환된 {@codeStatement}을(를) 사용하여 생성된 결과 집합
개체는 기본적으로 {@code TYPE_FORWARD_ONLY} 유형이 됩니다. 동시성 수준은 {@code CONCURE_READ_입니다.만}.public interface Statement extends Wrapper, AutoCloseable {
}
- The object used for executing a static SQL statement and returning the results it produces.
By default, only one {@code ResultSet} object per {@code Statement} object can be open at the same time. Therefore, if the reading of one {@code ResultSet} object is interleaved with the reading of another, each must have been generated by different {@code Statement} objects. All execution methods in the {@code Statement} interface implicitly close a current {@code ResultSet} object of the statement if an open one exists.
- 정적 SQL 문을 실행하고 결과를 반환하는 데 사용되는 개체입니다. 기본적으로 {@codeStatement} 개체당 하나의 {@codeResultSet} 개체만 동시에 열 수 있습니다. 따라서 한 {@codeResultSet} 개체의 읽기가 다른 개체의 읽기와 인터리브되는 경우 각 개체가 서로 다른 {@codeStatement} 개체에 의해 생성되어야 합니다. {@codeStatement} 인터페이스의 모든 실행 메서드는 열려 있는 문이 있는 경우 해당 문의 현재 {@codeResultSet} 개체를 암시적으로 닫습니다.public interface Statement extends Wrapper, AutoCloseable {
ResultSet executeQuery(String sql)
throws SQLException;
int executeUpdate(String sql) throws SQLException;
void close() throws SQLException;
}
executeQuery()
- ResultSet executeQuery(String sql) throws SQLException
- ResultSet단일 개체 를 반환하는 지정된 SQL 문을 실행 합니다.
- PreparedStatement 이 메서드는 또는 CallableStatement에서 호출할 수 없습니다 .
executeUpdate()
- int executeUpdate(String sql) throws SQLException
- 주어진 SQL 문을 실행합니다. 이 문은 INSERT, UPDATE또는 DELETE문이거나 SQL DDL 문과 같이 아무것도 반환하지 않는 SQL 문일 수 있습니다.
- PreparedStatement 이 메서드는 또는 CallableStatement에서 호출할 수 없습니다 .
close()
- void close() throws SQLException
- Statement자동으로 닫힐 때까지 기다리지 않고 이 개체의 데이터베이스와 JDBC 리소스를 즉시 해제합니다. 일반적으로 데이터베이스 리소스가 묶이지 않도록 작업을 마치는 즉시 리소스를 해제하는 것이 좋습니다.이미 닫힌 Statement 개체 에서 메서드 close를 호출해도 아무런 효과가 없습니다.
- Statement 개체가 닫히면 현재 개체( 있는 ResultSet경우)도 닫힙니다.public interface ResultSet extends Wrapper, AutoCloseable {
boolean next() throws SQLException;
void close() throws SQLException;
boolean wasNull() throws SQLException;
String getString throws SQLException;
boolean getBoolean throws SQLException;
int getInt throws SQLException;
float getFloat throws SQLException;
double getDouble throws SQLException;
// 그 외 byte[], Timestamp, Date, Array 등 ...
}
- 데이터베이스 결과 집합을 나타내는 데이터 테이블로, 일반적으로 데이터베이스 쿼리문을 실행하여 생성됩니다.
- ResultSet 개체는 현재 데이터 행을 가리키는 커서를 유지합니다. 처음에는 커서가 첫 번째 행 앞에 배치됩니다. 다음 메소드는 커서를 다음 행으로 이동하고 ResultSet 개체에 더 이상 행이 없을 때 false를 반환하므로 결과 집합을 반복하는 동안 루프에서 사용할 수 있습니다.
- ResultSet 인터페이스는 현재 행에서 열 값을 검색하기 위한 더 나은 메서드(getBoolean, getLong 등)를 제공합니다. 열의 인덱스 번호 또는 열의 이름을 사용하여 값을 검색할 수 있습니다. 일반적으로 열 인덱스를 사용하는 것이 더 효율적입니다. 열에는 1부터 번호가 매겨집니다. 이동성을 최대화하려면 각 행 내 결과 집합 열을 왼쪽에서 오른쪽 순서로 읽고 각 열을 한 번만 읽어야 합니다.
- getter 메소드의 경우, JDBC 드라이버는 기본 데이터를 getter 메소드에 지정된 Java 유형으로 변환하려고 시도하고 적절한 Java 값을 반환합니다.
- 가져오기 메서드에 대한 입력으로 사용되는 열 이름은 대소문자를 구분하지 않습니다. 열 이름으로 게터 메서드를 호출하고 여러 열의 이름이 동일하면 첫 번째 일치 열 값이 반환됩니다. 열 이름 옵션은 결과 집합을 생성한 SQL 조회에서 열 이름을 사용할 때 사용하도록 설계되었습니다. 쿼리에 명시적으로 이름이 지정되지 않은 열의 경우 열 번호를 사용하는 것이 가장 좋습니다. 열 이름이 사용되는 경우 프로그래머는 SQL AS 절을 통해 보장할 수 있는 의도된 열을 고유하게 참조하도록 주의해야 합니다.
- ResultSet 개체는 생성한 Statement 개체가 닫히거나, 다시 실행되거나, 여러 결과 시퀀스에서 다음 결과를 검색하는 데 사용될 때 자동으로 닫힙니다.
- ResultSet 개체의 열 수, 유형 및 속성은 ResultSet.getMetaData 메서드에서 반환하는 ResultSetMetaData 개체에 의해 제공됩니다.public interface ResultSet extends Wrapper, AutoCloseable {
boolean next() throws SQLException;
void close() throws SQLException;
boolean wasNull() throws SQLException;
}
next()
- boolean next() throws SQLException
- 커서를 현재 위치에서 한 행 앞으로 이동합니다. ResultSet커서는 처음에 첫 번째 행 앞에 위치합니다 . 메서드에 대한 첫 번째 호출은 next첫 번째 행을 현재 행으로 만듭니다. 두 번째 호출은 두 번째 행을 현재 행으로 만드는 식입니다.메서드 호출이 next반환 false되면 커서는 마지막 행 뒤에 위치합니다. ResultSet현재 행이 필요한 메서드를 호출하면 예외 SQLException가 발생합니다.
- true : 새로운 현재 행이 유효한 경우
- false : 더 이상 행이 없는 경우
- SQLException- 데이터베이스 액세스 오류가 발생하거나 닫힌 결과 집합에서 이 메서드가 호출된 경우
close()
- void close() throws SQLException
- ResultSet가 자동으로 닫힐 때까지 기다리지 않고 이 개체의 데이터베이스와 JDBC 리소스를 즉시 해제합니다.
-SQLException- 데이터베이스 접근 오류가 발생한 경우
wasNull()
void wasNull() throws SQLException
- 마지막으로 읽은 열의 값이 SQL NULL인지 여부를 보고합니다 . 먼저 열에서 getter 메서드 중 하나를 호출하여 해당 값을 읽은 다음 해당 메서드 wasNull를 호출하여 읽은 값이 SQL NULL인지 확인해야 합니다.
- true : 읽은 마지막 열 값이 SQL NULL인 경우
- false : 그렇지 않은 경우
- SQLException- 데이터베이스 액세스 오류가 발생하거나 닫힌 결과 집합에서 이 메서드가 호출된 경우public interface Connection extends Wrapper, AutoCloseable {
PreparedStatement prepareStatement(String sql)
throws SQLException;
}
- 미리 컴파일된 SQL 문을 나타내는 개체입니다.SQL 문은 미리 컴파일되어 PreparedStatement개체에 저장됩니다. 그런 다음 이 개체를 사용하여 이 문을 여러 번 효율적으로 실행할 수 있습니다.https://harutocoding.tistory.com/209
extends와 implements의 차이 : 인터페이스가 인터페이스를 extends하는 이유
하루입니다. ... 뭔가 이상하지 않나요? Wrapper와 AutoCloseable은 interface입니다. 그런데 왜!!!!!!!!!!!!!!!!!!! implements가 아니라 extends일까요!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 그 차이는 interface의 특성과 extends/implemen
harutocoding.tistory.com
221230 JDBC 실습

- 약간 ... 세미 스프링?
- 이제 역할별로 클래스를 구분한다.
- MemberMain에서 메뉴값을 입력받는다. 메뉴값에 따라 다른 xxxview로 이동한다.
- view라는 인터페이스를 만들고. 구현클래스들이 input이라는 메소드를 구현하게 만든다.
- dto는 변수클래스로, xxxview에서 받은 값을 임시로 담는 곳이다.
- 연결과 로직이 정상적이라면 memberdb에 정상적으로 값이 담긴다.
- CRUD에서 C와 R 했다
후기
- 6주가 지났다는 게 믿을 수 없다. 할 게 많다. 예전엔 하루는 느리고 일주일은 짧았다면, 이젠 하루도 빠르고 일주일도 빠르고 주말은 더 빠르다.
- 왜 API 공식문서를 살펴야 하는지 알았다. 그동안 왜 이런 식으로 사용하지? 라고 생각했던 것들의 퍼즐이 맞춰졌다. 예를 들어, Statement interface 안에는 executeQuery 추상메소드가 있다. 이 메소드는 ResultSet을 반환값으로 한다. 그래서 ResultSet rs = pre.executeQuery(); 로 적는 것이다. Connection interface 안에는 prepareState 추상메소드가 있는데, 반환값이 PreparedStatement다. 그래서 PreparedStatement pre = con.prepareStatement(sql);로 적는다.
- 동료 학습의 효과를 느꼈다. 그동안 왜 코드리뷰 혹은 페어 리뷰 등의 필요성을 느끼지 않았다. 하지만 동료들의 코드를 보는 것만으로도 이렇게도 풀 수 있구나, 이걸 이렇게 적용할 수 있구나 하면서 시야의 폭을 넓힐 수 있었다. 예를 들어 알고리즘 문제라던가, implements와 extends의 차이라던가, 내가 아는 것을 설명해 줄 때라던가. 슬쩍 가서 스트레스볼 조물거리며 코드 구경하기 *✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾
- 요즘 이클립스에서 인터페이스 구경하는 재미에 빠졌다. API 구경을 위해서는 컨트롤을 누르고 메소드를 누르거나, ctrl shift T를 누르고 검색하는 방법이 있다. 정말 재밌어 !
- 정말로 체력의 중요성을 느끼고 있다. 운동을 해야 하는데 진짜로 물리적인 시간이 없다. 운동하시는 분들 정말 대단하다고 생각함.
- 할 게 너무 너무 많아! 잠을 안 잔다면 다 할 수 있을텐데.
할 말은 많지만 조금 줄인 일지 끝
하루 끝!
* 유데미 바로가기 : https://bit.ly/3V220ri
본 후기는 유데미-웅진씽크빅 취업 부트캠프 3기 백엔드 과정 학습 일지 리뷰로 작성되었습니다.'스타터스 백엔드 3기' 카테고리의 다른 글
[ Servlet / JSP ] 1. 기초 (0) 2023.01.03 221230. DB 10. JDBC (수정, 삭제) (0) 2023.01.03 221229. DB 8. JDBC (0) 2022.12.29 221229. DB 7. 트랜잭션 (0) 2022.12.29 221228. DB 6. 함수, (트랜잭션) (0) 2022.12.28