Java 웹 개발

21.10.04 - 웹 개발 입문 36일차

개발이란 2021. 10. 4. 23:09

데이터베이스 - 인덱스(Index)

 INDEX(인덱스, 색인)
  = 데이터베이스 테이블의 컬럼에 설치하는 도구
  = 검색속도 향상
  = 유니크(Unique) 또는 기본키(Primary key)에는 인덱스가 자동 생성된다.
 


일반 인덱스 : create index 이름 on 테이블(컬럼)

create index name_index on product(name);

 

유니크 인덱스 : create unique index 이름 on 테이블(컬럼)

create unique index no_index on product(no);

 

인덱스 제거

drop index name_index;

 

index의 불균형을 재조정하는 명령

alter index name_index rebuild;

 

 

JDBC - 개요 및 접속

 

 

오라클 데이터베이스로의 접속(로그인) 시도

자바에서는 데이터베이스가 꼭 오라클이 아니어도 상관이 없다.
= 자바에서 오라클 정보를 기본적으로 알아야 하나?
= 오라클에 관련된 정보를 자바에게 알려줄 필요가 있다.
= 프로젝트 우클릭 -> [build path] -> [configure build path] -> [libraries] -> [add JARs] -> ojdbc8.jar 추가

 

package connect;

public class Test01 {

	public static void main(String[] args) throws ClassNotFoundException {

		Class.forName("oracle.jdbc.OracleDriver");
		System.out.println("오라클 드라이버 설치 완료");

	}
}

 

 

로그인 수행 - 연결(접속) 생성 - Connection 생성
= 필요한 정보 : 전송위치정보, 아이디, 비밀번호

package connect;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Test02 {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//드라이버 설치 코드
		Class.forName("oracle.jdbc.OracleDriver");
		System.out.println("오라클 드라이버 설치 완료!");

		//Connection con = DriverManager.getConnection(위치정보, 아이디, 비밀번호);
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");
		System.out.println("로그인 성공!");

		//명령 준비 및 전송 , 실행 및 결과 확인을 이곳에서 수행

		//접속 종료
		con.close();
	}
}

 

 

(ex) database에 insert 명령을 전송하여 데이터를 추가하도록 지시

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Test01 {

	public static void main(String[] args) throws SQLException, ClassNotFoundException {
		Class.forName("oracle.jdbc.OracleDriver");
		
		Connection con = DriverManager.getConnection(
				"jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");
		
		//1. 명령문 준비
		String sql = "insert into menu(menu_name, menu_price, menu_type) "
				+ "values('갈치조림', 7000, '식사')";
		
		//2. 전송객체 대여
		PreparedStatement ps = con.prepareStatement(sql);
		
		//3. 실행
		ps.execute();
		
		con.close();
		System.out.println("실행 완료!");

	}

}

 

 

Q : 변수에 저장된 값이 menu 테이블에 insert 될 수 있도록 JDBC 구문을 작성해보세요.

String menuName="오므라이스";
String menuType ="식사";
int menuPrice = 8500;

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Test02 {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		String menuName="오므라이스";
		String menuType ="식사";
		int menuPrice = 8500;
		
		Class.forName("oracle.jdbc.OracleDriver");
		
		Connection con = DriverManager.getConnection(
				"jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");
		
		String sql = "insert into menu(menu_name, menu_price, menu_type) "
				+ "values('"+menuName+"', '"+menuPrice+"', '"+menuType+"')";
		
		PreparedStatement ps = con.prepareStatement(sql);
		
		ps.execute();
		
		con.close();
		System.out.println("실행 완료!");

	}

}

 

 

최종 insert 형태
직접 구문을 더하여 만드는 방식의 문제점

1. 구문 형태를 보기 어렵다(문자열, 숫자, 날짜에 따른 표시 방식이 다르다)
2. 구문에서 사용하는 글자들을 값으로 추가할 수 없다. 혼선이 발생한다.(ex : KH's스페셜)
3. SQL Injection 공격이 발생할 수 있다.(입력값에 구문을 넣어서 정보를 탈취하는 기법)
=> 해결책 : 전송객체(PreparedStatement)에게 데이터 설정을 위임
=> 문제점 : 구문의 완성된 형태를 알 수 없다.

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Test03 {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {

		String menuName= "팥빙수";
		int menuPrice = 5000;
		String menuType = "디저트";
		
		Class.forName("oracle.jdbc.OracleDriver");
		Connection con = DriverManager.getConnection(
				"jdbc:oracle:thin:@localhost:1521:xe","계정아이디", "계정비밀번호");
		
		//동적 SQL 생성 방식에서는 위치 홀더(?)를 사용하여 데이터가 들어갈 자리를 표시
		//-> PreparedStatement를 이용해서 위치 홀더에 어떤 형태의 데이터를 채울 것인지 명을 내린다
		String sql = "insert into menu(menu_name, menu_price, menut_type) values(?, ?, ?)";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setString(1, menuName);//1번 위치홀더(?)에 menuName을 String 형태로 채울거에요!
		ps.setInt(2, menuPrice);//2번 위치홀더(?)에 menuPrice를 int 형태로 채울거에요!
		ps.setString(3, menuType);//3번 위치홀더(?)에 menuType을 String 형태로 채울거에요!
		
		ps.execute();//시킨대로 가서 실행하세요!
		
		con.close();
	
	}
}

 

 

 

Q. 사용자에게 필요한 정보를 입력받아서 exam 테이블에 데이터를 등록하는 프로그램을 구현
문제 없이 등록이 되었다면 마지막에 "등록 성공!" 이라는 메세지 출력

 

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class Test04_1 {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		Scanner sc = new Scanner(System.in);
		System.out.print("이름 : ");
		String student = sc.next();
		System.out.print("과목 : ");
		String subject = sc.next();
		System.out.print("유형 : ");
		String type = sc.next();
		System.out.print("점수 : ");
		int score = sc.nextInt();
		sc.close();

		Class.forName("oracle.jdbc.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");

//		String sql = "insert into exam values(exam_seq.nextval, '또가스', 'SQL활용', '서술형', 70)";
		String sql = "insert into exam values(exam_seq.nextval, ?, ?, ?, ?)";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setString(1, student);
		ps.setString(2, subject);
		ps.setString(3, type);
		ps.setInt(4, score);
		ps.execute();

		con.close();
		System.out.println("등록이 완료되었습니다");
	}
}

 

 

 

Q. 사용자에게 필요한 정보를 입력받아서 product 테이블에 데이터를 등록하는 프로그램을 구현
문제 없이 등록이 되었다면 마지막에 "등록 성공!" 이라는 메세지 출력

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class Test05_3 {
	public static void main(String[] args) throws Exception {
		// 준비 : 등록에 필요한 데이터
		Scanner sc = new Scanner(System.in);
		System.out.print("번호 : ");
		int no = sc.nextInt();
		System.out.print("이름 : ");
		String name = sc.next();
		System.out.print("종류 : ");
		String type = sc.next();
		System.out.print("가격 : ");
		int price = sc.nextInt();
		System.out.print("생산날짜 : ");
		String made = sc.next();
		System.out.print("유통기한 : ");
		String expire = sc.next();

		sc.close();

		// 처리 : 데이터베이스 등록
		Class.forName("oracle.jdbc.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");

		String sql = "insert into product values(" + "?,"
				+ "?, ?, ?, to_date(?, 'YYYY-MM-DD'), to_date(?, 'YYYY-MM-DD')" + ")";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setInt(1, no);
		ps.setString(2, name);
		ps.setString(3, type);
		ps.setInt(4, price);
		ps.setString(5, made);
		ps.setString(6, expire);
		ps.execute();

		con.close();

		// 완료 : 메세지 출력
		System.out.println("등록 완료!");
	}
}

 

 

Q. 사용자에게 필요한 정보를 입력받아서 회원가입을 구현(member 테이블 사용)
문제 없이 등록이 되었다면 마지막에 "회원가입 성공!" 이라는 메세지 출력
문제가 생겼다면 "회원 가입 과정에서 오류가 발생했습니다" 라는 메세지 출력

package jdbc.insert;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Scanner;

public class Test06_3 {
	public static void main(String[] args) {
		try {
			//입력
			Scanner sc = new Scanner(System.in);
			System.out.print("아이디 : ");
			String memberId = sc.next();
			System.out.print("비밀번호 : ");
			String memberPw = sc.next();
			System.out.print("닉네임 : ");
			String memberNick = sc.next();
			System.out.print("생년월일 : ");
			String memberBirth = sc.next();
			System.out.print("이메일 : ");
			String memberEmail = sc.next();
			System.out.print("연락처 : ");
			String memberPhone = sc.next();
			sc.close();

			//처리
			Class.forName("oracle.jdbc.OracleDriver");
			Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");

			//#1. 형식을 지정할 경우
			String sql1 = "insert into member("
										+ "member_id, "
										+ "member_pw, "
										+ "member_nick, "
										+ "member_birth, "
										+ "member_email, "
										+ "member_phone"
								+ ") values(?, ?, ?, to_date(?, 'YYYY-MM-DD'), ?, ?)";

			//#2. 형식을 지정하지 않을 경우
			String sql2 = "insert into member values(?, ?, ?, to_date(?, 'YYYY-MM-DD'), ?, ?, sysdate, 100, '준회원')";

			PreparedStatement ps = con.prepareStatement(sql2);
			ps.setString(1, memberId);
			ps.setString(2, memberPw);
			ps.setString(3, memberNick);
			ps.setString(4, memberBirth);
			ps.setString(5, memberEmail);
			ps.setString(6, memberPhone);
			ps.execute();

			con.close();

			//출력
			System.out.println("회원 가입이 완료되었습니다");
		}
		catch(SQLIntegrityConstraintViolationException e) {
			System.out.println("아이디 또는 닉네임이 사용중입니다");
		}
		catch(Exception e) {
			System.out.println("회원 가입 과정에서 오류가 발생했습니다");
		}
	}
}

 

 

Q. 과제

## jdbc.delete.Test01
사용자에게 상품번호(no)를 입력받아서 product 테이블에서 해당하는 상품번호 데이터를 삭제

package jdbc.delete;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;

public class Test01 {
	public static void main(String[] args) throws Exception {

		Scanner sc = new Scanner(System.in);
		System.out.print("상품번호를 입력하세요 : ");
		int no = sc.nextInt();
		sc.close();

		Class.forName("oracle.jdbc.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");

		String sql = "delete from product where no = ?";

		PreparedStatement ps = con.prepareStatement(sql);
		ps.setInt(1, no);

//		ps.execute();

		int count = ps.executeUpdate();

		if (count > 0) {
			System.out.println(count + "개의 상품이 삭제 되었습니다.");
		} else {
			System.out.println("상품이 존재하지 않습니다.");
		}

		ps.close();
		con.close();

	}
}

 


## jdbc.delete.Test02
사용자에게 아이디(memberId)와 비밀번호(memberPw)를 입력받아 일치하는 회원 정보를 삭제

package jdbc.delete;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;

public class Test02 {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		System.out.print("아이디를 입력하세요 : ");
		String memberId = sc.next();
		System.out.print("비밀번호를 입력하세요 : ");
		String memberPw = sc.next();
		sc.close();

		Class.forName("oracle.jdbc.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "계정아이디", "계정비밀번호");

		String sql = "delete from member where  member_id = ? and member_pw = ?";

		PreparedStatement ps = con.prepareStatement(sql);
		ps.setString(1, memberId);
		ps.setString(2, memberPw);

		int count = ps.executeUpdate();

		if (count > 0) {
			System.out.println("아이디가 삭제 되었습니다.");
		} else {
			System.out.println("잘못 입력했습니다.");
		}

		ps.close();
		con.close();

	}
}