JAVA/JAVA개발자 양성과정

[JAVA] 자바 개발자 양성과정 16일차 - Java와 MYSQL연동하기🔧(JDBC Driver, executeQuery, executeUpdate, Statement, PreparedStatement, SELECT, INSERT, DB 연결 모듈화, 모듈 연동)

728x90
반응형

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

받고! 저장하는 걸 따로따로 모듈화 할 필요가 없다고 한다.

왜냐하면, 받는다는 행위의 목적이 저장하는 것 뿐인 경우에는 굳이 분리할 필요가 없다고 한다.

그런데 만약 받는다는 행위를 재활용 할꺼라면 모듈화하는 게 좋다.

 

--> 결론 모듈은 생성하는 목적으로 구분한다.

 

 

마지막이 약간 쉽지않다........끙😑

728x90
반응형