자바 프로그래밍/Java
-
Eclipse에서 Properties 파일 작업하기2012.05.11
-
예전 작업 소스들2009.11.11
-
[SCJP 030-055] 덤프 드래그 앤 드롭 문제 풀이2009.10.23
-
[Java강의노트] Step by step으로 본 JDBC를 이용한 프로그래밍2009.09.18
Eclipse에서 Properties 파일 작업하기
Properties 파일을 자바에서 사용할 수 있도록 하기 위해 UCS-2로 변환하여야 한다. 이때 한글과 같은 비 ASCII 코드의 경우 Lation1 인코딩으로 변환하여 저장하여야 하는데, 저장된 내용을 편집할 경우 여간 불편한게 아니다.
Properties Editor는 일본 프로그래머에 의해 만들어졌으며, Eclipse indigo의 경우 Help-Install New Software… 메뉴에 http://propedit.sourceforge.jp/eclipse/updates/ 경로를 추가하여 PropertiesEditor를 선택하여 설치하면 된다.
ResourceBundle 사용하기
ResourceBundle 사용하기
클래스 상속관계 java.lang.Object - java.util.ResourceBundle
ResourceBundle은 다음과 같은 특징을 같습니다.
- 다른 국가의 언어에 맞추어 로컬라이징을 할 수 있습니다.
- 복수의 로케일을 동시에 처리할 수 있습니다.
- 새로운 로케일의 추가가 쉽습니다.
ResourceBundle을 사용하기 위해서는 다음과 같이 getBundle() 메서드를 사용하여 ResourceBundle 클래스를 로드합니다.
ResourceBundle myResource = ResourceBundle("MyResource", 로케일);
로케일의 생략시 현재 사용하는 로케일이 지정됩니다. 한글은 'ko_KR'로 로케일이 지정됩니다. 'MyResource'의 이름은 베이스 네임으로 로케일에 따라 자동으로 베이스 네임과 함께 로케일 이름이 붙은 이름을 먼저 찾게 됩니다. 예를 들면 로케일이 'ko_KR'인 경우 'MyResource_ko_KR'로 확장되며, 이 파일이 존재하지 않는 경우, 'MyResource_ko.properties'를 찾고 이 파일 존재하지 않으면 최종적으로 'MyResource_ko_KR.properties'이라는 리소스 파일을 현재 클래스가 위치한 패키지 내에서 찾게 됩니다. 만일 이런 이름의 파일이 없을 경우는 'MyResource.properties' 파일을 찾게 됩니다.
package net.jeongsam.extra; import java.util.Iterator; import java.util.ResourceBundle; import java.util.Set; public class ResourceLocaleEx01 { public static void main(String[] args) { // net.jeongsam.extra 패키지에서 MyResource_ko_KR.properties 파일을 탐색한다. ResourceBundle myResource = ResourceBundle.getBundle("net.jeongsam.extra.MyResource"); Setkeys = myResource.keySet(); Iterator itKeys = keys.iterator(); while (itKeys.hasNext()) { String key = itKeys.next(); System.out.println(key + "=" + myResource.getString(key)); } } }
예전 작업 소스들
package net.jeongsam.prjpkg; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ContentDAO { private Connection conn = null; private PreparedStatement pstmt = null; private ResultSet rs = null; private String sql = null; private ContentDAO() { conn = ConnectionManager.getConnection(); } public static ContentDAO getInstance() { return new ContentDAO(); } /** * 글을 데이터베이스에 삽입한다. 이때 태그는 별도의 테이블에 목록을 만들어 저장한다. * 태그의 경우 리스트를 만들어 리스트의 목록을 차례대로 태그가 저장된 테이블의 데이터와 비교하여 * 기존 태그의 카운트를 증가하거나 새로운 태그를 저장한다. * ※ 현재 구현만 해두었고 코드를 다듬어서 최적화시킬 필요가 있다. * @param content */ public void insertArticle(ContentDomain content) { sql = "INSERT INTO cont (num, title, content, tag_list) "; sql += "VALUES (seq_cont.NEXTVAL, ?, ?, ?)"; try { pstmt = conn.prepareStatement(sql); pstmt.setString(1, content.getTitle()); pstmt.setString(2, content.getContent()); pstmt.setString(3, content.getTags()); pstmt.executeUpdate(); IteratortagList = content.toTagList().iterator(); while (tagList.hasNext()) { String tag = tagList.next(); sql = "SELECT tag_name FROM tag_list "; sql += "WHERE tag_name LIKE ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, "%" + tag + "%"); if (pstmt.executeUpdate() > 0) { sql = "UPDATE tag_list SET tag_count = tag_count + 1 "; sql += "WHERE tag_name = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, tag); pstmt.executeUpdate(); } else { sql = "INSERT INTO tag_list (num, tag_name, tag_count) "; sql += "VALUES (seq_tag_list.NEXTVAL, ?, ?)"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, tag); pstmt.setString(2, "1"); pstmt.executeUpdate(); } } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public ContentDomain getArticle(int num) { // 데이터베이스에서 글 읽어오기 return new ContentDomain(); } public List getTagList() { // 데이터베이스에서 태그 목록 리턴 return new ArrayList (); } public static void main(String[] args) { ContentDomain article = new ContentDomain(); ContentDAO cdao = getInstance(); Iterator itrArticle = null; article.setTitle("두번째 글"); article.setContent("테스트 글입니다.\n테스트 글입니다."); article.setTags("태그, test, 두번째글, second"); itrArticle = article.toTagList().iterator(); while (itrArticle.hasNext()) System.out.println(itrArticle.next()); cdao.insertArticle(article); } }
/** * 문자열 컬렉션 타입 지정 * 태그 배열을 파라메터로 받기 위해 선언 */ CREATE OR REPLACE TYPE type_tag_list IS TABLE OF VARCHAR2(100) NOT NULL; /** * 태그 배열을 파라메터로 받아서 태그 카운트를 갱신하거나 * 신규 태그를 등록한다. */ CREATE OR REPLACE PROCEDURE insert_tag (tags IN type_tag_list) IS idx INTEGER; BEGIN idx := tags.FIRST; -- 컬렉션 인텍스 시작값으로 초기화 LOOP EXIT WHEN idx IS NULL; -- 컬렉션 데이터가 없으면 LOOP 빠져나감 UPDATE tag_list -- 태그가 존재하면 태그 카운트 증가 SET tag_count = tag_count + 1 WHERE tag_name = tags(idx); IF SQL%NOTFOUND THEN -- UPDATE의 WHERE 조건 만족하는 row가 없을 때 INSERT INTO tag_list -- 태그 추가 (num, tag_name, tag_count) VALUES (seq_tag_list.NEXTVAL, tags(idx), '1'); END IF; idx := tags.NEXT(idx); END LOOP; END;
package net.jeongsam.prjpkg; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import oracle.sql.ARRAY; import oracle.sql.ArrayDescriptor; public class ContentDAO { private ContentDAO() { } public static ContentDAO getInstance() { return new ContentDAO(); } /** * 글을 데이터베이스에 삽입한다. 이때 태그는 별도의 테이블에 목록을 만들어 저장한다. * 태그의 경우 리스트를 만들어 리스트의 목록을 차례대로 태그가 저장된 테이블의 데이터와 * 비교하여 기존 태그의 카운트를 증가하거나 새로운 태그를 저장한다. * @param content 글정보를 담은 JavaBean * @throws SQLException SQL Exception 처리 */ public void insertArticle(ContentDomain content) throws SQLException { Connection conn = null; PreparedStatement pstmt = null; CallableStatement cstmt = null; String query = null; String qproc = null; query = "INSERT INTO cont (num, title, content, tag_list) "; query += "VALUES (seq_cont.NEXTVAL, ?, ?, ?)"; qproc = "{CALL INSERT_TAG(:TAGS)}"; try { conn = ConnectionManager.getConnection(); // 글을 추가한다. pstmt = conn.prepareStatement(query); pstmt.setString(1, content.getTitle()); pstmt.setString(2, content.getContent()); pstmt.setString(3, content.getTags()); pstmt.executeUpdate(); // 태그 목록을 갱신, 추가하기 위해 Oracle Procedure 호출 cstmt = conn.prepareCall(qproc); ArrayDescriptor desc1 = ArrayDescriptor.createDescriptor("TYPE_TAG_LIST",conn); ARRAY input = new ARRAY(desc1, conn, content.toTagList().toArray()); cstmt.setArray(1, input); cstmt.executeUpdate(); } finally { if (pstmt != null) pstmt.close(); if (cstmt != null) cstmt.close(); if (conn != null) conn.close(); } } public ContentDomain getArticle(int num) { // 데이터베이스에서 글 읽어오기 return new ContentDomain(); } public List<;string> getTagList() { // 데이터베이스에서 태그 목록 리턴 return new ArrayList <string>(); } /** * 클래스 테스트 코드 * insertArticel() 메서드 테스트 * @param args 미사용 파라메터 */ public static void main(String[] args) { ContentDomain article = new ContentDomain(); ContentDAO cdao = getInstance(); Iterator <string> itrArticle = null; article.setTitle("일곱번째 글"); article.setContent("테스트 글입니다.\n테스트 글입니다."); article.setTags("일곱번째 글, 태그, 7th, example"); itrArticle = article.toTagList().iterator(); while (itrArticle.hasNext()) System.out.println(itrArticle.next()); try { cdao.insertArticle(article); } catch (SQLException e) { e.printStackTrace(); } } }
[SCJP 030-055] 덤프 드래그 앤 드롭 문제 풀이
030-055 덤프 풀이
덤프 중 드래그 앤 드롭 문제 오류가 많아서 해답을 올려봅니다. 본 해답은 오류가 있을 수 있으며 직접 정오를 확인하시어 참고하시고 오류로 인한 불이익은 응시자 본인에게 있음을 밝혀둡니다. 문제 전체를 블로그로 게시하는 것은 무리가 있을 것 같아서 PPT 첨부 파일 올립니다.
Question 2.
Question 16.
일단 Q2.부터 Q118.까지 올립니다.
[Java강의노트] Step by step으로 본 JDBC를 이용한 프로그래밍
처리 순서로 본 코딩
package net.jeongsam.testsuit; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC 이용 코드 v1 * @author 정샘 * */ public class JdbcCodeEx01 { public void delete(long articleNo) throws ClassNotFoundException, SQLException { // Driver 클래스 로딩 Class.forName("com.mysql.jdbc.Driver"); // Connection 인스턴스 생성 - DBMS에 연결 String url = "jdbc:mysql://127.0.0.1:3306/example"; // 사용할 Database 지정 String user = "root"; // 로그인 사용자 String password = "1234"; // 암호 Connection conn = DriverManager.getConnection(url, user, password); // 실행할 SQL문 작성 : 삭제할 번호는 매개변수 articleNo에서 가져옴. String sql = "DELETE FROM board_data WHERE no = " + articleNo; // Statement 인스턴스 생성 : Connection 객체에서 만들어 짐. Statement stmt = conn.createStatement(); // SQL문 실행 : Statement 객체를 이용 // INSERT, DELETE, UPDATE문은 executeUpdate() 사용 // SELECT문은 executeQuery() 사용 stmt.executeUpdate(sql); // Statement 객체를 close 시켜서 자원 반납 (운영체제에게 JVM이 반납) stmt.close(); // Statement 객체를 가비지 컬렉션 대상으로 만듬 (JVM에게 자원 반납) stmt = null; // Connection 객체를 close 시켜서 자원 반납 (운영체제에게 JVM이 반납) // DBMS에 연결하기 위해 운영체제는 Socket 등 자원을 사용. JVM에게 대여. conn.close(); // Connection 객체를 가비지 컬렉션 대상으로 만듬 (JVM에게 자원 반납) conn = null; /* 작업 종료 */ } }
중복코드를 정리한 코딩
package net.jeongsam.begin; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class JdbcCodeEx02 { public void delete(long articleNo) throws ClassNotFoundException, SQLException { /* 메서드내에서 사용할 지역변수의 선언 */ Connection conn = null; Statement stmt = null; // 실행할 SQL문 작성 : 삭제할 번호는 매개변수 articleNo에서 가져옴. String sql = "DELETE FROM board_data WHERE no = " + articleNo; try { conn = getConnection(); // Statement 인스턴스 생성 : Connection 객체에서 만들어 짐. stmt = conn.createStatement(); // SQL문 실행 : Statement 객체를 이용 // INSERT, DELETE, UPDATE문은 executeUpdate() 사용 // SELECT문은 executeQuery() 사용 stmt.executeUpdate(sql); } finally { if (stmt != null) { // Statement 객체가 존재할 경우만 close()가 의미있음 // Statement 객체를 close 시켜서 자원 반납 (운영체제에게 JVM이 반납) stmt.close(); // Statement 객체를 가비지 컬렉션 대상으로 만듬 (JVM에게 자원 반납) stmt = null; } if (conn != null) { // Connection 객체가 존재할 경우만 close()가 의미있음 // Connection 객체를 close 시켜서 자원 반납 (운영체제에게 JVM이 반납) // DBMS에 연결하기 위해 운영체제는 Socket 등 자원을 사용. JVM에게 대여. conn.close(); // Connection 객체를 가비지 컬렉션 대상으로 만듬 (JVM에게 자원 반납) conn = null; } } /* 작업 종료 */ } /** * Connection 인스턴스 생성(DB 연결) 부분은 모든 메서드에서 공통으로 사용하므로 * 중복 코드를 별도의 메서드로 분리합니다. * @return Connection 인스턴스를 리턴 * @throws ClassNotFoundException JDBC 드라이버 로딩 오류 * @throws SQLException DB 연결 오류 */ private Connection getConnection() throws ClassNotFoundException, SQLException { String url = "jdbc:mysql://127.0.0.1:3306/example"; // 사용할 Database 지정 String user = "root"; // 로그인 사용자 String password = "1234"; // 암호 // Driver 클래스 로딩 Class.forName("com.mysql.jdbc.Driver"); // Connection 인스턴스 생성 - DBMS에 연결 return DriverManager.getConnection(url, user, password); } }
Properties 클래스를 이용한 getConnection() 재 작성
/** * Connection 인스턴스 생성(DB 연결) 부분은 모든 메서드에서 공통으로 사용하므로 * 중복 코드를 별도의 메서드로 분리합니다. * @return Connection 인스턴스를 리턴 * @throws ClassNotFoundException JDBC 드라이버 로딩 오류 * @throws SQLException DB 연결 오류 * @throws IOException 프로퍼티스 정보 저장 파일 로딩 오류 */ private Connection getConnection() throws ClassNotFoundException, SQLException, IOException { String url = "jdbc:mysql://127.0.0.1:3306/example"; // 사용할 Database 지정 BufferedReader reader = null; Properties prop = new Properties(); // Driver 클래스 로딩 Class.forName("com.mysql.jdbc.Driver"); // Connection 인스턴스 생성 - DBMS에 연결 // mysecret.txt 파일에 다음과 같은 형식으로 저장합니다. // user=root // password=1234 reader = new BufferedReader(new FileReader("C:\\mysecret.txt")); prop.load(reader); return DriverManager.getConnection(url, prop); }