음...저도 참 몰랐는데, 이게 윈도우 환경이다보니....-_-;
참 셋팅도 힘들군요.

아무 셋팅을 안했다면 디버깅을 하게 되면 아래와 같은 경고문이 뜰껍니다.
사용자 삽입 이미지

Can't find a source file at "/cygdrive/d/~~~~~.c
Locate the file or edit the source lookup path to include its location.
저걸 보면서 느낀점은 "아놔! 저기에 파일 있잖아! 미췬 이클립스야!!!" 라는 생각이 들었는데요.

자세히보면 /cygdrive/d/....... 우리가 사용하는 윈도우는 d:/ 이겠지요.
저걸 매핑하는 것을 이클립스에서 지원합니다.

Window -> Preferences -> C/C++ -> Debug -> Common Source Lookup Path라는 것이 있습니다.
여기서 add버튼을 클릭해서 Path Mapping을 선택합니다.
추가된 것을 선택하고, Edit를 합니다.
이름은 아무렇게나 써주시고, Add를 합니다.
Compilation Path에 /cygdrive/d(c드라이브는 c일껍니다) 라고 적고,
Local file system path에다가는 실제 드라이브 경로 (ex - d:\. c드라이브면 c라고 해야할 껍니다 ^^)

그러면 이제 잘 찾네요.
원격 디버깅도 해봐야하는데-_-;

 
Posted by 머드초보
,
 
집에 컴퓨터가 고장이나서-_-;
포맷을 했는데, 이클립스를 받으러 가니까 뭔가 사이트가 아주 약간 살짝 달라진 듯한 느낌이 있었습니다.
뭐지-_-; 하고 다운로드를 받아보니 새버전이군요.

뭐가 달라진걸까요?-_-;

사용자 삽입 이미지

이것이 달라졌습니다!!!
로고가......더 찐해졌습니다-_-;

그리고......뭐가 달라졌지-_-;

찾아봐야하나....-_-;

에이 뭐 더 좋게 바뀌었겠지-_-;


 
Posted by 머드초보
,
 
Aptana로 javascript로 삽질중에-_-; 좀 쉴겸해서-_-;

AIR는 기존에 우리가 알던 html, ajax, javascript등을 이용해서 데스크탑 애플리케이션을 개발할 수 있습니다. 전에 다음openapi를 이용하고, prototype기반인 다음블로그검색을 만들었었습니다.

http://mudchobo.tomeii.com/tt/269

이 코드를 거의 그냥 이용해서 AIR애플리케이션으로 바꿀 수 있습니다.
우선 Aptana를 설치해야합니다.

http://mudchobo.tomeii.com/tt/241
여기에 Aptana설치 후기가 있습니다-_-;
기본으로 AIR프로젝트 만드는 건 안깔려있으니 따로 설치해야합니다. 글을 잘 읽어보시면 설치하기 쉽습니다^^

이제 프로젝트를 만들어봅시다.
File -> New - Project선택하면 Aptana Projects폴더에 -> Adobe AIR Project선택.
Project이름은 DaumBlogSearchAir라고 합시다-_-;
다음을 하면 뭔 옵션이 이래 많아-_-; XML파일을 사전에 설정할 수 있게 해놨는데 걍 디폴트로 해서 해봅시다.
마지막 다음으로 가면 javascript framework를 선택할 수 있습니다.
Prototype을 가볍게 체크해고 Finish를 누릅시다.

처음부터 뭔 쌤플로 자동으로 작성한게 많은지-_-;
DaumBlogSearchAir.html파일을 열어보면 코드가 많습니다. 가볍게 다 지워버리고-_-;
DaumBlogSearchAir.html
[code]<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Daum Blog Search</title>
        <link href="sample.css" rel="stylesheet" type="text/css"/>
        <script type="text/javascript" src="AIRAliases.js"></script>
        <script type="text/javascript" src="lib/prototype/prototype.js"></script>
        <script type="text/javascript" src="js/DaumSearch.js"></script>
    </head>
    <body>
        <h1>Daum Blog Search!</h1>
        <form onsubmit="searchDaum(this.query.value); return false;">
            <fieldset>
                <label>Search for</label>
                <input type="text" name="query" /><input type="submit" value="검색" />
            </fieldset>
        </form>
        <div id="results"></div>
    </body>
</html>
[/code]
요렇게 작성합니다.
그럼 이제 우리가 작성할 것은 js폴더에 있는 DaumSearch.js파일 입니다.
작성해봅시다.
DaumSearch.js
[code]
function searchDaum(query){
    var searchPacket = {
        method: 'get',
        parameters: {
            q: query,
            result: '10',
            start: '1',
            output: 'json',
            apikey: '발급받은 apikey',
        },
        onSuccess: parseResponse
    }
    new Ajax.Request('http://apis.daum.net/search/blog', searchPacket);
}


function parseResponse(data){
    var children;
    var results = $("results");
   
    while (results.hasChildNodes()) {
        results.removeChild(results.lastChild);
    }
   
    var json = data.responseText.evalJSON();
   
    // 개수를 air에서 제공하는 trace로 찍어보자-_-;
    air.trace(json.channel.result);
   
    for (var i = 0; i < json.channel.result; i++) {
        var title = json.channel.item[i].title;
        var summary = json.channel.item[i].description;
        var url = json.channel.item[i].link;
       
        var link = new Element("a", {
            "href": url,
            "target": "_blank"
        }).update(title);
        var header = new Element("h2").insert(link);
        var para = new Element("p").update(summary);
       
        results.insert(header);
        results.insert(para);
    }
}
[/code]
간단합니다. 그냥 다음에 url요청해서 데이터를 받아서 parseResponse메소드가 파싱하죠.
그리고, airaliases.js파일을 선언하면 air객체를 사용할 수 있는데, 기존 Flex에서 제공하는 몇몇 기능을 사용할 수 있습니다. Socket도 있고, File관련된 것도 있군요. 이건 나중에 공부해야겠군요.
air.trace하면 로그를 남길 수 있습니다.
아직 Aptana에서 디버깅이 안되기 때문에-_-;(완전 최악-_-) trace를 열심히 찍어줘야할 겁니다-_-;

실행을 해봅시다.
Ctrl + F11누르면 실행됩니다.

사용자 삽입 이미지

음....근데 <b>가 나오네. 왜그러지-_-;

 
Posted by 머드초보
,
 
사용자 삽입 이미지

음....우선 영화의 재미도는 보통입니다.
코믹적인 부분도 조금 있고, 나름 심각한 부분도 있고 그러네요.
이 영화와 연관된 영화는 내 생애 최악의 남자가 아닐까싶네요.

내 생애 최악의 남자도 극중에서 탁재훈이랑 염정아랑 둘 다 바람피는 걸루 나오거든요.
여기서도 김하늘이랑 윤계상이 바람 피는 걸루 나와요.
두 영화의 공통점은 바람남이 같다는거?-_-;
신성록이라는 배우인데, 염정아랑도 바람피고, 김하늘이랑도 바람을 피는군요-_-;
이 사람 바람남 전문 배우인가요? ^^

암튼, 6년동안 연애한 커플들을 현실적(?)으로 묘사했구요. (사실 저도 해보지는 않았습니다만-_-;)
뭐 그냥 아무생각없이 볼 수 있는 저한테 딱인 영화입니다.

영화의 포인트는 윤계상씨의 능숙한 욕입니다. 정말 잘 합니다.
윤계상씨의 멋진 욕을 듣고 싶으신 분들에게 추천합니다!!!

아...영화를 보고 난 뒤에 뭐가 기억이 남는 장면이 없어요-_-;

 
Posted by 머드초보
,
 
Thread를 두개를 실행시켜서 DB에 동시에 INSERT를 시켜버리니 INSERT할 때 데이터가 AUTOINCRESEMENT가 아니라 ID부분을 직접 입력해서 하는 부분이면 문제가 발생합니다.
그래서 이 MERGE INTO문을 활용해서 데이터가 있으면 INSERT하고 없으면 UPDATE하는 구문을 만들었습니다.
이렇게 해도 제 생각이지만, Thread한 놈은 이미 데이터가 없는 것을 확인하고 insert를 시도 하려고 하고, 다른 Thread놈은 저 놈이 insert를 아직 하지 않았으니까 검색해서 안나오니 insert를 해보려고 하니 둘 다 insert를 시도하게 되더라구요.

이게 예제 입니다.
우선 테이블구조입니다.
테이블은 autoincreament가 아닌 수동적인 기본키를 사용합니다.
[code]CREATE TABLE "INSERTTABLE" ( "ID" NUMBER NOT NULL ENABLE, "DATA" VARCHAR2(4000) NOT NULL ENABLE, CONSTRAINT "INSERTTABLE_PK" PRIMARY KEY ("ID") ENABLE )
[/code]


applicationContext.xml
[code]<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:component-scan base-package="thread" />
   
    <!-- oracle용 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="oracle.jdbc.driver.OracleDriver"
        p:url="jdbc:oracle:thin:@localhost:1521:XE"
        p:username="mudchobo" p:password="1234" />
 
    <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient"
        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
        p:dataSource-ref="dataSource"
        p:configLocation="classpath:config/SqlMapConfig.xml" />
   
    <bean id="sqlMapClientTemplete"
        class="org.springframework.orm.ibatis.SqlMapClientTemplate"
        p:sqlMapClient-ref="sqlMapClient"/>
           
</beans>
[/code]
SqlMapConfig.xml
[code]<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <sqlMap resource="config/Insert.xml" />
</sqlMapConfig>
[/code]
Insert.xml
[code]<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Sqlmap">
       <insert id="insertData">
           MERGE INTO INSERTTABLE
           USING DUAL
           ON (ID = 1)
           WHEN MATCHED THEN
           UPDATE SET
           DATA = 'HERMUSSERI'
           WHEN NOT MATCHED THEN
           INSERT (ID, DATA)
           VALUES (1, 'MUDCHOBO')
       </insert>
      
</sqlMap>
[/code]
ThreadTestDao.java
[code]package thread;

public interface ThreadTestDao {
    public void insertData();
}
[/code]
ThreadTestDaoImpl.java
[code]package thread;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class ThreadTestDaoImpl implements ThreadTestDao {

    @Autowired
    private SqlMapClientTemplate sqlMapClientTemplate;

    @Override
    public void insertData() {
        sqlMapClientTemplate.insert("insertData");
    }
}
[/code]
TestThread.java
[code]package thread;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Scope("prototype")
@Component
public class TestThread extends Thread {

    @Autowired
    private ThreadTestDao threadTestDao;
   
    @Override
    public void run() {
        threadTestDao.insertData();
    }
}
[/code]
ThreadTest.java
[code]package thread;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ThreadTest {

    public static void main(String[] args) {
        String configLocation = "config/applicationContext.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(
                configLocation);

        TestThread testThread1 = (TestThread) context
                .getBean("testThread");
        TestThread testThread2 = (TestThread) context
                .getBean("testThread");
       
        testThread1.start();
        testThread2.start();
    }
}
[/code]
실행할 때 계속 몇번을 실행해보면-_-; unique constraint 또는 ORA-00001: 무결성 제약 조건(MUDCHOBO.INSERTTABLE_PK)에 위배됩니다를 볼 수 있을 겁니다.

이게 제 생각인데, 첫번째 스레드가 돌면서 데이터를 확인하니 없길래 insert를 하려던 찰나에 두번째 스레드놈도 거의 동시에 데이터를 확인하니 없어서 insert를 시키려다가 에러가 나는 듯한데요.

트랜잭션도 먹이고 별 지롤을 다 했는데 안되길래 그냥 싱크방식으로 변경해버렸습니다.
insertData라는 메소드에
[code]@Override
    synchronized public void insertData() {
        sqlMapClientTemplate.insert("insertData");
    }
[/code]
메소드 앞에 synchronized를 붙입니다.
이건 어떤 스레드가 호출을 했으면 다음 스레드는 기다린 다음에 접근하게 되는 즉 싱크방식으로 처리를 시킬 수 있는 메소드가 됩니다.
이렇게 처리하면 효율은 좀 떨어지겠지만, 유니크 중복에러는 그나마 막을 수 있습니다.

다른 방법 있으면 좀 알려주세요 ㅠㅠ 고생하고 있습니다 ㅠ




 
Posted by 머드초보
,