원지의 개발
article thumbnail
728x90

JSP

  • JavaServer Page: HTML 코드에 java코드를 넣어서 동적 웹페이지를 생성하는 웹어플리케이션 도구
  • 사용자가 코드를 작성한 다음 컴파일 과정을 거치지 않고, 서버에서 실행
  • 웹 서버에 의해 자동으로 서블릿으로 변환 된 다음 실행

2022.11.30 - [Server/JSP] - [JSP] JSP(태그), Servlet(서블릿)

 

[JSP] JSP(태그), Servlet(서블릿)

Java servlet - 동적 웹 어플리케이션 컴포넌트 (순수 자바 코드) .java - java.resources에 생성 - 서버에서 실행되는 자바 프로그램 - java thread를 이용하여 동작(각각 처리 가능, a-a방식, b-b방식) - 요청되

j-won950101.tistory.com


Persistence Framework

  • 영속성은 프로그램이 종료되더라도 사라지지 않는 데이터의 특성을 말함
  • JDBC 프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있으며 안정적인 구동을 보장
SQL문을 실행하기 위한 방법
1. MyBatis (Spring에서 사용) - SQL 매핑
2. Hibernate (하이버네이트), JPA - ORM(객체) 매핑

SQL Mapper

  • SQL을 명시하여 필드를 매핑 시킴
  • 직접 데이터베이스를 다룸, 쿼리 직접 작성, 안정성
  • MyBatis 사용

ORM

  • Object Relation Mapping 객체 - 관계 매핑
  • 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결) 해주는 것
  • 객체 지향 프로그래밍은 클래스, 관계형 데이터베이스는 테이블을 사용하므로 ORM을 통해 불일치를 해결
  • Hibernate, JPA 사용

JPA(Java Persistent API)

  • ORM을 사용하기 위한 표준 인터페이스를 모아둔 것으로 JAVA에서 제공하는 API - 실제로 동작하는 것이 아
  • 사용자가 원하는 JAP 구현체(ORM Framework)를 선택해서 사용가능
    (Hibernate, EclipseLink, DataNucleus, OpenJPA, TopLink Essentials 등)
  • 통계나 동적 쿼리 같은 복잡한 쿼리를 처리하는 것이 어려우므로 QueryDSL을 함께 이용

https://gmlwjd9405.github.io/2019/08/04/what-is-jpa.html

 

[JPA] JPA란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

JPA 실습

더보기

Hibernate

  • JPA의 구현체 중 하나
  • 아래 블로그 참고

https://gmlwjd9405.github.io/2018/12/25/difference-jdbc-jpa-mybatis.html

 

[JDBC] JDBC, JPA/Hibernate, Mybatis의 차이 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

https://mangkyu.tistory.com/20

 

[Java] ORM이란? MyBatis와 JPA의 차이, MyBatis보다 JPA를 사용해야 하는 이유

오늘은 개발을 편리하게 해주는 Object Mapping 기술인 MyBatis와 ORM(Object Relational Mappin) 기술인 JPA에 대해 알아보도록 하겠습니다. 1. ORM(Object Relation Mapping)이란? [ ORM(Object Relation Mapping)이란? ] ORM이란

mangkyu.tistory.com


JDBC (ORM 사용X)

https://gmlwjd9405.github.io/2018/12/25/difference-jdbc-jpa-mybatis.html

  • Java Database Connectivity 프로그래밍
  • 자바 프로그램에서 SQL문을 실행하여 데이터를 관리하기 위한  API

JDBC 사용법 (Oracle Database 실습)

    1. 드라이버 로드: Class.forName()
      DriverManager: 로드된 드라이버를 통해서 Connectrion을 활성화해주는 객체
    2. Connection: DB 연결
    3. Statement: SQL 쿼리 실행: SQL을 실행하는 객체
      ResultSet: SQL문 실행 후 데이터를 받는 객체
    4. excute(): 결괏값 처리
    5. close() DB 연결 해제

JDBC 설치

1. Connector 다운로드

  • 커넥터 다운 받는 방법은 多
  • oracle connector - jdbc 검색 - 다운로드 - ojdbc8.jar 다운로드
    jar: 자바 파일의 압축형

2. 라이브러리 추가

3. 드라이버 클래스 (암기x)

  • MySQL: "com.mysql.jdbc.Driver"
  • Oracle: "oracle.jdbc.driver.OracleDriver"

AuthDAO.java

//드라이버 로드
	Class.forName("oracle.jdbc.driver.OracleDriver");

4. URL 패턴 (암기x)

  • MySQL: "jdbc:mysql://호스트이름:포트번호/DB이름"
  • Oracle: "jdbc:oracle:thin:호스트이름:포트번호:DB이름"
    • PDB 경우: "jdbc:orcle:thin:호스트이름:포트번호/XEPDB1"
                         11ver 이상은 : 에서 / 로 바뀜
      CDB(Container Database) 안에 여러 개의 PDB(Pluggable Database) 사용할 수 있음

MainClass.java

//상수 사용시 데이터베이스가 바뀌면 여기만 바뀌면 됨
	public static final String URL = "jdbc:oracle:thin:@localhost:1521:xe";
    //호스트 이름: IP주소 ▶ @localhost
    //포트 번호 ▶ 1521
    //DB 이름: 데이터베이스의 스키마명 ▶ xe
	public static final String UID = "hr";
	public static final String UPW = "hr";

JDBC 실행순서 (Statement)

Connection 객체

  • 데이터베이스와 자바 연결
  • 연결이 끝난 뒤에는 반드시 close() 메서드를 호출하여 Connection 객체가 사용한 시스템 자원을 반환해야 함

Statement = PreparedStatement 객체 (▼설명)

  • Statement와 PreparedStatement 객체는 동일한 기능을 제공하나 업그레이드 된 PreparedStatement 사용하면 됨
  • Connect 객체로부터 Statement를 생성하고 쿼리문 실행

setString (int parameterIndex, String x) 지정된 매개변수를 x값으로 설정  setString, setInt, setDate, setTimestamp 등
▲ sql문의 ?를 설정해주는 작업이라서 select에서 데이터를 가져올 때 필터링으로 사용 가능
executeUpdate() Insert, Update, Delete 쿼리문 실행 데이터를 가져오는 작업, ResultSet객체 반환
executeQuery() Select 쿼리문 실행 실행시키는 작업, int형 반환(성공 0, 실패 1)

ResultSet 객체 - select 에서만 사용

  • 위의 executeQuery() 메서드 안에 있는 객체로 select 쿼리문의 결과를 ResultSet 객체에 담아서 리
next() 다음 값 확인 (하나씩 전진, 후진은 x)
다음 행이 있으면 true를 반환하고 전진
getString() 지정한 컬럼 값을 String으로 읽음
getInt() 지정한 컬럼 값을 int 타입으로 읽음
getDouble() 지정한 컬럼 값을 double 타입으로 읽음

PrepareStatement 실행 순서

  • Statement 객체를 대신하는 PreparedStatement 객체
  • 값을 지정할 때 물음표(?)로 처리하기 때문에 값을 간단히 지정 가능
  • 첫번째 물음표의 인덱스는 1이며, 이후 순서대로 인덱스 값이 1씩 증가

JDBC 실습

insert

package jdbc.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class JDBCInsert {

	public static void main(String[] args) {
		
		//insert
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; //주소, @작성해야함
		String uid = "hr"; //계정 아이디
		String upw = "hr"; //비밀번호
		
		String sql = "insert into auth values( seq_auth.nextval , ?, ?)"; //auth 컬럼 3개
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		// throws exception을 던지니까 try-catch
		try {
			//드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");

			//connection - DB 연결
			conn = DriverManager.getConnection(url, uid, upw);
			
			//statement 객체 - sql문을 실행시키기 위한 query 전송 객체
			pstmt = conn.prepareStatement(sql);
			
			//?값 세팅 - 첫번째부터 1번 순서 (setString, setInt, setDate, setTimestamp)
			pstmt.setString(1, "홍길동"); //1은 물음표를 나타냄, 물음표가 2개 이므로 1,2가 나옴
			pstmt.setString(2, "프로그래머"); //직접 값을 적지 않고 변수화 가능
			
			//sql 실행 (select문은 query 문장으로 실행, i, d, u문은 update 메서드로 실행) - i,d,u는 완전 똑같음 sql문만 바뀜
			int result = pstmt.executeUpdate(); //업데이트문은 정수형 반환, 성공(1), 실패(0) 반환
			// executeUpdate는 정수형 반환
			if(result == 1) {
				System.out.println("성공");
			} else {
				System.out.println("실패");
			}
			
		} catch(Exception e ) {
			e.printStackTrace(); //에러 로그를 봐야 하니까
		} finally {
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
		} //end try ~ catch ~ finally 

	} //end main
}
  • Connection객체 - prepareStatement객체 - setString(index, x) 설정 - executeUpdate() 쿼리문 실행(업데이트)

select

package jdbc.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JDBCSelect {

	public static void main(String[] args) {
		
		//insert
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; //주소, @작성해야함
		String uid = "hr"; //계정 아이디
		String upw = "hr"; //비밀번호
		
		String sql = "select * from auth order by auth_id desc"; //?가 없으니까 아래에서 딱히 할게 없음
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null; //결과 저장 객체, select 결과를 반환받을 객체
		
		try {
			//드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//conn
			conn = DriverManager.getConnection(url, uid, upw);
			//pstmt
			pstmt = conn.prepareStatement(sql);
			//?값에 대한 처리 x
			
			//sql 실행 (select의 실행 - 데이터를 가져오는 작업)
			rs = pstmt.executeQuery();
			//executeQuery는 ResultSet형으로 반환
			//그대로 실행된 결과가 rs에 담김
			
			while (rs.next()) { //다음 row가 있다면 true
				
				//한 행에 대한 처리(getInt, getString, getDouble, getTimestamp, getDate)
				int auth_id = rs.getInt("auth_id");
				String name = rs.getString("name"); //컬럼명
				String job = rs.getString("job");
				
				System.out.println("번호:" + auth_id + ", 이름:" + name + ",직업:" + job);
			
			}
				
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
		} //end try ~ catch ~ finally 

	} //end main
}
  • Connection객체 - prepareStatement객체 - executeQuery() 쿼리문 실행(데이터 가져오기) - next(), get()으로 한 행에 대한 처리

select2 - 조건O

package jdbc.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class JDBCSelect2 {

	public static void main(String[] args) {
		
		/*
		 * 사원수를 입력받습니다.
		 * employees, departments 테이블에서 부서별 사원수가 입력받은 사원수보다 큰 데이터를 select
		 * 출력할 컬럼은 부서명, 사원수, 부서아이디
		 */
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("사원수 입력>");
		String tmp = scan.nextLine();
		int c = Integer.parseInt(tmp);
		
		//변수선언
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; //주소, @작성해야함
		String uid = "hr"; //계정 아이디
		String upw = "hr"; //비밀번호
		
		String sql = "select d.department_name, a.total, d.department_id\r\n"
					+ "from departments d\r\n"
					+ "inner join (select department_id, count(*) as total\r\n"
					+ "            from employees e\r\n"
					+ "            group by department_id) a\r\n"
					+ "on d.department_id = a.department_id\r\n"
					+ "where total > ?";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null; //select결과를 반환받을 객체
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection(url, uid, upw);
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setInt(1, c); //물음표의 내용을 적어줌
			
			//sql
			rs = pstmt.executeQuery();
			
			while(rs.next()) { //한줄이면 한번, 여러줄이면 여러번 실행
				String department_name = rs.getString("department_name");
				int total = rs.getInt("total");
				int department_id = rs.getInt("department_id");
				
				System.out.println("부서명:" + department_name + ", 사원수:" + total + ",부서아이디:" + department_id);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
		} //end try ~ catch ~ finally 
		
	} //end main
}
select count(*) from employees ;

select department_id, count(*) total
from employees e
group by department_id;

select d.department_name, a.total, d.department_id
from departments d
inner join (select department_id, count(*) as total
                from employees e
                group by department_id) a -- null이 안나오면 좋겠어서 inner join
on d.department_id = a.department_id
where total > 1;
  • Connection객체 - prepareStatement객체 - 특정 조건(?물음표에 대한) 설정 가능, set메서드 사용 - executeQuery() 쿼리문 실행(데이터 가져오기) - next(), get()으로 한 행에 대한 처리

update

package jdbc.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;

public class JDBCUpdate {

	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("auth_id 입력>");
		String tmp = scan.nextLine();
		int auth_id = Integer.parseInt(tmp);
		System.out.println("name 입력>");
		String name = scan.nextLine();
		System.out.println("job 입력>");
		String job = scan.nextLine();
		
		//변수선언
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; //주소, @작성해야함
		String uid = "hr"; //계정 아이디
		String upw = "hr"; //비밀번호
		
		//스캐너로 auth_id, name, job을 입력받아서 해당 auth_id의 name, job을 업데이트 하는 구문.
		String sql = "update auth set name = ?, job = ? where auth_id = ?";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		try {
			//드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//connection
			conn = DriverManager.getConnection(url, uid, upw);
			//statement 객체
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, name); //str
			pstmt.setString(2, job); //str
			pstmt.setInt(3, auth_id); //number
			
			//sql 실행
			int result = pstmt.executeUpdate(); // 1 or 0
			
			if(result == 1) {
				System.out.println("성공");
			} else {
				System.out.println("실패");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
				scan.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
		} //end try ~ catch ~ finally 

	} //end main
}
  • 실행 과정은 insert와 같
  • 변경 할 데이터 변수에 담기
  • Connection객체 - prepareStatement객체 - setString(index, x) 설정 - executeUpdate() 쿼리문 실행(업데이트)

JDBC.Model 실습

AuthDAO.java

  • DAO에서는 단순 연결
  • URL 패턴으로 주소 적고, 아이디, 비밀번호 적고 사용
  • 위에서 처럼 MainClass에 상수로 적어주면 AuthDAO.java 에서 MainClass.URL; 이런식으로 불러옴
	//멤버변수
	private String url = MainClass.URL; //주소, @작성해야함
	private String uid = MainClass.UID; //계정 아이디
	private String upw = MainClass.UPW; //비밀번호

삽입 - insertEx()

	//메서드화 - 데이터베이스 작업(insert,select 등)만, 스캐너같은 작업은 main에서
	//성공실패를 받기 위해서 int형 메서드, 매개변수는 MainClass의 스캐너값 받으려고
	public int insertEx(String name, String job) {
		int result = 0;
		
		String sql = "insert into auth values( seq_auth.nextval , ?, ?)"; //auth 컬럼 3개임
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		// throws exception을 던지니까 try-catch
		try {
			//드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");

			//connection
			conn = DriverManager.getConnection(url, uid, upw);
			
			//statement 객체
			pstmt = conn.prepareStatement(sql);
			
			//?값 세팅 - 첫번째부터 1번 순서 (setString, setInt, setDate, setTimestamp)
			pstmt.setString(1, name); //1은 물음표를 나타냄, 물음표가 2개 이므로 1,2가 나옴
			pstmt.setString(2, job); //직접 값을 적지 않고 변수화 가능
			
			//sql 실행 (select문은 query 문장으로 실행, i, d, u문은 update 메서드로 실행) - i,d,u는 완전 똑같음 sql문만 바뀜
			result = pstmt.executeUpdate(); //업데이트문은 정수형 반환, 성공(1), 실패(0) 반환
		}catch(Exception e ) {
			e.printStackTrace(); //에러 로그를 봐야 하니까
		}finally {
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
		}
		return result; //성공하면 sql값 반환, 실패하면 0 반환
	}

검색 - selectEx()

	//조회메서드
	public ArrayList<AuthVO> selectEx() {
		ArrayList<AuthVO> list = new ArrayList<>();
		
		String sql = "select * from auth order by auth_id desc"; //?가 없으니까 아래에서 딱히 할게 없음
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null; //결과 저장 객체, select 결과를 반환받을 객체
		
		try {
			//드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//conn
			conn = DriverManager.getConnection(url, uid, upw);
			//stmt
			pstmt = conn.prepareStatement(sql);
			//?값에 대한 처리 x
			
			//sql 실행 (select의 실행)
			rs = pstmt.executeQuery();
			//executeQuery는 ResultSet형으로 반환
			//그대로 실행된 결과가 rs에 담김
			
			while (rs.next()) { //다음 row가 있다면 true
				
				//한 행에 대한 처리(getInt, getString, getDouble, getTimestamp, getDate)
				int auth_id = rs.getInt("auth_id");
				String name = rs.getString("name"); //컬럼명
				String job = rs.getString("job");
				
				//ORM 작업 = 데이터바인딩
				//vo에 행 데이터 저장
				//vo를 list에 저장
				AuthVO vo = new AuthVO(auth_id, name, job);
				list.add(vo);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			
			try { //객체 계속 쌓여서 close 필수로 해줌
				conn.close();
				pstmt.close();
				rs.close();
			} catch (Exception e2) {
				System.out.println("close 에러");
			}
			
		}
		return list;
	}

AuthVO.java

  • 조회한 데이터를 저장할 클래스
  • 변수는 은닉, 테이블이 가지고 있는 멤버변수를 그대로 사용
  • getter & setter
package jdbc.model;

public class AuthVO {

	//특별한 알고리즘을 가진 클래스가 아니라, 조회한 데이터를 저장할 클래스
	//1. 변수는 은닉하고, 테이블이 가지고 있는 멤버변수를 그대로 사용합니다.
	//2. getter, setter
	
	private int auth_id;
	private String name;
	private String job; //테이블의 컬럼을 그대로 사용
	
	//생성자 - 기본생성자, 매개변수 생성자(모든 멤버변수를 저장하는)
	public AuthVO() { /* ctrl + shift + enter */ }

	public AuthVO(int auth_id, String name, String job) {
		super();
		this.auth_id = auth_id;
		this.name = name;
		this.job = job;
	}

	//toString메서드 오버라이딩
	@Override
	public String toString() {
		return "AuthVO [auth_id=" + auth_id + ", name=" + name + ", job=" + job + "]";
	}
	
	//getter, setter
	public int getAuth_id() {
		return auth_id;
	}

	public void setAuth_id(int auth_id) {
		this.auth_id = auth_id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}
	
}

MainClass.java

package jdbc.model;

import java.util.ArrayList;
import java.util.Scanner;

public class MainClass {

	//상수 사용시 데이터베이스가 바뀌면 여기만 바뀌면 됨
	public static final String URL = "jdbc:oracle:thin:@localhost:1521:xe";
	public static final String UID = "hr";
	public static final String UPW = "hr";
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		//DAO 클래스 선언
		AuthDAO authDAO = new AuthDAO();
		String menu = "";
		
		while(true) {
			try {
				System.out.println("메뉴 [ 1.저장, 2.조회 ] \n>");
				menu = scan.nextLine();
			} catch (Exception e) {
				// TODO: handle exception
			}
				switch (menu) {
				case "1" :
					System.out.print("이름>");
					String name = scan.nextLine();
					System.out.print("직업>");
					String job = scan.nextLine();
					
					//이 아래부터 1끝까지 메서드화 되어 AuthDAO로 들어가야 함
					int result = authDAO.insertEx(name, job);
					if (result == 1) {
						System.out.println("정상 값이 입력되었습니다");
					} else {
						System.out.println("입력 오류 발생");
					}
					break;
				
				case "2":
					ArrayList<AuthVO> list = authDAO.selectEx();
					for(AuthVO vo : list) {
						System.out.println(vo.toString());
					}
					break;
					
				default:
					break;
				} //end switch
		}
	} //end main
}

 

2023.06.20 - [Server/Spring] - [Spring] DAO, VO, DTO

2023.02.02 - [Server/Spring] - [Spring] ??? MVC Controller, MVC 웹서비스 service, service 실습, DAO 구조

 

[Spring] ??? MVC Controller, MVC 웹서비스 service, service 실습, DAO 구조

 

j-won950101.tistory.com

728x90

'Database > Oracle' 카테고리의 다른 글

[Oracle] 데이터베이스 모델링  (0) 2022.11.18
profile

원지의 개발

@원지다

250x250