반응형
어제 하던 클래스 내용 채워 넣기
*PreparedStatement==============
-
Singleton Pattern
-
CLOB (Character Large Object): 4GB의 문자를 저장할 수 있음 -> 내용은 내일
-
ResultSetMetaData
<PreparedStatement 사용시 like 주의사항>
-
like쓸 때 : 값에 대한 일부분만 알아도 검색 (한글자: _ , 여러글자 : %, 주로 %를 사용)
-
like 사용시 %와 bind변수가 함께 사용되는 bind변수를 인식하지 못하는 문제가 발생
-
%를 일반문자열로 만들어서 ||(or)로 붙여줌 (Framework쓸 때도 같음)
-
예) like %?% (x) -> like '%'||?||'%'
*Design Pattern
-
이미 만들어진 프로젝트를 분석하여 공통코드를 몇 가지 얻어낸 것
-
대표) nvc, Singleton
-
GoF의 Design Pattern이 유명
*Singleton Pattern==========================
-
실행중인 JVM에서 단 하나의 객체를 만들어 사용하는 pattern
-
장점 : 속도가 빠르다
-
장점 : 메모리를 적게 사용한다- 객체가 하나만 생성되기 때문에 (효율적)
-
단점 : 객체가 소멸되면 그 이후에 해당 기능을 사용할 수 없다. (해결하는 코드가 등장)
작성법)
1. 객체 생성을 클래스 내부에서만 할 수 있도록 한다.
public class Test{
Test t;
//생성자를 private으로 하면 안에서만 만들 수 있음
private Test(){
}
2. 클래스 외부에서 객체를 얻어갈 수 있는 method작성 // 객체를 얻어 간다 : Instance
//생성자가 private이라서 부를 수가 없음.
//객체화 없이 method를 부르고 싶다면 : static을 붙이면 됨
public static Test getInstance(){ //calendar class 만들 때 써봤던 것
Test t = new Test(); //private이기 때문에 내 클래스 안에서 부를 수 있음
return t;
}
//밖에서 부를 땐 이렇게 부름
Test t = Test.getInstance();
//위는 부를때마다 객체가 생성되어 나가기 때문에 Singleton이 아님
//Singleton으로 만들려면 | 객체를 하나만 생성하려면 : if문을 넣어줌
//Instance변수의 속성: 자동초기화
public static Test getInstance(){
If(t==null){
Test t = new Test();
}
return t;
}
//에러가 남
//이유 : Static영역은 Instance보다 먼저 메모리에 올라가서 에러
//따라서 객체를 static으로 접근지정을 바꿔줘야 함
public class Test{
static Test t;
private test() {
}
public static Test getInstance(){
If(t==null){
Test t = new Test();
}
return t;
}
아래는 업무코드가 들어가면 됨
Test t = Test.getInstance();
DB업무/Framework는 속도가 느려서 Singleton으로 만들게 됨
더 나중엔 prototype(객체가 매번 생성되는 것)으로 만들게 됨
*ResultSetMetaData==============
-
모든 데이터베이스가 Dictionary를 제공하지 않음
-
실행되는 쿼리문을 사용하여 Dictionary가 없어도 테이블의 컬럼정보를 얻는 일.(DB의 정보를 끌어옴)
-
컬럼정보 : 컬럼의 수, 컬럼명, data type, 크기 등 (제약사항은 알 수 없음)
사용법)
rs = pstmt.executeQuery(); 커서의 제어권을 얻기 때문에 이후 작업 수행 가능
String sql = "select 컬럼명1, 컬럼명2, 컬럼명3 "; //DB쪽은 거의 대부분 1부터 시작
1. ResultSet으로부터 RSMD(ResultSetMetaData)를 얻음
ResultSetMetaData rsmd = rs.getMetaData();
2. 컬럼의 수
int <- rsmd.getColumnCount();
3. 컬럼명
String <- rsmd.getColumnName(int column//인덱스);
rsmd.getColumnLabel(int column);
두 개 다 같은 결과 나옴
4. 컬럼의 데이터형명
String rsmd.getColumnTypeName(인덱스);
5. 컬럼의 크기
int rsmd.getPrecision();
*CLOB사용(Character Larger Object)==============
-
오라클에만 있음 (다른DB에는 존재하지 않음)
-
Oracle에서 제공하는 문자열을 저장하기 위한 데이터 형
-
char: (고정길이) 데이터 적게 입력되더라도 처음의 크기를 유지하는 데이터형, 2000자
-
varchar2 : (가변길이) 데이터 적게 입력되면 처음 크기를 무시하고 줄어드는 데이터형, 4000자
-
4GByte의 문자열을 저장할 수 있다.(크기 저장된 Text의 크기)
-
rs.getString("컬럼명")으로 얻을 수 없다. (local에서는 됨)
-
별도의 Stream을 구성하여 데이터를 얻는다.
사용법)
1. clob얻기
Clob clob = rs.getClob("컬럼명");
2. Stream연결
Readline은 BufferedReader
BufferedReader br = new BufferedReader
(clob.getCharacterStream()); //반환형 Reader이기 때문에 getCharacterStream으로
3. 반복하여 줄 단위로 읽어들임
String str = "";
while((str=br.readLine())!=null){
str //줄 단위로 읽어들일 수 있음
}
package day0108;
import java.io.BufferedReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import kr.co.sist.connection.GetConnection;
public class UseClob {
public UseClob()throws SQLException, IOException{
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
BufferedReader br = null;
try {
//1.
//2.
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String id = "scott";
String pass = "tiger";
con = GetConnection.getInstance().getConn(url,id, pass);
//3.
//테이블이 존재하지 않아서 테이블을 생성하고 다시 보는걸로
String selectClob =
"select subject, news, reporter, to_char(input_date, 'yyyy-mm-dd') input_date from test_clob";
pstmt = con.prepareStatement(selectClob);
//4.
rs = pstmt.executeQuery();
System.out.printf("번호\t기자\t작성일\t기사\n");
System.out.println("----------------------------------------------");
int cnt = 0;
String reporter="", input_date=""/*, news=""*/;
StringBuilder news = null;
String temp = "";
while(rs.next()) {
reporter = rs.getString("reporter");
input_date = rs.getString("input_date");
// news = rs.getString("news");//clob는 local상에서는 getString으로 얻어짐
news = new StringBuilder();
//CLOB데이터를 얻기 위한 스트림 연결
br = new BufferedReader(rs.getClob("news").getCharacterStream());
while((temp=br.readLine())!=null) {
news.append(temp).append("\n"); //readLine은 줄 바뀌면 띄어지기 때문에 \n을 붙여줌
}
System.out.printf("%d\t%s\t%s\t%s\n", cnt++, reporter,input_date,news.toString());
}//end while
//5.
}finally {
//6.
if(br!=null) {br.close();}//end if
if(rs!=null) {rs.close();}//end if
if(pstmt!=null) {pstmt.close();}//end if
if(con!=null) {con.close();}//end if
}//end finally
}//UseClob
public static void main(String[] args) {
try {
new UseClob();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}//end catch
}//main
}//class
반응형