Java와 MYSQL연동해서 SELECT하기🔧
1. JAVA에 JDBC Driver를 설치
JDBC
오라클, mysql 과 같은 다양한 DBMS와 접속이 가능하도록 표준화된 방법으로 만든 API
= 자바 프로그램에서 다른 기종 간의 데이터베이스를 표준화된 방법으로 접속할 수 있도록 만든 API
JDBC Driver (제이디비씨 드라이버)
MYSQL(사용 DBMS)에서 제공하는 JDBC드라이브가 있어야지 자바와 연결을 하는 기능을 제공한다.
2. JAVA에 JDBC드라이브 로딩
//1. JDBC드라이브 로딩
try {
Class.forName("com.mysql.cj.jdbc.Driver"); //다른 서버 접속시 바뀌는 부분
} catch (Exception e) {
e.printStackTrace();
}
👇 forName
public static Class<?> forName(String className) throws ClassNotFoundException
3. Connection [커넥션] 객체 생성
// import되어야함
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
String url = "jdbc:mysql://localhost:3306/jdbcdb"; //다른 서버 접속시 바뀌는 부분
String uesr = "[DB USER ID]";
String password = "[DB USER PW]";
conn = DriverManager.getConnection(url, uesr, password); //import됨
} catch (Exception e) {
e.printStackTrace();
}
👇 getConnection
public static Connection getConnection(String url, String user, String password) throws SQLException
4.
SQL로 전송 객체 생성
SQL문을 MySQL 서버에 전송한다.
3번에 conn = DriverManager.getConnection(url, uesr, password); 아래에 코드를 이어서 작성한다.
~~~~~~~~~~~~~~~~
// 3. SQL로 전송 객체 생성
stmt = conn.createStatement();
// 4. SQL문을 MySQL 서버에 전송한다.
StringBuffer sql = new StringBuffer();
sql.append("SELECT id, name, age, grade, point ");
sql.append("FROM customer ");
sql.append("ORDER BY id ASC");
rs = stmt.executeQuery(sql.toString());
while (rs.next()) { //row가 있으면 true, 없으면 false
String id = rs.getString(1);
String name = rs.getString(2);
int age = rs.getInt(3);
String grade = rs.getString(4);
int point = rs.getInt(5);
System.out.printf("%s, %s, %d, %s, %d%n", id, name, age, grade, point);
}
~~~~~~~~~~~~~~~~
그리고 catch { }뒤에 finally을 추가한다.
rs랑 stmt등.. 이제는 안쓸 선언니까 자원을 지워두겠다는 의미로 close를 사용한다.
finally {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
👇 executeQuery
ResultSet executeQuery(String sql) throws SQLException
👇 getString
String getString(int columnIndex) throws SQLException
5. 최종
package jdbcApp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/*
* 작성일자: 2021-09-07
* 프로그램 설명: SQL결과 java로 가져오기
*/
public class selectExam {
public static void main(String[] args) {
// 1. JDBC드라이브 로딩
try {
Class.forName("com.mysql.cj.jdbc.Driver"); // 다른 서버 접속시 바뀌는 부분
} catch (Exception e) {
e.printStackTrace();
}
// 2. Connection 객체 생성
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
String url = "jdbc:mysql://localhost:3306/jdbcdb"; // 다른 서버 접속시 바귀는 부분
String uesr = "jdbc";
String password = "jdbc1234";
conn = DriverManager.getConnection(url, uesr, password);
// 3. SQL로 전송 객체 생성
stmt = conn.createStatement();
// 4. SQL문을 MySQL 서버에 전송한다.
StringBuffer sql = new StringBuffer();
sql.append("SELECT id, name, age, grade, point ");
sql.append("FROM customer ");
sql.append("ORDER BY id ASC");
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
int age = rs.getInt(3);
String grade = rs.getString(4);
int point = rs.getInt(5);
System.out.printf("%s, %s, %d, %s, %d%n", id, name, age, grade, point);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//resource release
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
Statement
1. 단일 SQL 문을 수행할 때 속도가 빠르다.
2. 쿼리에 인자를 부여할 수 없다.
3. 매번 컴파일을 수행한다.
PreparedStatement
1. 쿼리에 인자를 부여할 수 있다.
2. 처음 프리컴파일 된 후, 이후에는 컴파일을 수행하지 않는다.
3. 동일한 SQL 문을 반복적으로 수행할 때 효율적이다
Java와 MYSQL연동해서 INSERT하기🔧 (feat.PreparedStatement)
위에 2번까지는 동일하다.
3.
Connection [커넥션] 객체 생성
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
//2. Connection 객체 생성
Connection conn = null;
PreparedStatement pstmt = null;
try {
String url = "jdbc:mysql://localhost:3306/jdbcdb"; //다른 서버 접속시 바뀌는 부분
String uesr = "jdbc";
String password = "jdbc1234";
conn = DriverManager.getConnection(url, uesr, password); //import됨
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
} catch (Exception e2) {
e2.printStackTrace();
}
}
4.
SQL로 전송 객체 생성
SQL문을 MySQL 서버에 전송한다.
3번에 conn = DriverManager.getConnection(url, uesr, password); 아래에 코드를 이어서 작성한다.
//3. Connection 객체 생성
conn = DBConn.getConnection();
// 4. SQL문을 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO customer ( id, name, age, grade, point ) ");
sql.append("VALUES ( ?, ?, ?, ?, ? ) ");
pstmt = conn.prepareStatement(sql.toString()); ✨
pstmt.setString(1, "java4");
pstmt.setString(2, "사길동");
pstmt.setInt(3, 40);
pstmt.setString(4, "vip");
pstmt.setInt(5, 10);
//5. sql문 실행(sql문을 서버에 전송)
int rowCount = pstmt.executeUpdate(); ✨✨
if(rowCount == 1) { ✨✨✨
System.out.println("등록!");
}
✨
PreparedStatement pstmt = null;
pstmt = conn.prepareStatement(sql.toString());
?를 변경해야하는 경우에는 prepareStatement 를 사용하고,
쿼리를 수정할 필요없이 작동시킬 것이라면 createStatement로 sql전송객체를 만들면 된다.
✨✨
int rowCount = pstmt.executeUpdate();
//executeQuery는 가져올때! executeUpdate는 수정할때 사용!
✨✨✨
int rowCount = pstmt.executeUpdate();
if(rowCount == 1) {
쿼리가 실행된 다음 변경된 데이터 갯수
5. 최종
package jdbcApp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/*
* 작성일자: 2021-09-07
* 프로그램 설명: java로 SQL추가하기
*/
public class InsertExam {
public static void main(String[] args) {
//1. JDBC드라이브 로딩
try {
Class.forName("com.mysql.cj.jdbc.Driver"); //다른 서버 접속시 바뀌는 부분
} catch (Exception e) {
e.printStackTrace();
}
//2. Connection 객체 생성
Connection conn = null;
PreparedStatement pstmt = null;
try {
//3. Connection 객체 생성
String url = "jdbc:mysql://localhost:3306/jdbcdb"; //다른 서버 접속시 바뀌는 부분
String uesr = "jdbc";
String password = "jdbc1234";
conn = DriverManager.getConnection(url, uesr, password); //import됨
// 4. SQL문을 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO customer ( id, name, age, grade, point ) ");
sql.append("VALUES ( ?, ?, ?, ?, ? ) ");
//?를 변경해야하는 경우에는 prepareStatement 를 사용하고 쿼리를 수정할 필요없이
//작동시킬 것이라면 createStatement로 sql전송객체를 만들면 된다.
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, "java4");
pstmt.setString(2, "사길동");
pstmt.setInt(3, 40);
pstmt.setString(4, "vip");
pstmt.setInt(5, 10);
//5. sql문 실행(sql문을 서버에 전송)
//executeQuery는 가져올때! executeUpdate는 수정할때 사용
int rowCount = pstmt.executeUpdate();
//rowCount => 는 위의 쿼리로 변경된 데이터 갯수
if(rowCount == 1) {
System.out.println("등록!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
//resource release
if (conn != null) conn.close();
if (pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
DB 연결 모듈화, 모듈 연동🧱
매번 쿼리를 가져올때마다 DB연결할 필요없이 CLASS로 만들어서 모듈화하면 편하게 사용할 수 있다.
1. DBConn.class 생성
package jdbcApp;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBConn {
public static Connection getConnection() throws Exception { ✨
// 1. JDBC드라이브 로딩
Class.forName("com.mysql.cj.jdbc.Driver"); // 다른 서버 접속시 바뀌는 부분
//3. DB에 접속한다
String url = "jdbc:mysql://localhost:3306/jdbcdb"; //다른 서버 접속시 바뀌는 부분
String uesr = "[DB USER ID]";
String password = "[DB USER PW]";
//conn = DriverManager.getConnection(url, uesr, password); //import됨
//return conn;
return DriverManager.getConnection(url, uesr, password);
}
}
✨
해당 모듈에 오류가 생기면 실행시킨 곳으로 오류를 보낸다.
2.중복 부분 모듈화하기
package jdbcApp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/*
* 작성일자: 2021-09-07
* 프로그램 설명: java로 SQL추가하기
*/
public class InsertExam {
public static void main(String[] args) {
//1. JDBC드라이브 로딩 - 모듈화로 인해 생략 ✨
//2. Connection 객체 생성
Connection conn = null;
PreparedStatement pstmt = null;
try {
//3. 모듈화로 아래와 같이 변경 ✨✨
conn = DBConn.getConnection();
// 4. SQL문을 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO customer ( id, name, age, grade, point ) ");
sql.append("VALUES ( ?, ?, ?, ?, ? ) ");
//?를 변경해야하는 경우에는 prepareStatement 를 사용하고 쿼리를 수정할 필요없이
//작동시킬 것이라면 createStatement로 sql전송객체를 만들면 된다.
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, "java6");
pstmt.setString(2, "사길동");
pstmt.setInt(3, 40);
pstmt.setString(4, "vip");
pstmt.setInt(5, 10);
//5. sql문 실행(sql문을 서버에 전송)
//executeQuery는 가져올때! executeUpdate는 수정할때 사용
int rowCount = pstmt.executeUpdate();
//rowCount => 는 위의 쿼리로 변경된 데이터 갯수
if(rowCount == 1) {
System.out.println("등록!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
//resource release
if (conn != null) conn.close();
if (pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
Java와 MYSQL연동해서 UPDATE하기🔧
INSERT하는 방식과 동일하다
package jdbcApp;
import java.sql.Connection;
import java.sql.PreparedStatement;
/*
* 작성일자: 2021-09-07
* 프로그램 설명: 고객의 id가 java1인 고객의 등급 vip, 포인트는 10으로 바꾸기
*/
public class UpdateExam {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 1. Connection 객체 생성
conn = DBConn.getConnection();
// 2. sql문 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("UPDATE customer ");
sql.append("SET grade = ?, point = ? ");
sql.append("WHERE id = ? ");
pstmt = conn.prepareStatement(sql.toString());
//물음표에 값 넣기
pstmt.setString(1, "vip");
pstmt.setInt(2, 10);
pstmt.setString(3, "java1");
int rowCount = pstmt.executeUpdate();
if(rowCount == 1) {
System.out.println("등록!");
}else {
System.out.println("오류!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java와 MYSQL연동해서 DELECT하기🔧
INSERT하는 방식과 동일하다
package jdbcApp;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class DeleteExam {
public static void main(String[] args) {
//1.컨넥션 객체 생성
Connection conn = null;
//3.데이터를 어떻게 담아서 보낼지 정할 부분
PreparedStatement pstmt = null;
//2.접속 결과 확인
try {
conn = DBConn.getConnection();
//4.sql문 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("DELETE FROM customer ");
sql.append("WHERE id = ? ");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, "java1");
int rowCount = pstmt.executeUpdate();
if(rowCount == 1) {
System.out.println("삭제 성공!");
}else {
System.out.println("삭제 실패!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(conn != null) conn.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
(예제) 고객정보를 수정,추가,관리 해보기🛒
1.
고객정보를 구현한 클래스를 만든다
이름규칙 : 프로젝트명AO
package customAPP;
//고객정보를 구현한 클래스
public class CustomerVO {
// 1. 인스턴스 변수 선언
private String id;
private String name;
private int age;
private String grade;
private int point;
// 2. 디폴트 생성자 메소드
public CustomerVO() {
super();
}
// 3. 매개변수 생성자 메소드
public CustomerVO(String id, String name, int age, String grade, int point) {
super();
this.id = id;
this.name = name;
this.age = age;
this.grade = grade;
this.point = point;
}
// 4. 개터 셋터 메소드
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
// 5. toString
@Override
public String toString() {
return "CustomerVO [id=" + id + ", name=" + name + ", age=" + age + ", grade=" + grade + ", point=" + point
+ "]";
}
}
🎈순서
1. 인스턴스 함수 선언
2. 디폴트 생성자 메소드
3. 매개변수 생성자 메소드
4. 개터 셋터 메소드
5. toString 오버라이딩
2.
데이터에 접근하는 클래스를 만든다
이름규칙 : 프로젝트명Dao
해당 파일은 db에 접근하는 것이기에 return으로 값을 보내고, 출력하지는 않아야 한다.
package customAPP;
import java.sql.Connection;
import java.sql.PreparedStatement;
//customer테이블에 접근하는 로직을 담당하는 클래스
public class CustomerDao {
// ✨싱글톤 패턴
// static가 있으면 프로그램 실행시 메소드 에리어에 저장되기에 프로그램 종료 전까지 사용 가능하다.
// 즉 static은 단 1회만 실행된다.
private static CustomerDao customerDao;
private CustomerDao() {
}
public static CustomerDao getInstance() {
if (customerDao == null) {
customerDao = new CustomerDao();
}
return customerDao;
}
// 고객정보를 등록한다.
// ✨✨throws Exception는 manger로 돌려보낸다.
public void insertCustomer(CustomerVO customer) throws Exception {
// 1. JDBC드라이브 로딩 - 모듈화로 인해 생략
// 2. Connection 객체 생성
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 3. Connection 객체 생성 - 모듈화로 아래와 같이 변경
conn = DBConn.getConnection();
// 4. SQL문을 전송객체 생성
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO customer ( id, name, age, grade, point ) ");
sql.append("VALUES ( ?, ?, ?, ?, ? ) ");
// ?를 변경해야하는 경우에는 prepareStatement 를 사용하고 쿼리를 수정할 필요없이
// 작동시킬 것이라면 createStatement로 sql전송객체를 만들면 된다.
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, customer.getId());
pstmt.setString(2, customer.getName());
pstmt.setInt(3, customer.getAge());
pstmt.setString(4, customer.getGrade());
pstmt.setInt(5, customer.getPoint());
// 5. sql문 실행(sql문을 서버에 전송)
// executeQuery는 가져올때! executeUpdate는 수정할때 사용
int rowCount = pstmt.executeUpdate();
// rowCount => 는 위의 쿼리로 변경된 데이터 갯수
if (rowCount == 1) {
System.out.println("등록!");
} else {
System.out.println("오류!");
}
} finally { // ✨✨✨catch문의 제외하고 바로 finally문을 쓸수도 있다.
try {
// resource release
if (conn != null)
conn.close();
if (pstmt != null)
pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
// 고객정보를 삭제한다.
public void delectCustomer(CustomerVO customer) throws Exception {
//커넥션 객체 생성
Connection conn = null;
//데이터를 어떻게 담아서 보낼지 정할 부분
PreparedStatement psmt = null;
try {
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
✨
싱글톤은 위에 {}안에 있는 패턴을 가르킨다.
메모리에 인스턴스를 하나만 사용하고 싶다는 의미를 가지고 있다.
즉 static은 단 1회만 실행된다.
그래서 다른 class에서 싱글톤으로 만든 인스턴스를 생성하려할때 오류가 난다.
package customAPP;
public class CustomerManager {
public static void main(String[] args) {
//싱글톤이기때문에 호출이 안됨
CustomerDao dao = new CustomerDao(); //오류
}
}
✨✨
throws Exception는 이걸 호출시킨 manger로 돌려보낸다.
✨✨✨
throws Exception로 호출시킨 곳으로 오류메세지를 보낼꺼라
catch문을 제외해도 되는데, catch문을 제외하고 바로 finally문을 쓸수도 있다.
3.
관리하는 핸들 역할을 하는 부분
이름규칙 : 프로젝트명Manager
출력에 관련한 코드를 작성한다. (전체 보기 등..)
package customAPP;
import java.util.Scanner;
public class CustomerManager {
public static void main(String[] args) {
try {
//고객정보 받기
Scanner scan = new Scanner(System.in);
System.out.print("아이디 : ");
String id = scan.next();
System.out.print("이름 : ");
String name = scan.next();
System.out.print("나이 : ");
int age = scan.nextInt();
System.out.print("등급 : ");
String grade = scan.next();
System.out.print("포인트 : ");
int point = scan.nextInt();
CustomerDao dao = CustomerDao.getInstance();
dao.insertCustomer(new CustomerVO(id, name, age, grade, point));
} catch (Exception e) {
e.printStackTrace();
}
}
}
추가로, static가 있으면 프로그램 실행시 메소드 에리어에 저장되기에 프로그램 종료전까지 사용 가능하다.
만약 회원정보를 가져와서 메모리에 넣어두었다가 사용하려고 할때 가장 좋은 데이터 관리 방법은
arraylist를 사용하는 것이다 인덱스를 통해서 빠르게 접근할 수 있기 때문이다.
질문한거!
회원정보를 저장하기 위해서는 회원정보를 받아서 - 1 / 회원정보를 저장해야하는데 -2
받고! 저장하는 걸 따로따로 모듈화 할 필요가 없다고 한다.
왜냐하면, 받는다는 행위의 목적이 저장하는 것 뿐인 경우에는 굳이 분리할 필요가 없다고 한다.
그런데 만약 받는다는 행위를 재활용 할꺼라면 모듈화하는 게 좋다.
--> 결론 모듈은 생성하는 목적으로 구분한다.
마지막이 약간 쉽지않다........끙😑