220510
DB 연결 / 종료
SQL 실행하는 역할
텍스트 쿼리 실행용 ⭐
프로시저 실행용
오라클에 테이블 만들어 놓음
-- 주소록 테이블
select * from tblAddress;
create table tblAddress(
seq number primary key, -- PK
name varchar2(10) not null, -- 이름
age number(3) not null check(age between 0 and 150), -- 나이
gender char(1) not null check(gender in ('m','f')), -- 성별(m,f)
tel varchar2(15) not null, -- 전화번호
address varchar2(300) not null, -- 주소
regdate date default sysdate not null -- 등록일
);
create sequence seqAddress;
ex1) INSERT 실행
1. DB 접속
2. SQL 실행
3. DB 종료
try {
Connection conn = null; -- DB 연결
Statement stat = null; -- SQL 실행
// 1. DB 접속
conn = DBUtil.open();
if (!conn.isClosed()) {
System.out.println("연결 성공");
// 2. SQL 실행
// - 자바는 SQL을 모른다. > SQL을 문자열로 취급한다.(아무 의미없이)
String sql =
"insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, '아무개', 25, 'm', '010-5555-5555','서울시 강남구 대치동 OO빌딩', default)";
// stat > SQL 실행 > 어느 DB + 어떤 계정으로 SQL 실행할지는 모르고 있음
// 쿼리 수행할래?
stat = conn.createStatement();
// 반환값이 없는 쿼리 > 나머지
// - (int) stat.executeUpdate(sql);
// SQL Developer > Ctrl + Enter 동일!
int result = stat.executeUpdate(sql); // result는 '1 행 이(가) 삽입되었습니다.'
if (result == 1) {
System.out.println("등록 성공");
} else {
System.out.println("등록 실패");
}
stat.close();
conn.close();
// 모든 자원은 close! 꼭 닫아야해.
}
// 3. DB 종료
DBUtil.close();
} catch (Exception e) {
System.out.println("Ex03_Statement.m1");
e.printStackTrace();
}
ex2) UPDATE 실행
Connection conn = null;
Statement stat = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "update tblAddress set age = age + 1 where seq = 1";
int result = stat.executeUpdate(sql);
System.out.println(result);
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex03_Statement.m2");
e.printStackTrace();
}
ex3) CREATE 실행
Connection conn = null;
Statement stat = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "create table tblAddress2 ("
+ " seq number primary key, "
+ " name varchar2(10) not null,"
+ " age number(3) not null check (age between 0 and 150),"
+ " gender char(1) not null check(gender in ('m','f')),"
+ " tel varchar2(15) not null,"
+ " address varchar2(300) not null, "
+ " regdate date default sysdate not null "
+ ")";
int result = stat.executeUpdate(sql);
System.out.println(result);
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex03_Statement.m3");
e.printStackTrace();
}
ex4) 사용자 입력 > INSERT 실행
// UI + SQL
// - 사용자 입력 > insert
Connection conn = null;
Statement stat = null;
Scanner scan = new Scanner(System.in);
try {
// 자바 자로형 <- 아무 연관성X -> 오라클 자료형
// - 언어가 다르면 자료형 절대 호환 안된다.
System.out.print("이름: ");
String name = scan.nextLine(); // varchar2
System.out.print("나이: ");
String age = scan.nextLine(); // number
System.out.print("성별(m,f): ");
String gender = scan.nextLine(); // char
System.out.print("전화번호: ");
String tel = scan.nextLine(); // varchar2
System.out.print("주소: ");
String address = scan.nextLine(); // varchar2
conn = DBUtil.open();
stat = conn.createStatement();
String sql = String.format(
"insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, '%s', %s, '%s', '%s', '%s', default)",
name, age, gender, tel, address);
int result = stat.executeUpdate(sql);
System.out.println(result);
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex03_Statement.m4");
e.printStackTrace();
}
ex1) 단일값 반환 - 1행 1열
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "select count(*) as cnt from tblInsa";
// 반환값 X -> executeUpdate(); -> 실행은 되지만 올바른 결과를 얻을 수가 없다.
// 반환값 O -> executeQuery();
// ResultSet == 커서(Cursor) > 커서가 가리키고 있는 레코드의 특정 컬럼값을 가져온다.
// 조회한 결과들을 ResultSet에 rs에 저장
rs = stat.executeQuery(sql);
rs.next(); // 커서를 1줄 전진 > 레코드 위치
// rs.getXXX(); (XXX-> 자료형) 현재 커서가 가르키고 있는 레코드의 특정 컬럼값을 가져와라
int cnt1 = rs.getInt(1); // 컬럼 순서(Index)
int cnt2 = rs.getInt("cnt"); // 컬럼명 ******** 주의!! as 꼭 붙여라
String cnt3 = rs.getString("cnt");
System.out.println(cnt1);
System.out.println(cnt2);
System.out.println(cnt3);
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m1");
e.printStackTrace();
}
ex2) 다중값 반환 - 1행 N열 (레코드 1줄 + 여러개 컬럼)
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "select name, age, tel, address from tblAddress where seq = 5";
rs = stat.executeQuery(sql);
// rs.next()를 통해 다음행을 내려갈 수 있으면 true를 반환하고, 커서를 한칸 내림
// 다음행이 없으면 false를 반환
if (rs.next()) {
System.out.println("이름: " + rs.getString("name"));
System.out.println("나이: " + rs.getString("age"));
System.out.println("전화번호: " + rs.getString("tel"));
System.out.println("주소: " + rs.getString("address"));
} else {
System.out.println("데이터가 없습니다.");
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m2");
e.printStackTrace();
}
ex3) 다중값 반환 - N행 1열 (레코드 N줄 + 컬럼 1개)
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "select name from tblInsa order by name";
// rs가 가리키고 있는거!
// 60명
rs = stat.executeQuery(sql);
rs.next();
rs.next();
rs.next();
// 몇바퀴? > 57바퀴
while (rs.next()) {
System.out.println("이름: " + rs.getString("name"));
}
// System.out.println("이름: " + rs.getString("name")); -> 출력문 : 결과 집합을 모두 소모했음
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m3");
e.printStackTrace();
}
ex4) 다중값 반환 - N행 N열 (레코드 N줄 + 컬럼 N개)
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String buseo = "총무부";
String sql =
"select name, jikwi, city, basicpay from tblInsa where buseo = '" + buseo + "'";
rs = stat.executeQuery(sql);
System.out.println("[이름]\t[직위]\t[지역]\t[급여]");
while (rs.next()) {
// 직원1명
System.out.printf("%s\t%s\t%s\t%,10d원\n", rs.getString("name"),
rs.getString("jikwi"), rs.getString("city"), rs.getInt("basicpay"));
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m4");
e.printStackTrace();
}
ex5) 연습문제
// tblInsa + tblBonus
// 요구사항] 특정 직원에게 보너스를 지급하세요.
// 1. 모든 직원 명단을 출력(직원번호, 이름, 부서, 직위) > m4() 참조
// 2. 사용자 > 직원 선택(직원번호 입력)
// 3. 사용자 > 보너스 급액 입력
// 4. 보너스 지급 > insert tblBonus
// 5. 지급된 내역을 명단 출력(직원번호, 이름, 부서, 직위, 보너스 금액) > m4() 참조
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
// 1.
System.out.println(" [직원명단]");
String sql = "select num, name, buseo, jikwi from tblInsa";
rs = stat.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s, %s, %s, %s\n", rs.getString("num"), rs.getString("name"),
rs.getString("buseo"), rs.getString("jikwi"));
}
rs.close();
// 2.
System.out.print("보너스를 지급할 직원 번호를 선택하세요 : ");
Scanner scan = new Scanner(System.in);
String num = scan.nextLine();
// 3.
System.out.print("보너스를 지급할 금액을 입력하세요 : ");
String money = scan.nextLine();
// 4.
sql = String.format(
"insert into tblBonus (seq, num, bonus)
values(seqBonus.nextVal, %s, %s)", num, money);
int result = stat.executeUpdate(sql);
// 5.
if (result > 0) {
System.out.println("보너스 지급을 완료했습니다.");
System.out.println();
System.out.println("[번호]\t[이름]\t[부서]\t[직위]\t[보너스]");
sql = "select a.num as anum, a.name as aname, a.buseo as abuseo, a.jikwi as ajikwi, b.bonus as bbonus from tblInsa a inner join tblBonus b on a.num = b.num";
rs = stat.executeQuery(sql);
while (rs.next()) {
// as 붙여라!!!!!!
System.out.printf("%s\t%s\t%s\t%s\t%,10d원\n",
rs.getString("anum"),
rs.getString("aname"),
rs.getString("abuseo"),
rs.getString("ajikwi"),
rs.getInt("bbonus"));
}
System.out.println();
System.out.println("프로그램 종료");
}else {
System.out.println("보너스 지급을 실패했습니다.");
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m5");
e.printStackTrace();
}
ex6) sql 주의점 - AS
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
// 회원명 + 대여한 비디오명
String sql =
"select m.name as mname, v.name as vname
from tblVideo v
inner join tblRent r
on v.seq = r.video
inner join tblMember m
on m.seq = r.member";
rs = stat.executeQuery(sql);
while (rs.next()) {
// 값 나옴
// System.out.println(rs.getString(1));
// System.out.println(rs.getString(2));
// 값 안 나옴
// System.out.println(rs.getString("m.name"));
// System.out.println(rs.getString("v.name"));
// System.out.println(rs.getString("name"));
// System.out.println(rs.getString("name_1")); -> X
// System.out.println(rs.getString("name")); m.name -> 김유신
// System.out.println(rs.getString("name")); m.name -> 김유신
// AS 꼭 붙여주자!
System.out.println(rs.getString("mname"));
System.out.println(rs.getString("vname"));
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
ex7) 요구사항] 영업부 직원수와 영업부 직원 명단을 출력하시오.
1. select count() as cnt from tblInsa where buseo = '영업부'
2. select from tblInsa where buseo = '영업부'
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
stat = conn.createStatement();
String sql = "";
// 1번 요구사항
sql = "select count(*) as cnt from tblInsa where buseo = '영업부'";
rs = stat.executeQuery(sql);
// 레코드가 1개라고 확실할때 if문으로
if (rs.next()) {
System.out.println("직원수 : " + rs.getString("cnt"));
}
rs.close();
// 2번 요구사항 + 1번 요구사항도 가능
sql = "select * from tblInsa where buseo = '영업부'";
rs = stat.executeQuery(sql);
int n = 0;
// 레코드가 여러개라고 while문
while (rs.next()) {
System.out.println(rs.getString("name"));
n++; // 1번 요구사항
}
System.out.println("직원수: " + n);
// 자원 해제 코드, Clean-up code > 꼭 안 닫아도 자동으로 닫아주지만, 직접 해주는게 좋다.
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex04_select.m8");
e.printStackTrace();
}
정적 쿼리
(매개 변수가 없는 쿼리)동적 쿼리
(매개 변수가 있는 쿼리)매개변수값으로 부적절한 값이 있어도 자동으로 이스케이프(escape)를 시켜줌
★★★ // insert > 사용자 입력
String name = "하하하";
String age = "20";
String gender = "m";
String tel = "010-1211-1111";
String address = "서울시 동대문구 이문's동";
// address = address.replace("'", "''");
Connection conn = null;
Statement stat = null;
PreparedStatement pstat = null;
try {
conn = DBUtil.open();
// Statement
String sql = String.format(
"insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, '%s', %s, '%s', '%s', '%s', default)",
name, age, gender, tel, address);
stat = conn.createStatement(); // A.
System.out.println(sql);
int result = stat.executeUpdate(sql); // A. 실행 시 SQL 대입
System.out.println(result);
// PreparedStatement
// ? : 오라클 매개변수
sql = String.format(
"insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, ?, ?, ?, ?, ?, default)",
name, age, gender, tel, address);
pstat = conn.prepareStatement(sql); // B. 미리 SQL 대입
// 인자값에 대한 처리 추가 진행(***)
pstat.setString(1, name); // 1번째 물음표에 name을 넣어라.
pstat.setString(2, age);
pstat.setString(3, gender);
pstat.setString(4, tel);
pstat.setString(5, address);
int result = pstat.executeUpdate(); // B.
System.out.println(result);
} catch (Exception e) {
System.out.println("Ex05_PreparedStatement.m1");
e.printStackTrace();
}
Connection conn = null;
Statement stat = null;
PreparedStatement pstat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
// 정적 쿼리
String sql = "select name from tblInsa where num = 1001";
stat = conn.createStatement();
rs = stat.executeQuery(sql);
if (rs.next()) {
System.out.println(rs.getString("name"));
}
rs.close();
stat.close();
// 동적 쿼리
sql = "select name from tblInsa where num = ?";
pstat = conn.prepareStatement(sql);
// java.sql.SQLException: 인덱스에서 누락된 IN 또는 OUT 매개변수:: 1
pstat.setString(1, "1001");
// pstat.setInt(1, 1001);
rs = pstat.executeQuery();
if (rs.next()) {
System.out.println(rs.getString("name"));
}
rs.close();
pstat.close();
// 인자없는 쿼리 > pstat
// ? 전달하는 과정 생략하면 됨.
sql = "select count(*) as cnt from tblInsa";
pstat = conn.prepareStatement(sql);
rs = pstat.executeQuery();
if(rs.next()) {
System.out.println(rs.getString("cnt"));
}
rs.close();
pstat.close();
conn.close();
} catch (Exception e) {
System.out.println("Ex05_PreparedStatement.m2");
e.printStackTrace();
}
SQL문을 사용하여
저장 프로시저를 호출
할 수 있도록 한다.
ex1) 인자값(X), 반환값(X)
create or replace procedure procM1
is
begin
insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, '홍길동', 20, 'm', '010-1234-6789', '서울시 강남구 역삼동 한독빌딩', default);
end;
Connection conn = null;
ResultSet rs = null;
CallableStatement stat = null;
try {
conn = DBUtil.open();
// 프로시저 호출구문
String sql = "{ call procM1 }";
stat = conn.prepareCall(sql); // 매개변수 처리 능력 보유 > ? 지원
int result = stat.executeUpdate();
System.out.println(result);
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
Java 컴파일 시 정상 작동시 result 콘솔에 1이 출력된다. Oracle DB 확인 결과 insert 된 결과를 볼 수 있다.
ex2) 인자값(O), 반환값(X)
create or replace procedure procM2(
pname tblAddress.name%type,
page tblAddress.age%type,
pgender tblAddress.gender%type,
ptel tblAddress.tel%type,
paddress tblAddress.address%type
)
is
begin
insert into tblAddress (seq, name, age, gender, tel, address, regdate)
values (seqAddress.nextVal, pname, page, pgender, ptel, paddress, default);
end;
/
-- 검증
begin
procM2('이름',20,'m','010-1234-1234','주소');
end;
/
-- 검증 완료
select * from tblAddress order by seq desc;
Connection conn = null;
CallableStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
// begin
// procM2('이름',20,'m','010-1234-1234','주소');
// end;
// String sql = "{ call procM2('상수', 22, 'm', '010-2222-2222','주소') }";
String sql = "{ call procM2(?, ?, ?, ?, ?) }";
stat = conn.prepareCall(sql);
// 인덱스에서 누락된 IN 또는 OUT 매개변수:: 1
// 인덱스에서 누락된 IN 또는 OUT 매개변수:: 2
stat.setString(1, "홍길동");
stat.setString(2, "25");
stat.setString(3, "m");
stat.setString(4, "010-3333-3333");
stat.setString(5, "서울시");
int result = stat.executeUpdate();
System.out.println(result);
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
ex3) 인자값(X), 반환값(O)
create or replace procedure procM3(
pcount out number
)
is
begin
select count(*) into pcount from tblAddress;
end procM3;
/
declare
vcount number;
begin
procM3(vcount);
dbms_output.put_line(vcount);
end;
/
Connection conn = null;
CallableStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
String sql = "{ call procM3(?) }";
stat = conn.prepareCall(sql);
// in 매개변수
// stat.setString(1,값)
// out 매개변수
stat.registerOutParameter(1, OracleTypes.NUMBER);
// PLSQL 문에서 인출을 수행할 수 없습니다.: next
// rs = stat.executeQuery();
// System.out.println(rs.next());
stat.executeQuery(); // rs(X)
int count = stat.getInt(1); // Out Parameter 가져오는 역할
System.out.println(count);
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
ex4) 연습문제
create or replace procedure procM4(
pnum in number,
pname out varchar2,
pbuseo out varchar2,
pjikwi out varchar2,
pcity out varchar2
)
is
begin
select name, buseo, jikwi, city into pname, pbuseo, pjikwi, pcity from tblInsa where num = pnum;
end;
/
declare
vname tblInsa.name%type;
vbuseo tblInsa.buseo%type;
vjikwi tblInsa.jikwi%type;
vcity tblInsa.city%type;
begin
procM4(1001,vname,vbuseo,vjikwi,vcity);
dbms_output.put_line(vname);
dbms_output.put_line(vbuseo);
dbms_output.put_line(vjikwi);
dbms_output.put_line(vcity);
end;
/
// 문제. 직원 번호를 입력하면, 이름, 부서, 직위, 지역을 반환 + 출력
// procM4
// - in > 직원 번호
// - out > 이름
// - out > 부서
// - out > 직위
// - out > 지역
Connection conn = null;
CallableStatement stat = null;
ResultSet rs = null;
System.out.print("직원번호를 입력하세요: ");
Scanner scan = new Scanner(System.in);
String num = scan.nextLine();
try {
conn = DBUtil.open();
String sql = "{ call procM4(?, ?, ?, ?, ?) }";
stat = conn.prepareCall(sql);
stat.setString(1, num);
stat.registerOutParameter(2, OracleTypes.VARCHAR);
stat.registerOutParameter(3, OracleTypes.VARCHAR);
stat.registerOutParameter(4, OracleTypes.VARCHAR);
stat.registerOutParameter(5, OracleTypes.VARCHAR);
stat.executeQuery();
System.out.println("이름 : " + stat.getString(2));
System.out.println("부서 : " + stat.getString(3));
System.out.println("직위 : " + stat.getString(4));
System.out.println("지역 : " + stat.getString(5));
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
ex5)
create or replace procedure procM5(
pbuseo in varchar2,
pcursor out sys_refcursor
)
is
begin
open pcursor
for
select name, jikwi, basicpay
from tblInsa
where buseo = pbuseo;
end procM5;
/
declare
pcursor sys_refcursor;
vname tblInsa.name%type;
vjikwi tblInsa.jikwi%type;
vbasicpay tblInsa.basicpay%type;
begin
procM5('개발부', pcursor);
loop
fetch pcursor into vname, vjikwi, vbasicpay;
exit when pcursor%notfound;
dbms_output.put_line(vname || ', ' || vjikwi || ', ' || vbasicpay);
end loop;
end;
/
Connection conn = null;
CallableStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
String sql = "{call procM5(?,?)}";
stat = conn.prepareCall(sql);
stat.setString(1, "개발부");
stat.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
stat.executeQuery();
// 오라클 커서 == 자바 ResultSet ********
rs = (ResultSet) stat.getObject(2);
while (rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getString("jikwi"));
System.out.println(rs.getString("basicpay"));
System.out.println();
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
ex6)
create or replace procedure procM6(
pbuseo in varchar2,
pcursor out sys_refcursor
)
is
begin
-- 1. 부서명 > 직원 번호
-- 2. 직원번호 > 보너스 지급 내역
open pcursor for
select name, bonus from tblInsa i
left outer join tblBonus b
on i.num = b.num
where buseo = pbuseo;
end procM6;
/
declare
vname varchar2(30);
vbonus number;
vcursor sys_refcursor;
begin
procM6('기획부', vcursor);
loop
fetch vcursor into vname, vbonus;
exit when vcursor%notfound;
dbms_output.put_line(vname || ' > ' || vbonus);
end loop;
end;
/
Connection conn = null;
CallableStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtil.open();
// 부서명 입력 > 부서의 직원의 보너스 직급 내역 출력
Scanner scan = new Scanner(System.in);
System.out.print("부서명: ");
String buseo = scan.nextLine();
String sql = "{ call procM6(?,?) }";
stat = conn.prepareCall(sql);
stat.setString(1, buseo);
stat.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
stat.executeQuery();
rs = (ResultSet) stat.getObject(2);
System.out.println("== 보너스 지급 내역 ==");
System.out.println("[직원명]\t[지급액]");
while (rs.next()) {
System.out.printf("%s\t%,10d원\n", rs.getString("name"),
// the column value; if the value is SQL NULL, thevalue returned is 0
rs.getInt("bonus"));
}
rs.close();
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
JDBC 중요! 반복해서 보기
감사합니다 큰 도움되었습니다