* 추상화 ) 실세계의 객체에서 불필요한 부분을 제거하여 필요한 부분만을 간결하고 이해하기 쉬운 클래스로 만드는 것.
* JDBC ? ) DB 연결하기 위해 자바에서 제공하는 인터페이스 == 자바에서 DB에 접속할 수 있도록 하는 자바 API
( 이 인터페이스만 맞추면 연결할 수 있음.)
각 vendor(oracle, mssql, mariadb, mysql...) 들이 인터페이스에 맞게 드라이버 제공.
-> MariaDB 접속해야하기 때문에 MariaDB 드라이버가 필요
jdbc 통해 DB연결 시 프로토콜 (포트, 패턴, url 등을 결정해야함.)
ex) naver 접속 위해서는 http 프로토콜 이용해 주소만 써주면 됨. (웹은 기본으로 80 포트를 포함하고 있기 때문에)
http://www.naver.com == http://www.naver.com:80/ 같은 의미
<CRUD>
C, U, D : 실행한 행의 갯수를 반환
R : ResultSet 반환.
<Java를 통한 JDBC 프로그램 순서>
1. jdbc 드라이버 로드
2. DB Connection 객체 생성
3. SQL을 위한 Statement 객체 생성
4. SQL 쿼리(문장) 실행
5. SQL 실행 결과 처리
6. JDBC 객체들 연결 해제
<실습>
1. 바탕화면에 작업폴더 생성
2. JDBC 드라이버 다운 (MariaDB driver) -> 작업폴더/lib 폴더로 이동. -> 드라이버 인식할 수 있게 라이브러리 추가
* 라이브러리 추가 : Project Structure - libraries에 다운한 .jar 파일 추가하면 lib/ ~~.jar 폴더가 확장되어 안을 볼 수 있음.
3. DB 접속위해 필요한 5가지 정보 : "IP(domain), port, 계정, pw, 인스턴스"를
String url , String dbUserId, String dbPassword 3가지 형태로 기재.
url -> jdbc:DB_VENDER://IP_ADDR:IP_PORT/INSTANCE
ex)
String url = "jdbc:mariab://우분투탄력ip주소:3306/testdb1";
String dbUserId = "testuser1";
String dbPassword = "비번";
< 코드 작성>
1. 드라이버 로드( 예외처리 해줘야함)
try {
Class.forName("org.mariadb.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
* forName 안의 인자는 jar 파일 안에 Driver 클래스에 패키지.클래스명 쓰면 됨. 외울필요 X
2. Connection 객체 생성 (예외처리 필요)
try {
Connection connection = DriverManager.getConnection(url, dbUserId, dbPassword);
} catch (SQLException e) {
e.printStackTrace();
}
3. Statement 객체 생성 (예외처리 필요하므로 Connection try 안에 같이 넣는다.)
try {
Connection connection = DriverManager.getConnection(url, dbUserId, dbPassword);
Statement statement = connection.createStatement();
String sql = "select member_type, user_id, password, name" +
" from member " +
" where member_type = 'email' ";
} catch (SQLException e) {
e.printStackTrace();
}
* Statement 객체 종류 3가지
Statement statement = null; //얘는 파라미터 처리가 안 됨.
PreparedStatement preparedStatement = null; //앞으로 이거 사용
CallableStatement callableStatement = null;
* statement 객체는 new를 통해 생성하는 것이 아닌 connection 객체를 통해 가져옴.
* query문들 사이에 공백 필수 !
4. 쿼리 실행
ResultSet rs = statement.executeQuery(sql);
* execute()는 컬렉션 형태로 반환되지 않아서 executeQuery() 사용
5. 결과 수행
while(rs.next()) {
String memberType = rs.getString("member_type");
System.out.println(memberType);
6. 객체 연결해제
(닫혔는지 확인해줘야하고 각각은 필수로 실행되어야하기 때문에 finally문에 쓰되 또 각각을 예외처리 해줘야함.)
finally {
try {
if (rs != null && !rs.isClosed()) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (preparedStatement != null && !preparedStatement.isClosed()) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
* 여기서 finally는 try문과 다른 scope이기 때문에 객체들 인식을 못 한다.
따라서 Connection, ResultSet, Statement를 try문 밖 앞에 빼서 null로 선언을 해놓는다.
이렇게 하면 일단 끝났는데 추가 사항이 있다.
try {
Connection connection = DriverManager.getConnection(url, dbUserId, dbPassword);
Statement statement = connection.createStatement();
String sql = "select member_type, user_id, password, name" +
" from member " +
" where member_type = 'email' ";
} catch (SQLException e) {
e.printStackTrace();
}
이 쿼리문에서 email을 고정값으로 하드코딩하는 것이 아닌 변수로 원하는 값을 넣어주고 싶다면
String memberTypeValue = "kakao";
String sql ="select member_type, user_id, password, name" +
" from member " +
" where member_type = '" + memberTypeValue + "' ";
이렇게 할 수 있음. 그런데 입력한 값을 그대로 db에 쏴줘버리면 해커가 이 점을 이용해 DB의 모든 정보를 탈취하는 등 SQL Injection 이라는 보안이슈가 발생함.
==> PreparedStatement 로 작업.
Statement를 PreparedStatement로 바꿈.
바꾸면
try {
connection = DriverManager.getConnection(url, dbUserId, dbPassword);
// 3. statement 객체 생성 (얘도 sqlException 발생시켜서 try안에서 진행)
String sql ="select member_type, user_id, password, name" +
" from member " +
" where member_type = ? ";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, memberTypeValue);
// 4. 쿼리 실행
rs = preparedStatement.executeQuery();//쿼리를 실행하면 내용이 컬렉션형태로 반환 되기 때문에 그냥 execute가 아닌 executeQuery로 해야함.
이렇게 됨.
달라진 점은
1. sql문과 preparedStatement 객체 생성 순서가 바뀜. sql문이 먼저 나오고 preparedStatement 객체를 connection 객체 이용하여 생성할 때 prepareStatement(sql) 메소드를 이용하고 인자로 sql 쿼리를 넣어줌.
2. 원하는 값을 넣어주고 싶은 곳을 ?로 두고 preparedStatement.setString(1부터 순서, 넣어주고 싶은 값)을 입력해서 세팅한다.
3. 쿼리 실행시 rs = preparedStatement.executeQuery(); 이용하는 건 같지만 인자를 아무것도 넣어주지 않는다.
'공부 > Trouble Shooting' 카테고리의 다른 글
Open API로 받아온 정보 JSON 파싱 (0) | 2023.09.04 |
---|---|
ExERD 이클립스 플러그인으로 설치 (0) | 2023.08.31 |
윈도우 파일 우분투로 전송 (0) | 2023.08.26 |
윈도우에서 우분투 MariaDB 접속 시 Can't connect to server 오류 (0) | 2023.08.24 |
윈도우에서 우분투 ssh로 원격접속 후 mariaDB 설치 (0) | 2023.08.24 |