2012년 8월 29일 수요일

내부클래스와 익명클래스


익명 클래스의 용도는 문법적으로 봤을 때 어렵지는 않습니다만.. (쉽게 말해서 클래스 안에 클래스를 다시 선언하는 방식) 문제는 그 사용법을 정확한 포인트에 넣어주는 것이 상당히 어려운 문제입니다.

 익명클래스를 선언하는 경우에 얻을 수 있는 최대의 장점은 객체가 필요한 데이터를 매번 전달받는 방식이 아니라.. 기생하고 있는 클래스에서 바깥쪽의 객체가 가지는 데이터를 그대로 사용할 수 있다는 점이 최대의 장점입니다.


public class OuterA {

        private String name;
       
        private  class InnerA{
               public void display(){
                       System.out.println(name);
               }
        }
       
       
        public InnerA getInstance(){
              
               return new InnerA();
              
        }
       
       
        public static void main(String[] args) {
              
               OuterA outer = new OuterA();
              
               System.out.println(outer.getInstance());
               System.out.println(outer.getInstance());
               System.out.println(outer.getInstance());
              
              
        }
}
예를 들어 위와 같은 경우에는 외부에서 직접적으로 InnerA클래스의 객체를 생성할 수 없도록 설계할 수 있습니다. 게다가 더 강력한 점은 모든 InnerA클래스의 객체가  OuterA객체의 name값을 자동적으로 참조하도록 설계할 수 있다는 사실 입니다.

이런 방식을 이용하면 객체들이 같이 공유해야 하는 데이터를 처리하는 하는 데에 좀 더 편리해 질 수 있습니다.

inner클래스를 사용하게 되면 누릴 수 있는 최대의 장점은 역시나 자바 언어의 가장 문제점인 메소드의 파라미터와 리턴타입의 종속적인 문제를 해결하는데에도 도움이 될 수 있습니다.

예를 들어 다음과 같은 인터페이스를 생각해 봅니다.

public interface Connector {
       
        public void execute()throws RuntimeException;

}

인터페이스의 가장 큰 문제점은 추상 메소드 자체가 상당히 고정적이라는 겁니다. 즉 어떤 클래스에서 구현하게 되면 파라미터나 리턴타입을 처리할 수 없게 되는 문제를 가집니다. 익명 클래스를 이용하게 되면 이러한 단점을 커버할 수 있습니다.

public class Job {

        public void doJob(String webURL)throws Exception{
              
               final URL url = new URL(webURL);
              
               final InputStream in = url.openStream();
              
               final OutputStream out = new FileOutputStream("");
              
               new Connector(){

                       @Override
                       public void execute() throws RuntimeException {
                             
                              try {
                                      in.read();
                                      out.write(11);                              
                              } catch (IOException e) {
                                      // TODO Auto-generated catch block
                                      e.printStackTrace();
                              }
                             
                       }
                      
               }.execute();
              
               out.close();
               in.close();
              
              
              
        }
}
위의 코드를 보면 익명 클래스를 이용해서 파라미터의 전달 없이 필요한 모든 자원을 메소드 내에서 조달하는 것을 볼 수 있습니다. 이 작업을 별도의 객체로 만들면 상당히 복잡하지만 익명 클래스에서는 final 키워드를 조합해서 사용하는 방식으로 동작하면 되기 때문에 별도의 제약이 없이 사용할 수 있습니다.


제가 간단하게 예를 들어 설명했지만, 익명 클래스나 내부 클래스의 경우에는 실제 코드를 작성할 때 쉽게 나오는 개념은 아닙니다. 현실적으로는 안드로이드의 예제들을 보면 제한된 상속내에서 익명 클래스를 이용하는 것을 많이 볼 수 있는데, 이러한 것은 기존의 설계가 인터페이스 기반으로 튼튼하게 설계된 경우에 빛을 볼 수 있습니다.

..역시 설명이 너무 어렵네요..^^;;;;

2012년 8월 19일 일요일

상속과 조합에 대한 단상



public interface DeviceRole {

 public void execute();

}





---------------------------------------------------------------------------
4가지의 기능들

public class CreateRole implements DeviceRole {

 @Override
 public void execute() {

  System.out.println("You Can Create.........");
 }

}


public class ReadRole implements DeviceRole {

 @Override
 public void execute() {

  System.out.println("You Can Read.....");
 }

}



public class UpdateRole implements DeviceRole {

 @Override
 public void execute() {

  System.out.println("You can Update...");
 }

}




public class DeleteRole implements DeviceRole {

 @Override
 public void execute() {

  System.out.println("You Can Delete");
 }

}
--------------------------------------------------------------------

4가지의 기능들을 조합해서 사용할 수 있는 사용자 객체

상속으로 한다면 기능의 경우에 수에 맞게 객체를 생성해야만 하지만, 인터페이스와 조합의 경우에는
그럴 필요가 없다.


import java.util.ArrayList;
import java.util.List;


public class User {

 private List<DeviceRole> roleList;


 public User(){

  roleList = new ArrayList<DeviceRole>();
 }


 public List<DeviceRole> getRoleList() {
  return roleList;
 }


 public void setRoleList(List<DeviceRole> roleList) {
  this.roleList = roleList;
 }




}

2011년 9월 22일 목요일

바닷가풍경

살다보면 가끔은 '그동안 내가 어떻게 살았던거지?' 라는 생각이 들때가 있다. 

참 별거 아닌 일에 끙끙거리며 살고 있구나... 

2011년 8월 10일 수요일

네이트온이 해킹당했다고해서...


아.. 네이트온이 해킹당했다..

왠지 S자 들어가는 기업과 별로 안 친한 관계로.. (사실 대인 관계의 폭이 무척이나 경색된 관계로 인해)

별로 하지도 않는 네이트의 비밀 번호를 변경하러 갔다..

그런데...













젠장.. 원래 비밀 번호를 기억 못했다..
... 30분 동안 삽질하다가 포기..ㅠㅠ



뭐야..이거 한편으로는 내 비밀번호를 해커가 알아도 쓸모가 없다는 안심!
근데..진짜 내 비밀번호는 뭘까?

2011년 6월 23일 목요일

게시판용 SQL

create table tbl_bbs (seqno number,
title varchar2(500) not null,
content varchar2(2000) not null,
readcnt number default 0,
writer varchar2(50) not null,
regdate date default sysdate,
updatedate date default sysdate
);

alter table tbl_bbs add constraint pk_bbs primary key (seqno);

create sequence seq_bbs;

insert into tbl_bbs(seqno, title, content,writer) values (seq_bbs.nextval, 'title......'||seq_bbs.currval,'contents....'||seq_bbs.currval, 'user00');

create table tbl_user (userid varchar2(50), userpw varchar2(50), username varchar2(100));

alter table tbl_user add constraint pk_user primary key (userid);

insert into tbl_user (userid, userpw, username) values ('user00','user00','Hong Gil Dong');
insert into tbl_user (userid, userpw, username) values ('user01','user01','Gun wo chi');

insert into tbl_user (userid, userpw, username) values ('user02','user02','Sim Chung');
insert into tbl_user (userid, userpw, username) values ('user03','user03','Houng Bu');

insert into tbl_bbs(seqno, title, content,writer)
(select seq_bbs.nextval, 'title......'||seq_bbs.currval,'contents....'||seq_bbs.currval, 'user0'||MOD(seq_bbs.currval,4) from tbl_bbs);

create table tbl_bbs_reply
(bbsno number ,
replydate date default sysdate,
replyer varchar2(50) not null,
reply varchar2(1000)
);


select round(dbms_random.value(0,3)) from dual;

insert into tbl_bbs_reply (bbsno, replyer, reply)
values ( round(dbms_random.value(0,seq_bbs.currval)), 'user0'||round(dbms_random.value(0,3)), 'reply.......' );

insert into tbl_bbs_reply (bbsno, replyer, reply)
(select round(dbms_random.value(0,seq_bbs.currval)), 'user0'||round(dbms_random.value(0,3)), 'reply.......' from tbl_bbs_reply );



select /*+INDEX_DESC(tbl_bbs pk_bbs)*/ seqno,title, content, regdate
from tbl_bbs
where rownum < 20

2011년 6월 21일 화요일

네이버 새로운 지도서비스 마커추가하기 예제


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<html >
 <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
<title>OpenAPI Map Test - 마커, InfoWindow 테스트</title>
<!-- prevent IE6 flickering -->
<script type="text/javascript">
try {document.execCommand('BackgroundImageCache', false, true);} catch(e) {}
</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">

var tList;

jQuery(document).ready(
function () {
loadTerminatorLocations();
loadMap();
}
);

function loadTerminatorLocations(){
jQuery.ajax({
    type: 'GET',
    url: 'http://localhost:8080/satellite/pos/all',
    dataType: 'json',
    success: function(data)  {
    tList = data.terminatorGeoList;
    },
    data: {},
    async: false
});
}

function loadMap(){
var oCenterPoint = new nhn.api.map.LatLng(37.5010226, 127.0396037);
nhn.api.map.setDefaultPoint('LatLng');
oMap = new nhn.api.map.Map('testMap', {
point : oCenterPoint,
zoom : 10, // - 초기 줌 레벨은 10으로 둔다.
enableWheelZoom : false,
enableDragPan : true,
enableDblClickZoom : false,
mapMode : 0,
activateTrafficMap : false,
activateBicycleMap : false,
minMaxLevel : [ 5, 12 ],
size : new nhn.api.map.Size(500, 400)
});
var mapZoom = new nhn.api.map.ZoomControl(); // - 줌 컨트롤 선
mapZoom.setPosition({left:80, bottom:40}); // - 줌 컨트롤 위치 지
oMap.addControl(mapZoom); // - 줌 컨트롤 추가.
var markerCount = 0;
var oSize = new nhn.api.map.Size(28, 37);
var oOffset = new nhn.api.map.Size(14, 37);
var oIcon = new nhn.api.map.Icon('terminator_cyborg.gif', oSize, oOffset);
var mapInfoTestWindow = new nhn.api.map.InfoWindow(); // - info window 생
mapInfoTestWindow.setVisible(false); // - infowindow 표시 여부 지정.
oMap.addOverlay(mapInfoTestWindow); // - 지도에 추가.

var oLabel = new nhn.api.map.MarkerLabel(); // - 마커 라벨 선언.
oMap.addOverlay(oLabel); // - 마커 라벨 지도에 추가. 기본은 라벨이 보이지 않는 상태로 추가됨.

mapInfoTestWindow.attach('changeVisible', function(oCustomEvent) {
if (oCustomEvent.visible) {
oLabel.setVisible(false);
}
});


  oMap.attach('mouseenter', function(oCustomEvent) {
var oTarget = oCustomEvent.target;
// 마커위에 마우스 올라간거
if (oTarget instanceof nhn.api.map.Marker) {
var oMarker = oTarget;
oLabel.setVisible(true, oMarker); // - 특정 마커를 지정하여 해당 마커의 title을 보여준다.
}
});

oMap.attach('mouseleave', function(oCustomEvent) {
var oTarget = oCustomEvent.target;
// 마커위에서 마우스 나간거
if (oTarget instanceof nhn.api.map.Marker) {
oLabel.setVisible(false);
}
});

  jQuery(tList).each(
function(idx){
var oMarker1 = new nhn.api.map.Marker(oIcon,  { title : '터미네이터  : ' + this.tcode});
oMarker1.setPoint(new nhn.api.map.LatLng(tList[idx].latitude, tList[idx].longitude));
jQuery(oMap).click( function(oEvent){
alert('마커 ' + oEvent.target.getTitle() + '를 클릭했습니다');
});

oMap.addOverlay(oMarker1);

  }
); 

 
  oMap.attach('click', function(oEvent) {
     
    mapInfoTestWindow.setPoint(oEvent.target.getPoint());
    mapInfoTestWindow.setContent('<DIV style="border-top:1px solid; border-bottom:2px groove black; border-left:1px solid; border-right:2px groove black;margin-bottom:1px;color:black;background-color:white; width:auto; height:auto;">'+
  '<span style="color: #000000 !important;display: inline-block;font-size: 12px !important;font-weight: bold !important;letter-spacing: -1px !important;white-space: nowrap !important; padding: 2px 2px 2px 2px !important">'
  ''+oEvent.target.getTitle()+' <br /> <span></div>');
    mapInfoTestWindow.setVisible(true);
  });



}



</script>
<script type="text/javascript" src="http://openapi.map.naver.com/openapi/naverMap.naver?ver=2.0&key=4e4cc2effff6e97f9c04f5dbad16f0eb"></script>
 <body>
 <div id = "testMap" style="border:1px solid #000; width:500px; height:400px; margin:20px;"></div>

</body>

</html>


2011년 6월 16일 목요일

PL/SQL가벼운 예제

CREATE OR REPLACE PROCEDURE THINKER.p_emp(empno in number)
 IS
BEGIN
 NULL;
END p_emp;


-------------------------------------------------------------

CREATE OR REPLACE PROCEDURE THINKER.p_emp(empno in number)
 IS
BEGIN
 DELETE TBL_EMP WHERE employee_id = empno;
END p_emp;

-------------------------------------------------------------

CREATE OR REPLACE PROCEDURE THINKER.p_log(v_param IN number)
 IS
BEGIN
 INSERT INTO tbl_log(param) VALUES (v_param);

END p_log;

-------------------------------------------------------------

CREATE OR REPLACE PROCEDURE THINKER.p_emp(empno in number)
 IS
BEGIN
 p_log(empno);
 DELETE TBL_EMP WHERE employee_id = empno;
END p_emp;



-------------------------------------------------------------









CREATE OR REPLACE PROCEDURE THINKER.p_emp2(empno IN tbl_emp.employee_id%type)
 IS
BEGIN
 NULL;

END p_emp2;

-------------------------------------------------------------


CREATE OR REPLACE PROCEDURE THINKER.p_emp2(empno IN tbl_emp.employee_id%type)
 IS
BEGIN
 IF TRUE then
   NULL;

 END IF;

END p_emp2;


-------------------------------------------------------------


CREATE OR REPLACE PROCEDURE THINKER.p_emp2(empno IN tbl_emp.employee_id%type)
 IS
  v_job tbl_emp.job_id%TYPE;
BEGIN

 DBMS_OUTPUT.put_line('TARGET employee_id : '||empno);


 IF TRUE then
 
   NULL;

 END IF;

END p_emp2;



-------------------------------------------------------------



CREATE OR REPLACE PROCEDURE THINKER.p_emp2(empno IN tbl_emp.employee_id%type)
 IS
  v_job tbl_emp.job_id%TYPE;
BEGIN

 SELECT job_id INTO v_job FROM TBL_EMP WHERE employee_id = empno;

 DBMS_OUTPUT.put_line('TARGET employee_id : '||empno);


 IF TRUE then
 
   NULL;

 END IF;

END p_emp2;


-------------------------------------------------------------



CREATE OR REPLACE PROCEDURE THINKER.p_emp2(empno IN tbl_emp.employee_id%type)
 IS
  v_job tbl_emp.job_id%TYPE;
BEGIN

 SELECT job_id INTO v_job FROM TBL_EMP WHERE employee_id = empno;

 DBMS_OUTPUT.put_line('TARGET employee_id : '||empno);

 IF v_job = 'IT_PROG' then

  DBMS_OUTPUT.put_line('UPDATE employee_id : '||empno);
  UPDATE TBL_EMP SET salary = salary * 2 WHERE job_id = v_job;

 END IF;

END p_emp2;

-------------------------------------------------------------


CREATE OR REPLACE PROCEDURE THINKER.p_emp3(cnt in number)
 IS
  v_cnt NUMBER := 0;
BEGIN
 FOR v_cnt IN 1.. cnt LOOP

  DBMS_OUTPUT.put_line(v_cnt);

 END LOOP;

END p_emp3;

--------------------------------------------------------------


CREATE OR REPLACE PROCEDURE THINKER.p_emp4
 IS
 CURSOR emp_cursor IS
 SELECT employee_id, first_name ||' '|| last_name, salary FROM TBL_EMP;
 
BEGIN

 OPEN emp_cursor ;


 CLOSE emp_cursor;
 

END p_emp4;










CREATE OR REPLACE PROCEDURE THINKER.p_emp4
 IS
 v_id tbl_emp.EMPLOYEE_ID%TYPE;
 v_name VARCHAR2(200);
 v_sal number;

 CURSOR emp_cursor IS
 SELECT employee_id, first_name ||' '|| last_name, salary FROM TBL_EMP;
 
BEGIN

 OPEN emp_cursor ;

 LOOP
   FETCH emp_cursor INTO v_id, v_name, v_sal;
 
   DBMS_OUTPUT.put_line(v_id||' '||v_name);
 
   EXIT WHEN emp_cursor%NOTFOUND;

 END LOOP;


 CLOSE emp_cursor;
 

END p_emp4;

-------------------------------------------------------------

CREATE OR REPLACE PROCEDURE THINKER.p_emp5(empno in number)
 IS
  v_name VARCHAR2(200);
  v_job VARCHAR2(30);
BEGIN

 SELECT first_name||''||last_name, job_id INTO v_name, v_job  FROM TBL_EMP WHERE employee_id = empno;

 DBMS_OUTPUT.put_line(v_name||'- '|| v_job);

EXCEPTION
 WHEN NO_DATA_FOUND THEN
  DBMS_OUTPUT.put_line('NO DATA FOUND');
  p_log2(empno);  


END p_emp5;



CREATE OR REPLACE PROCEDURE THINKER.p_emp5(empno in number)
 IS
  v_name VARCHAR2(200);
  v_job VARCHAR2(30);
BEGIN

 SELECT first_name||''||last_name, job_id INTO v_name, v_job  FROM TBL_EMP WHERE employee_id = empno;

 DBMS_OUTPUT.put_line(v_name||'- '|| v_job);

 UPDATE TBL_EMP SET salary = salary + 100;

EXCEPTION
 WHEN NO_DATA_FOUND THEN
  DBMS_OUTPUT.put_line('NO DATA FOUND');


END p_emp5;

2011년 6월 15일 수요일

스프링..트랜잭션 어노테이션 분산 DB 처리

<resource>
<data-source>
<database>
<vendor>oracle</vendor>
<export-name>datasource1</export-name>
<data-source-class-name>oracle.jdbc.pool.OracleConnectionPoolDataSource</data-source-class-name>
<data-source-type>ConnectionPoolDataSource</data-source-type>
<database-name></database-name>
<data-source-name>oracle.jdbc.pool.OracleConnectionPoolDataSource</data-source-name>
<port-number></port-number>
<server-name></server-name>
<user></user>
<password></password>
<driver-type>thin</driver-type>
<connection-pool>
<pooling>
<min>20</min>
<max>30</max>
<step>10</step>
<period>3600000</period>
</pooling>
<wait-free-connection>
<enable-wait>true</enable-wait>
</wait-free-connection>
</connection-pool>
</database>
<database>
<vendor>oracle</vendor>
<export-name>datasource3</export-name>
<data-source-class-name>oracle.jdbc.pool.OracleConnectionPoolDataSource</data-source-class-name>
<data-source-type>ConnectionPoolDataSource</data-source-type>
<database-name></database-name>
<data-source-name>oracle.jdbc.pool.OracleConnectionPoolDataSource</data-source-name>
<port-number></port-number>
<server-name></server-name>
<user></user>
<password></password>
<driver-type>thin</driver-type>
<connection-pool>
<pooling>
<min>5</min>
<max>10</max>
<step>10</step>
<period>3600000</period>
</pooling>
<wait-free-connection>
<enable-wait>true</enable-wait>
</wait-free-connection>
</connection-pool>
</database>
</data-source>
</resource>

설정후 was jndi
resource>
<data-source>
<database>
<vendor>oracle</vendor>
<export-name>datasource1</export-name>
<data-source-class-name>oracle.jdbc.xa.client.OracleXADataSource</data-source-class-name>
<data-source-type>XADataSource</data-source-type>
<database-name>db명</database-name>
<data-source-name>oracle.jdbc.xa.client.OracleXADataSource</data-source-name>
<port-number>port</port-number>
<server-name>ip</server-name>
<user></user>
<password></password>
<driver-type>thin</driver-type>
<connection-pool>
<pooling>
<min>20</min>
<max>30</max>
<step>10</step>
<period>3600000</period>
</pooling>
<wait-free-connection>
<enable-wait>true</enable-wait>
</wait-free-connection>
</connection-pool>
</database>
<database>
<vendor>oracle</vendor>
<export-name>datasource3</export-name>
<data-source-class-name>oracle.jdbc.xa.client.OracleXADataSource</data-source-class-name>
<data-source-type>XADataSource</data-source-type>
<database-name>db명</database-name>
<data-source-name>oracle.jdbc.xa.client.OracleXADataSource</data-source-name>
<port-number>port</port-number>
<server-name>ip</server-name>
<user></user>
<password></password>
<driver-type>thin</driver-type>
<connection-pool>
<pooling>
<min>5</min>
<max>10</max>
<step>10</step>
<period>3600000</period>
</pooling>
<wait-free-connection>
<enable-wait>true</enable-wait>
</wait-free-connection>
</connection-pool>
</database>
</data-source>

그리고 spring applicationContext.xml 설정입니다.
이부분이 변경 정 설정이구요 ㅎ보라색 부분을 빨간색 부분으로 수정하였어요

<jee:jndi-lookup id="dataSource-totd" jndi-name="jdbc/datasource1" resource-ref="true" />
<jee:jndi-lookup id="dataSource-hris" jndi-name="jdbc/datasource3" resource-ref="true" />
<jee:jndi-lookup id="dataSource-another" jndi-name="jdbc/datasource1" resource-ref="true" />
<!-- dataSource-totd datasource의 transaction 처리를 위한 transactionmanager설정 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource-totd" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager_hris" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource-hris" />
<tx:annotation-driven transaction-manager="transactionManager_hris"/>


<bean id="sqlMapClient-totd"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:sqlMapConfig.xml</value>
</property>
<property name="useTransactionAwareDataSource">
<value>true</value>
</property>
<property name="dataSource">
<ref bean="dataSource-totd" />
</property>
</bean>
<bean id="sqlMapClient-hris"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:sqlMapConfig.xml</value>
</property>
<property name="useTransactionAwareDataSource">
<value>true</value>
</property>
<property name="dataSource">
<ref bean="dataSource-hris" />
</property>
</bean>
<bean id="sqlMapClient-another"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:sqlMapConfig.xml</value>
</property>
<property name="useTransactionAwareDataSource">
<value>true</value>
</property>
<property name="dataSource">
<ref bean="dataSource-another" />
</property>
</bean>

변경후
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager"/>


이렇게 JtaTransactionManager 를 쓰니까 datasource 를 참조 안시켜도 

- DAO 부분
DAO
@Repository
public class RecruitDAO extends WMBaseDAO {

private static String packageName = "JobInfo.";

@Autowired
@Override
public void setSqlMapClient(@Qualifier("sqlMapClient-hris")SqlMapClient sqlMapClient) {
super.setSqlMapClient(sqlMapClient);
}

public void insertRecruitStep02(HashMap<String, Object> mapParams) throws Exception{
delete(packageName+"deletePhoto",mapParams); // 사진 삭제
insert(packageName+"insertPhoto", mapParams); // 사진 등록

insert(packageName+"insertLGADDRM", mapParams); // 지원자 신상1 정보 등록..
insert(packageName+"insertLGMASTM", mapParams); // 지원자 신상2
insert(packageName+"insertLGBDSTM", mapParams); // 지원자 신체사항
insert(packageName+"insertLGMILM", mapParams); // 지원자 병력사항

//지원자 가족사항
List<HashMap<String, Object>> famList = (List<HashMap<String, Object>>)mapParams.get("LGFAMLM");

for(int i = 0 ; i < famList.size(); i++)
{
HashMap<String, Object> famObj = (HashMap<String, Object>)famList.get(i);
insert(packageName+"insertLGFAMLM", famObj); // 지원자 병력사항
}
}
}

- Service 부분

@Service
public class RecruitService {

@Autowired
private RecruitDAO dao;

@Transactional(propagation=Propagation.REQUIRED, rollbackFor = Exception.class)
public void insertRecruitStep02(HashMap<String, Object> mapParams) throws Exception{
dao.insertRecruitStep02(mapParams);
}
}



서버 재가동

 <!-- jeus connection pool 사용을 위한 jndi lookup -->
<jee:jndi-lookup id="dataSource-totd" jndi-name="jdbc/datasource1" resource-ref="true" />
<jee:jndi-lookup id="dataSource-hris" jndi-name="jdbc/datasource3" resource-ref="true" />
<jee:jndi-lookup id="dataSource-another" jndi-name="jdbc/datasource1" resource-ref="true" />

<!-- dataSource-totd datasource의 transaction 처리를 위한 transactionmanager설정 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource-totd" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager_hris" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource-hris" />
<!-- <tx:annotation-driven transaction-manager="transactionManager_hris"/> -->

<aop:config>
<aop:pointcut id="recruitOperation"
expression="execution(* wm.ir.jobInfo.service.RecruitService.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="recruitOperation" />
</aop:config>

<tx:advice id="txAdvice" transaction-manager="transactionManager_hris">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

2011년 6월 14일 화요일

sql실습

SELECT employee_id, department_id FROM TBL_EMP


SELECT 1 a, 2 b, 3 c FROM dual
UNION ALL
SELECT 4 a, 5 b, 6 c FROM dual


SELECT SUM(d10), SUM(d20), SUM(d30)
FROM
(SELECT COUNT(employee_id) d10 , 0 d20, 0 d30 FROM TBL_EMP WHERE department_id = 10
UNION ALL
SELECT 0 d10, COUNT(employee_id) d20, 0 d30 FROM TBL_EMP WHERE department_id = 20
UNION ALL
SELECT 0 d10, 0 d20, COUNT(employee_id) d30 FROM TBL_EMP WHERE department_id = 30 ) dept



SELECT '10' d10, '20' d20, '30' d30, '40' d40, '50' d50 FROM dual
UNION ALL
SELECT
SUM( DECODE(department_id, 10, 1, 0)) d10 ,
SUM( DECODE(department_id, 20, 1, 0)) d20 ,
SUM( DECODE(department_id, 30, 1, 0)) d30 ,
SUM( DECODE(department_id, 40, 1, 0)) d40 ,
SUM( DECODE(department_id, 50, 1, 0)) d50
FROM TBL_EMP




SELECT * FROM hr.EMPLOYEES, hr.DEPARTMENTS WHERE employee_id = 100


SELECT 2889/107 FROM dual

SELECT *
FROM
(SELECT * FROM hr.EMPLOYEES WHERE employee_id = 100 ) emp, hr.DEPARTMENTS



SELECT
*
FROM
(
SELECT ROWNUM rn, seqno, title, writer, regdate, updatedate
FROM
TBL_BOOK
WHERE seqno > 0
AND ROWNUM > 0 AND ROWNUM <= (3 * 10) ORDER BY seqno desc ) WHERE rn > ( (3-1) * 10)



SELECT * FROM hr.DEPARTMENTS

SELECT employee_id, dept.department_id
FROM hr.EMPLOYEES emp, hr.DEPARTMENTS dept
WHERE emp.DEPARTMENT_ID(+) = dept.DEPARTMENT_ID

2011년 6월 13일 월요일

100만건 만들기

CREATE table tbl_book (
seqno NUMBER,
title VARCHAR2(300) NOT NULL,
writer VARCHAR2(100) NOT NULL,
regdate DATE DEFAULT SYSDATE,
updatedate DATE DEFAULT sysdate
);

ALTER TABLE tbl_book ADD CONSTRAINT pk_book PRIMARY KEY (seqno);

CREATE SEQUENCE seq_book;


INSERT INTO tbl_book (seqno, title, writer )
VALUES (SEQ_BOOK.NEXTVAL, 'The old man and the sea', 'Honest Hamingway');

SELECT * FROM tbl_book;

INSERT INTO tbl_book(seqno, title,writer) (SELECT SEQ_BOOK.NEXTVAL, title, writer FROM tbl_book);

100만건 만들기

CREATE table tbl_book (
seqno NUMBER,
title VARCHAR2(300) NOT NULL,
writer VARCHAR2(100) NOT NULL,
regdate DATE DEFAULT SYSDATE,
updatedate DATE DEFAULT sysdate
);

ALTER TABLE tbl_book ADD CONSTRAINT pk_book PRIMARY KEY (seqno);

CREATE SEQUENCE seq_book;


INSERT INTO tbl_book (seqno, title, writer )
VALUES (SEQ_BOOK.NEXTVAL, 'The old man and the sea', 'Honest Hamingway');

SELECT * FROM tbl_book;

INSERT INTO tbl_book(seqno, title,writer) (SELECT SEQ_BOOK.NEXTVAL, title, writer FROM tbl_book);

2011년 6월 9일 목요일

루저의 말을 듣지 말고, 위너의 말을 듣기를...

살다보면 누구나 힘들거나, 지겹거나, 나태한 시기가 오는 것 같습니다.

그런데.. 주변의 사람들 중에서는 그 상황을 벗어나기 위한 편한 방법을 쓰는 사람들에게 혹하는 것 같습니다.

즉 불평 불만을 하고, 같이 투덜거리고, 남의 탓을 하는 겁니다.



그게 더 쉬우니까요..


혼자 할 일을 찾고, 묵묵하게 자신의 일을 하는 것은 참으로 어렵고 힘든 일인것 같습니다.

하지만 모든 역사가 증명해 줍니다.

불평불만은 결국 루저들의 몫입니다.

그걸로 해결되는 것은 아무것도 없습니다.
좀 더 높은 세계를 봐야 합니다.

위너라고 불리는 사람들이 대처하는 방식을 ..


부모님들이 좋은 학교에 가라.. 좋은 직장에 가라는 말은 결국은
그런 위너들이 더 많은 곳에서 배우길 바라는 마음이 아닐까..


바보처럼 투덜거리지 마십시요..
그건 루저들이나 하는 짓입니다.

맨 마지막 승부는 자신이 하는 겁니다.
그 평가는 아무도 손댈수 없습니다. 본인이 스스로 잘 느끼기 때문에...
마음에 빚을 지고 살지 맙시다...

2011년 6월 8일 수요일

제네릭의 본질에 대하여..

흔히들 Java기초를 공부하는 동안 Generic문법을 피상적으로 공부하게 됩니다.
예를들어

List list = new ArrayList();

방식의 코드입니다.

그럼 이것이 Generic문법인가요? 아닙니다.

Generic은 코드를 작성할 때 형(타입)을 결정하는 것이 아니라,
코드가 활용될 때 타입을 결정하는 방식이라는 겁니다.

예를 들어 볼까요?


public class GenericEx {

public void add(E p1, K p2){

System.out.println(p1);
System.out.println(p2);

}
}


위의 코드에 대한 해석은 나중에 E, K라는 타입을 결정해 주겠다는 코드입니다.
이것이 객체화 될 때는 다음처럼 다양한 방식의 코드를 생성해 줄 수 있게 됩니다.

GenericEx ex1 = new GenericEx();

ex1.add("AAAAAAAAAA", 1234);

GenericEx ex2 = new GenericEx();

ex2.add( 1234.12, 1234F);


코드를 보면 나중에 파라미터의 타입을 전혀 다르게 결정하는 모습을 볼 수 있습니다.

사실 제네릭은 자바의 기존의 Object타입의 모호성과 오버로딩의 제약을 해결하기 위한 하나의 방식이라고 보는 것이 더 좋지 않을까 싶습니다.


--------------------------------------------
한동안 정신적으로, 육체적으로 힘든 시기였습니다.
때문에 이 블로그 작성역시 소홀했습니다.
아직 온전하지 않은 육체와 정신이지만 다시 노력해 보려 합니다.

2011년 5월 11일 수요일

오라클페이징

2011년 5월 5일 목요일

안드로이드 SMS 메시지 가로채기

Bundle bundle = intent.getExtras();

SmsMessage[] msgs = null;
String str = "";
if (bundle != null)
{
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
}
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();

2011년 4월 15일 금요일

오라클 계층형 게시판용 SQL

예를들어 다음과 같은 구조로 게시판을 만들어야 한다면?


1

  2
 
    3
    
       6
    
    4


  5
 
  7


create table tbl_board (
  seqno number,
  title varchar2(300) not null,
  content varchar2(4000) not null,
  writer varchar2(50) not null,
  regdate date default sysdate,
  updatedate date default sysdate,
  gid number,
  ord number,
  pid number,
  depth number
);

alter table tbl_board add constraint pk_board primary key (seqno);





drop sequence seq_board;

create sequence seq_board increment by 1;

delete  tbl_board;
--원글 등록--
insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title1','content1','user00', seq_board.currval, 0, 0, 0);

--2
--select * from tbl_board start with pid= 1 connect by pid = prior seqno;

--select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1);

insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title2','content2','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1), 1, 1);

--3
--select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 2 connect by pid = prior seqno) ) from tbl_board where seqno = 2;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 2 connect by pid = prior seqno) ) from tbl_board where seqno = 2);

insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title3','content3','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 2 connect by pid = prior seqno) ) from tbl_board where seqno = 2), 2, 2);

--4

--select * from tbl_board start with pid= 1 connect by pid = prior seqno;

--select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 2 connect by pid = prior seqno) ) from tbl_board where seqno = 2);

insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title3','content3','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1), 2, 2);


--5

--select * from tbl_board start with pid= 1 connect by pid = prior seqno;

--select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1);

insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title3','content3','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1), 1, 1);


--6

--select * from tbl_board start with pid= 3 connect by pid = prior seqno;

--select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 3 connect by pid = prior seqno) ) from tbl_board where seqno = 3;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 3 connect by pid = prior seqno) ) from tbl_board where seqno = 3);


insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title6','content6','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 3 connect by pid = prior seqno) ) from tbl_board where seqno = 3), 3, 3);


--7

select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1;

update tbl_board set ord = ord + 1 where gid = 1 and ord >= (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1);

insert into tbl_board (seqno, title, content, writer, gid, ord, pid, depth)
values (seq_board.nextval, 'title7','content7','user00', 1, (select (ord + (select count(seqno) + 1  r from tbl_board start with pid= 1 connect by pid = prior seqno) ) from tbl_board where seqno = 1), 1, 2);

2011년 4월 12일 화요일

의존성 주입의 개념에 관하여

객체지향 프로그래밍에서 가장 신경을 많이 쓰는 것은 역시나 '객체의 구성'입니다.

예를 들어  A,B,C 라는 객체가 있다고 가정해 보면 가장 쉬운 방식의 구성은 '기차'와 같은 방식으로 연결하는 구조라고 할 수 있습니다.

이 방식을 전문적으로 ' Demeter'방식이라고 합니다.

이 방식은  A클래스안에  B b = new B( );  와 같은 방식으로 다음에 연결될 객체를 의존적으로 사용하는 방식을 의미합니다.

 Demeter 방식은 하나의 클래스를 여러 곳에서 사용하는 경우(그물망 구조)에는 아주 최악의 복잡성을 가지게 됩니다.

따라서 이런 상태에서는 효율적인 설계를 위해서 '기차'대신에 'G마켓'방식을 사용합니다.
(당근 공식용어일리가 없잖앗!)


전문적으로 'Facade'패턴이라고 하기도 하는데 우리가  G마켓을 통해서 물건을 구매하면 안쪽에서 실제 업체를 몰라도 되는 것과 비슷한 방식입니다.

우리가 알아야 하는 것은 'G마켓'의 역할을 하는 객체만 알고 사용하면 됩니다.

이 방식의 복잡성을 하나로 모으는 효과를 가집니다.(간단히 여러분이 여러개의 인터넷 쇼핑몰을 돌아다닐 필요가 없는것과 마찬가지 입니다)


이 방식의 코드는 예를 들어 A클래스 안에서  B target = Facade.get("B") 처럼 A가 G마켓 역할을 하는 존재만 알면 되도록 하는 구조를 사용합니다.

하지만 Facade역할을 하는 코드가 없다면 이 역시 무용지물이므로 전체구조가 경직되는 것을 피할 수는 없습니다.

이래서 등장한 방식이.. 음..


이해를 위한 거니까..

'시라노 연애 조작단' 방식과 같은 방식입니다.

즉 어떤 객체가 알아채지 못하게 알아서 모든 상황을 준비하는겁니다.

예를 들어 A가 B객체가 필요하다면

누군가  A를 필요로 할때  B객체를 미리 준비 시켜서 동행시키는 방식입니다.

즉 외부에서 필요한 객체(dependency) 를 집어넣는다(injection)는 개념으로 봐야합니다.

영화에서 보면 한 커플을 맺어주기 위해서 많은 스텝들이 움직이듯이..

외부에 거대한 존재가 A가 필요한 모든 다른 객체들을 준비해 두었다가 A를 사용하는 순간에 완벽한 상황을 만들어서 처리하는 방식이라고 생각할 수 있습니다.

의존성 주입은 A안에는 B 를 받아들이는 코드만 준비해 두고..

외부에서 B를 A에 넣은 상태로 만들어서 사용하는 방식이므로

A의 코드안에서 실제 new 하는 코드를 없앨 수 있게 됩니다.