데이터 수정
JDBC를 이용해 UPDATE문을 실행해보자.
boards 테이블에 저장된 게시물 중에서 bno가 3인 게시물의 btitle, bcontent, bfilename, bfiledata를 변경해보자.
package mariadb;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class BoardUpdateExampleApp {
public static void main(String[] args) {
Connection conn = null;
String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
String JDBC_URL = "jdbc:mariadb://localhost:3306/thisisjava";
String USER = "root";
String PASSWORD = "mariadb";
try {
// JDBC_DRIVER 등록
Class.forName(JDBC_DRIVER);
// 연결
conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
// 매개변수화된 SQL문 작성
String sql = new StringBuilder()
.append("UPDATE boards SET")
.append("btitle = ?, ")
.append("bcontent = ?, ")
.append("bfilename = ?, ")
.append("bfiledata = ?, ")
.append("WHERE bno = ?")
.toString();
// PrepareStatement 객체 얻기 및 값 지정
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "눈사람");
pstmt.setString(2, "눈으로 만든 사람");
pstmt.setString(3, "snowman.jpg");
pstmt.setBlob(4, new FileInputStream("src/mariadb/images/snowman.jpg"));
pstmt.setInt(5, 3);
// SQL문 실행
int rows = pstmt.executeUpdate();
System.out.println("수정된 행 수 : " + rows);
// PreparedStatement 닫기
pstmt.close();
} catch(Exception e) {
e.printStackTrace();
} finally {
if (conn != null ) {
try {
conn.close();
} catch (SQLException e) {}
}
}
}
}
※ 오류 발생 : SQLSyntaxErrorException 에러
java.sql.SQLSyntaxErrorException: (conn=80) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE bno = 3' at line 1
- 로그 이용해 DB와의 연결까지는 제대로 진행됨을 알 수 있었다.
- 구글 검색 결과, SQL Syntax의 규칙을 위반할 경우, SQLSyntaxErrorException가 발생한다고 한다.
- 그래서 오타가 있는지 살펴보았다.
아무리 봐도 어떤 문법에서 오류가 났는지 모르겠다.
사용자 정보 읽어오기 - DTO 클래스
package mariadb;
import lombok.Data;
// @ 어노테이션 : 특수한 기능을 실행하는 자바의 실행 주석
@Data // lombok 라이브러리에게 생성자, setter/getter 메서드를 생성하라는 의미
public class User {
// 멤버변수 ( 접근제어자 : private )
private String userId;
private String userName;
private String userPassword;
private int userAge;
private String userEmail;
}
- 멤버 변수의 접근제어자 : private로 지정
→ 속성함수 (getter/setter함수)를 이용해 외부에서 접근하자
- Getter / Setter 함수 만드는 방법
① 직접 입력
② 이클립스의 자동 생성 방법 ( Source - Generate Getters and Setters... )
③ 롬복(lombok)이라는 개발 지원툴 라이브러리 이용
프로젝트 개발 실행 시, 자동생성
lombok 설치 방법
▶ 맥북 설치 방법
① 구글 검색 - 홈페이지 이동 - Download 1.18.28 다운로드 - lombok.jar 파일 다운로드됨
② 터미널 - 다운로드 파일로 접근 - 롬복 실행
③ 아래와 같이 Installer 창이 뜸 - [ Specify location ] 클릭 → 최종적으로 SpringToolSuite4.ini 선택 - [ Install / Update ]
→ 성공적으로 다운로드되었다는 창이 뜸
( dev / ide / workspace-spring-tool-suite-4-4.18.0.RELEASE / SpringToolSuite4 / Contents / Eclipse 폴더 내에 SpringToolSuite4.ini 존재함 )
▶ window에서 설치하는 방법
( lombok 다운로드 방법은 위와 동일 )
① lombok.jar 파일이 다운된 경로 복사 → 명령 프롬프트 창에 아래와 같이 입력 후 Enter
② Installer 창 - [ Specify location ] - dev\ide\sts-4.18.0.RELEASE\STS4.exe 선택 → [ Install / Update ] 클릭
③ 성공적으로 다운로드되었다는 창이 뜸 → 설치 완료 후, STS 종료한 뒤 재실행
※ 만약 lombok이 실행되지 않을 경우
Build Path 클릭해서 이전에 했던 방식대로 Modulepath 아래에 적용시킨 후, Package Explorer 창에서 확인
⇒ [ Source ] - [ Generate Getters and Setters... ] 클릭 시, 아래 사진과 같이 이미 만들어졌다는 창이 뜸
∴ lombok @Data가 제대로 실행되고 있음
사용자 정보 읽기
users 테이블에서 userid가 winter인 사용자의 정보를 가져와 출력해보자.
먼저 users 테이블의 한 개의 행 ( 사용자 )을 저장할 User 클래스를 작성하자.
컬럼 개수와 타입에 맞게 필드를 선언하고, lombok @Data 어노테이션을 이용해서 Getter, Setter, toString( ) 메서드를 자동 생성시키자.
package mariadb;
import lombok.Data;
@Data // @ 어노테이션 : 특수한 기능을 실행하는 자바의 실행 주석
public class User {
// 멤버변수 ( 접근제어자 : private )
private String userId;
private String userName;
private String userPassword;
private int userAge;
private String userEmail;
}
① DTO 클래스
즉, 데이터 클래스에서는 '@Data'를 사용하여 생성자, Getter / Setter, toString( ) 메서드를 자동으로 생성시킴
② 외부에서 멤버 변수에 접근할 수 있는 속성함수 ( Getter / Setter 함수 ) 작성하는 방법
❶ 직접 입력
❷ 이클립스의 자동 생성 방법 : [ Source ] - [ Generate Getters and Setters ]
❸ lombok이라는 개발 지원 툴 라이브러리 사용 → 프로젝트 개발 실행 시, 자동 생성
package mariadb;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// DAO 클래스
public class UserSelectExampleApp {
public static void main(String[] args) {
Connection conn = null ;
String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
String JDBC_URL = "jdbc:mariadb://localhost:3306/thisisjava";
String USER = "root";
String PASSWORD = "mariadb";
try {
// 드라이버 찾기
Class.forName(JDBC_DRIVER);
System.out.println("DRIVER 로딩 성공!");
// MariaDB와 연결
conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
System.out.println("MariaDB와 연결 성공!");
// SELECT문 정의
String sql = "" +
"SELECT userid, username, userpassword, " +
" userage, useremail " +
" FROM users " +
" WHERE userid = ? ";
// preparedStatement 얻기 및 값 인수 지정
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "winter");
// SQL 실행 후 결과 얻기 (executeQuery()메서드 : ResultSet 반환)
ResultSet rs = pstmt.executeQuery();
// 한 개의 레코드만 가져왔다고 가정하자.
if(rs.next()) { // 사용자 아이디 발견
// DTO 클래스 사용
// ① 생성자를 이용해 초기화
User user = new User();
// ② 속성함수 이용
user.setUserId(rs.getString("userid"));
user.setUserName(rs.getString("username"));
user.setUserPassword(rs.getString("userpassword"));
user.setUserAge(rs.getInt(4));
user.setUserEmail(rs.getString(5));
System.out.println(user);
// println(object obj); -> user : 객체
// println 메서드에 매개변수로 객체가 들어갈 경우,
// 객체.toString()으로 변환하여 출력함
} else {
// SELECT 질의 결과, 데이터가 없는 경우
System.out.println("사용자 아이디가 존재하지 않습니다.");
}
} catch(ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
} finally {
if(conn != null) {
try {
conn.close();
} catch(SQLException e) {}
}
}
}
}
※ 오류 발생
- lombok를 설치하고 Referenced Libraries에 적용시켰는데, Setter 속성함수가 정의가 되지 않았다고 한다.
- User 클래스에서 [ Source ] - [ Generate Getters and Setters ]한 결과, 생성 창이 뜬다.
- lombok 설치가 제대로 되지 않은 듯 하다.
⇒ 일단, User 클래스에 Setter 속성함수와 toString( ) 메서드를 직접 작성하고 나중에 해결하자.
▷ 출력 결과
게시물 정보 읽기
package mariadb;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BoardSelectExample {
public static void main(String[] args) {
Connection conn = null;
String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
String JDBC_URL = "jdbc:mariadb://localhost/thisisjava";
String USER = "root";
String PASSWORD = "mariadb";
// -> 보안 )인증
try {
Class.forName(JDBC_DRIVER);
System.out.println("DRIVER 로딩 성공!");
conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
System.out.println("MariaDB와 연결 성공!");
// MariaDB에 질의할 SELECT SQL 정의
String sql = "" +
"SELECT " +
" bno, btitle, bcontent, bwriter, " +
" bdate, bfilename, bfiledata " +
" FROM boards " +
" WHERE bwriter = ?; ";
// preparedStatement 명령객체 생성 및 인수 값 지정
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "winter");
// SQL문 실행 후, ResultSet 값 얻기
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
// 데이터 행을 읽고 각 컬럼 값을 대입하여 DTO 객체인 Board 객체 생성
Board board = new Board();
// 기본생성자를 통해 모든 멤버변수가 null값으로 초기화됨.
board.setBno(rs.getInt("bno"));
board.setBtitle(rs.getString("btitle"));
board.setBcontent(rs.getString("bcontent"));
board.setBwriter(rs.getString("bwriter"));
board.setBdate(rs.getDate("bdate"));
board.setBfilename(rs.getString("bfilename"));
board.setBfiledata(rs.getBlob("bfiledata"));
// 메모리로 올림
// 콘솔에 내용출력
System.out.println(board);
// println()메서드의 매개변수로 참조변수가 들어오는 경우
// 참조변수를 참조변수.toString()으로 변환해서 출력됨
// board 객체의 bfiledata를 파일로 저장
// board DTO객체의 Blob 형식 bfiledata의 참조주소를
// blob 변수에 저장
// 참조라는 것은 원본데이터를 직접 접근할 수 있다.
// 참조변수가 원본을 바꾸면 원본이 변한다.
// 새로운 변수를 만들면 접근경로가 짧아진다. 접근하기 쉬워짐.
Blob blob = board.getBfiledata();
// board 테이블의 bfiledata를 읽어와서
// Blob 타입의 참조변수 blob에 참조주소를 저장시킴
if(blob != null) {
// getBinaryStream이라는 의미는
// blob 객체로부터 얻어온다 = 읽어온다(=read) = 입력한다(=input)
InputStream is = blob.getBinaryStream();
// 메모리에 있는 게 파일로 저장되어야 함.
OutputStream os;
String folderPath = "/Users/dahee/Desktop/temp/";
String filepath = folderPath + board.getBfilename();
File folder = new File(folderPath);
if(!folder.exists()) {
try {
folder.mkdir(); // 폴더를 생성
System.out.println("폴더를 생성했습니다!");
} catch(Exception e) {
e.printStackTrace();
}
}
os = new FileOutputStream(filepath);
is.transferTo(os);
os.flush();
os.close();
is.close();
}
rs.close();
// preparedStatement 닫기
pstmt.close();
}
} catch(ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
} finally {
if(conn != null) {
try {
conn.close();
} catch(SQLException e) {}
}
}
}
}
※ 맥에서 파일 폴더의 경로 위치정보 얻는 방법
❶ 해당 폴더에서 오른쪽 클릭 - [ 정보 가져오기 ] 클릭
❷ 해당 폴더의 정보 창이 뜸 - [ 위치 ] 에서 오른쪽 클릭 - [ 경로 이름으로 복사 ] → 붙여넣기하면 됨
▷ 출력 결과
① bfiledata 컬럼의 그림 데이터는 bfilename 컬럼 값을 파일명으로 해서 /Users/dahee/Desktop/temp/ 디렉토리에 저장됨
② 콘솔 출력 결과
※ 오류 발생 : Operation not permit on a closed resultSet
'백엔드 > JAVA' 카테고리의 다른 글
게시판 구현 (2) (0) | 2023.06.07 |
---|---|
게시판 구현 (1) (0) | 2023.06.02 |
데이터 입출력(1) (0) | 2023.05.30 |
JDBC 드라이버 다운로드 및 등록 (0) | 2023.05.23 |
H2 데이터베이스 연결 (2) (0) | 2023.05.22 |