참고 : http://intomysql.blogspot.kr/2011/01/join-update-multiple-table-update.html
         http://intomysql.blogspot.kr/2011/01/join-delete-multiple-table-delete.html


1. JOIN으로 여러 테이블 한번에 DELETE (DELETE와 FROM 절 사이에 삭제할 테이블 명시)

DELETE A, B, C
   FROM USER A
   LEFT JOIN USER_PHOTO B
               ON A.USER_ID = B.USER_ID
   LEFT JOIN USER_TOPIC C
              ON A.USER_ID = C.USER_ID
 WHERE A.USER_ID = 'test'

 
1-1. JOIN으로 여러 테이블 한번에 DELETE (FROM과 USING 절 사이에 삭제할 테이블 명시)
     - A, B 테이블만 삭제되고 C 테이블은 JOIN에만 참여

DELETE FROM A, B
  USING USER A INNER JOIN USER_PHOTO B INNER JOIN USER_TOPIC C
 WHERE A.USER_ID = B.USER_ID
     AND A.USER_ID = C.USER_ID
    AND A.USER_ID = 'test'





2. JOIN 으로 테이블 UPDATE
     - 두 테이블이 USER_ID로 JOIN 후 B테이블의 SOURCE_COL 값이 A테이블 TARGET_COL로 업데이트 된다.

UPDATE USER A, USER_PHOTO B
      SET A.TARGET_COL = B.SOURCE_COL
 WHERE A.USER_ID = B.USER_ID



 2-1. JOIN 으로 여러 테이블 한번에 UPDATE
    - 두 테이블이 USER_ID로 JOIN 후 B테이블의 SOURCE_COL 값이 A테이블 TARGET_COL로 업데이트 되고 A테이블의 SOURCE_COL 값이 B테이블 TARGET_COL로 업데이트 된다.

UPDATE USER A, USER_PHOTO B
      SET A.TARGET_COL = B.SOURCE_COL
          , B.TARGET_COL = A.SOURCE_COL
 WHERE A.USER_ID = B.USER_ID



 2-2. JOIN 으로 여러 테이블 한번에 UPDATE
   - 두 테이블이 USER_ID로 JOIN 후 B테이블의 SOURCE_COL 값이 A테이블 TARGET_COL로 업데이트 되고 A테이블의 SOURCE_COL 값이 B테이블 TARGET_COL로 업데이트 된다.

UPDATE USER A JOIN USER_PHOTO B
      ON A.USER_ID = B.USER_ID
      SET A.TARGET_COL = B.SOURCE_COL
          , B.TARGET_COL = A.SOURCE_COL
 WHERE A.USER_ID = 'TEST'



 

http://code.google.com/p/sqlyog/downloads/list


간만에 MySQL을 사용할 일이 있어 SQLyog를 다운받으러 Webyog 사이트를 뒤져보는데 다운로드 페이지에 무료 버전이 보이지 않는 것이다!! 그리고 처음 보는 30일 평가판이 보였다.


Google Code SQLyog Community Edition (http://code.google.com/p/sqlyog/downloads/list)


SQLyog는 Trial이 아닌 Community Edition이 무료버전이었다. 
사이트 검색을 해보니 Community Edition은 Webyog에서 호스팅하지 않는다는 답변이 있다.

출처 : http://devday.tistory.com/entry/ArtifactDescriptorException-Failed-to-read-artifact-descriptor-for-xxx

Maven 프로젝트 체크아웃 시 다음과 같은 에러에 직면할 수 있다.

ArtifactDescriptorException: Failed to read artifact descriptor for org.apache.commons:com.springsource.org.apache.commons.logging:jar:1.1.1: ArtifactResolutionException: Failure to transfer org.apache.commons:com.springsource.org.apache.commons.logging:pom:1.1.1 from http://repository.springsource.com/maven/bundles/release was cached in the local repository, resolution will not be reattempted until the update interval of com.springsource.repository.bundles.release has elapsed or updates are forced. Original error: Could not transfer artifact org.apache.commons:com.springsource.org.apache.commons.logging:pom:1.1.1 from/to com.springsource.repository.bundles.release (http://repository.springsource.com/maven/bundles/release): No route to host to http://repository.springsource.com/maven/bundles/release/org/apache/commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.pom    pom.xml    /spring.test    line 1    Maven Dependency Problem

or


Received fatal alert: protocol_version



이 경우 다음과 같이 한다.

Maven -> Update Dependencies

다음을 체크하고, OK 버튼을 클릭한다.

Force Update of Snapshots/Releases


Java 1.7을 사용해서 이클립스나 JDK 를 실행했을 때에는 위와 같은 방법으로도 되지 않느다.

방법1) 이클립스 기동을 1.8 이상으로 한다.

- eclipse.ini 수정

-vm
../openjdk-1.8.0.242-1.b08/bin/javaw.exe
-startup
... (생략) ...




방법2) JVM 옵션에 TLSv1.2 protocol을 추가한다.

- eclipse.init 수정

... (생략) ...
-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
-Xms40m
... (생략) ...




Homepage : http://jwebsocket.org/

Spring Long Polling Server : http://blog.springsource.org/2012/05/16/spring-mvc-3-2-preview-chat-sample/
                           https://github.com/rstoyanchev

참고 Ajax Push Engine : http://www.ape-project.org/


Push Server 구현 방식
1. Hidden IFrame
2. polling - Ajax
3. Long polling - Ajax (Comet)
4. SSE (Server-Send-Event)


WebSocket과 Async : https://www.slipp.net/wiki/pages/viewpage.action?pageId=14549157




출처 : http://blog.naver.com/tyboss/70097410517

Java SE Autodownload Files
http://www.oracle.com/technetwork/java/javase/autodownload-140472.html


Applet 을 만들 때 package를 적용하고 싶으면 java 프로젝트를 별도로 만들어 jar로 배포를 하고 class 파일 단위로 처리할 경우에는 pacakge 없이 컴파일을 해야 한다.

Applet을 refresh 하고 싶다면 새로고침 시 나오는 java 보안 경고 창에서 실행/취소 중 취소를 클릭하고 Applet 표시 부분에 마우스 우클릭 Reload Applet 클릭하면 됨. Java 콘솔도 우클릭 메뉴에 있음.



1. Applet 만들기

package com.maruara.applet;

import java.applet.Applet;
import java.awt.TextField;
import java.util.Date;

import netscape.javascript.JSObject;

public class TestApplet extends Applet implements Runnable {

  /**
  *
  */
 private static final long serialVersionUID = -176201962325630072L;
 
 JSObject window;
 Thread clockThread;
 Date date;
 boolean running = true;
 TextField tf = new TextField(30);

 public void init() {
  window = JSObject.getWindow(this);
  
  clockThread= new Thread(this);
  clockThread.start();
  add(tf);

  /*
  JSObject window = JSObject.getWindow(this);
  JSObject document = (JSObject)window.getMember("document");
  JSObject location = (JSObject)document.getMember("location");
   
  String s = (String)location.getMember("href");
  window.call("doAlert", null);
  */
 }
 
 public void doStart(String msg) {
  System.out.println(msg);
  tf.setText(msg);
  
  running = true;
  clockThread= new Thread(this);
  clockThread.start();
 }
 
 public void doStop(String msg) {
  System.out.println(msg);
  tf.setText(msg);
  
  running = false;
  clockThread = null;
 }
 
 public void run() {
  // loop until told to stop
        while (running) {
            date = new Date();
           
            window.call("view", new Object[] {date});
           
            try {
             // Wait 500milliseconds before continuing
                clockThread.sleep(1000);
            } catch (InterruptedException e) {
             System.out.println(e);
            }
            // he has wait and will now restart his actions.
         }
    }
 
 public void destroy()
    {
         // will cause thread to stop looping
         running = false;
         // destroy it.
         clockThread = null;
    }
 
}


2. Applet Jar로 묶어서 Web 서버에 올리기

jar 묶을 때 src class folder만 체크한 후 export 한다.
이미지처럼 웹에서 접근할 수 있는 경로로 이동한다.


3. HTML 적용

 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>

</head>
<body>

<%-- <object id="myApplet" name="myApplet" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" archive="${pageContext.request.contextPath }/myApplet.jar" width="200" height="200" codebase="http://java.sun.com/update/1.7.0/jinstall-7u17-windows-i586.cab"> --%>
<%--  <param name="archive" value="${pageContext.request.contextPath }/myApplet.jar" /> --%>
<!--     <param name="code" value="com.maruara.applet.TestApplet.class" /> -->
<!--     <param name="codebase" value="." /> -->
<!--     <param name="type" value="application/x-java-applet;version=1.6" /> -->
<!--      No JDK 1.3 support for APPLET!! -->
<!-- </object> -->

<!-- <embed id="testapplet" -->
<!--        type="application/x-java-applet;version=1.7" -->
<!--        width="256" height="256"  -->
<%--        archive="${pageContext.request.contextPath }/myApplet.jar" --%>
<!--        code="com.maruara.applet.TestApplet.class" -->
<!--        pluginspage="http://java.com/download/" /> -->


<object id="myApplet" name="myApplet" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" archive="${pageContext.request.contextPath }/myApplet.jar" width="200" height="200" codebase="http://java.sun.com/update/1.7.0/jinstall-7u17-windows-i586.cab">
 <param name="archive" value="${pageContext.request.contextPath }/myApplet.jar" />
    <param name="code" value="com.maruara.applet.TestApplet.class" />
    <param name="codebase" value="." />
    <param name="type" value="application/x-java-applet;version=1.6" />
    <comment>
     <embed id="myApplet"
         type="application/x-java-applet;version=1.7"
         width="256" height="256"
         archive="${pageContext.request.contextPath }/myApplet.jar"
         code="com.maruara.applet.TestApplet.class"
         pluginspage="http://java.com/download/" />
    </comment>
</object>

<div id="view"></div>
<button type="button" id="btnStart">시작</button>
<button type="button" id="btnStop">정지</button>

<script>
function view(time) {
 $('#view').text(time);
}

$('#btnStart').on('click', function() {
  $('#myApplet').get(0).doStart('stop');
});

$('#btnStop').on('click', function() {
 document.getElementById('myApplet').doStop('stop');
});
</script>

</body>
</html>

 

<script language="Javascript">

  var _app = navigator.appName;

  if (_app == 'Netscape') {
    document.write('<embed code="Applet1.class"',
                   'width="200"',
                   'height="200"',
                   'type="application/x-java-applet;version=1.5.0">');
    }
  else if (_app == 'Microsoft Internet Explorer') {
    document.write('<OBJECT ',
                   'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
                   'width="200"',
                   'height="200">',
                   '<PARAM name="code" value="Applet1.class">',
                   '</OBJECT>');
    }
  else {
    document.write('<p>Sorry, unsupported browser.</p>');
    }

</script> 


1. ROWNUM 구현하기

 SELECT @RNUM := @RNUM + 1 AS RNUM
            , A.*
    FROM 테이블 A
           , (SELECT @RNUM := 0) B



2. ROW_NUMBER(PARTITION BY ...) 구현하기

참고 : http://www.explodybits.com/2011/11/mysql-row-number/

ROW_NUMBER(PARTITION BY 컬럼1 ORDER BY 컬럼2)

SELECT @ROW_NUM := IF(@PREV_VALUE = A.컬럼1, @ROW_NUM + 1, 1) AS ROW_NUMBER
          , @PREV_VALUE := A.컬럼1
          , A.*
  FROM 테이블 A
         , (SELECT @ROW_NUM := 1) X
         , (SELECT @PREV_VALUE := '') Y
 ORDER BY A.컬럼2

-- 참고 샘플
SELECT  @row_num := IF(@prev_value=o.Customer,@row_num+1,1) AS RowNumber
       ,o.Customer
       ,o.OrderDate
       ,o.Amount
       ,@prev_value := o.Customer
  FROM Orders o,
      (SELECT @row_num := 1) x,
      (SELECT @prev_value := '') y
  ORDER BY o.Customer, o.OrderDate DESC



 



 

굴림 9pt(12px)의 글자 크기에 맞춰서 Width로 글자 자르기
굴림체는 맨 아래 byte 글자 자르기로 하면 되고 가변 글자체일 경우에는 해당 width를 수정하여 사용하면 된다.


출처 (PHP) : http://www.xpressengine.com/zb4_tip/854296
출처 첨부파일 :cutstring.php



Java 소스로 변환 (junit test) :TestSubWidth.java

 package test;

import java.text.StringCharacterIterator;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

public class TestSubByte {
 
 private final static String[] strTemp = new String[10];
 private final static int[] strWidth = new int[10];
 private static Map<Integer, Integer> asciiMap = new HashMap<Integer, Integer>();
 
 static {
  strTemp[0] = "@#&*@※☆★○●◎◇◆△▽→←↔〓◁◀▷▶♤♡♧⊙◈▣◐◑▒▤▥▨▧▦▩♨☏☎☜☞↗↙↖↘♭♩♬㉿㈜№㏇™㏂㏘℡";
  strWidth[0] = 12;
  strTemp[1] = "\\mM";
  strWidth[1] = 11;
  strTemp[2] = "%wW□■▲▼♣";
  strWidth[2] = 10;
  strTemp[3] = "~QONGC↑↓♠♥↕®";
  strWidth[3] = 9;
  strTemp[4] = "<>&ZXYRSTUVKHEDBAP♪";
  strWidth[4] = 8;
  strTemp[5] = "zyxusqponhgedcbaLF¶";
  strWidth[5] = 7;
  strTemp[6] = "#$*+-/0123456789=?[]^_{|}vkJ†‡§";
  strWidth[6] = 6;
  strTemp[7] = "()";
  strWidth[7] = 5;
  strTemp[8] = " :;.,!\"'`rª";
  strWidth[8] = 4;
  strTemp[9] = "tljifIº·";
  strWidth[9] = 3;
  
  try {
   StringCharacterIterator sci = null;
   int ascii = 0;
   for(int i=0, s=strTemp.length; i<s; i++) {
    sci = new StringCharacterIterator(strTemp[i]);
    ascii = sci.first();
    while(ascii < 65535) {
     asciiMap.put(ascii, strWidth[i]);
     ascii = sci.next();
    }
   }
  } catch (Exception e) {
  }
 }
 
 private String subWidth(String str, int maxWidth, String tail) throws Exception {
  if (str == null || str.length() < 1) {
   return "";
  }
  if(maxWidth < 1) {
   return "";
  }
  StringCharacterIterator sci = new StringCharacterIterator(str);
  StringBuffer buffer = new StringBuffer();
  int ascii = sci.first();
  Object widthObj = null;
  int width = 0;
  while(ascii < 65535) {
   widthObj = asciiMap.get(ascii);
   if(widthObj != null) {
    width += (Integer)widthObj;
   } else {
    if(ascii > 127) {
     width += 12;
    } else {
     width += 6;
    }
   }
   
   if(width > maxWidth) {
    if(tail != null && tail.length() > 0) {
     buffer.append(tail);
    }
    break;
   } else {
    buffer.append((char)ascii);
   }
   ascii = sci.next();
  }
  return buffer.toString();
 }
 
 @Test
 public void test1() throws Exception {
  System.out.println( subWidth("대 korea", 100, "..") );
  System.out.println( subWidth("대 korea 한민국1 넘버 입니다", 100, "..") );
  System.out.println( subWidth("abcdEFASDFASDFASDFASDFADSASD", 100, "..") );
 }
 
}




Java 소스로 변환 (TagLibrary) :TagUtility.java

public static String subByte(String str, int len, String encoding) {
  try {
   if (StringUtil.isEmpty(str)) {
    return str;
   }
   byte[] strBytes = str.getBytes(encoding);
   int strLength = strBytes.length;
   int minusByteNum = 0;
   int offset = 0;
   int hangulByteNum = encoding.equals("UTF-8") ? 3 : 2;
   if (strLength > len) {
    minusByteNum = 0;
    offset = len;
    for (int j = 0; j < offset; j++) {
     if (((int) strBytes[j] & 0x80) != 0) {
      minusByteNum++;
     }
    }
    if (minusByteNum % hangulByteNum != 0) {
     offset -= minusByteNum % hangulByteNum;
    }
    return new String(strBytes, 0, offset, encoding);
   } else {
    return str;
   }
  } catch (Exception e) {
   throw new BaseException(e);
  }
 }




Byte(바이트)로 글자 자르기

출처 : http://blog.naver.com/PostView.nhn?blogId=nackhwa7&logNo=140103352320

 public static String parseStringByBytes(String str, int len, String encoding) {
  try {
   if (StringUtil.isEmpty(str)) {
    return str;
   }
   byte[] strBytes = str.getBytes(encoding);
   int strLength = strBytes.length;
   int index = 0;
   int minusByteNum = 0;
   int offset = 0;
   int hangulByteNum = encoding.equals("UTF-8") ? 3 : 2;
   if (strLength > len) {
    minusByteNum = 0;
    offset = len;
    if (index + offset > strLength) {
     offset = strLength - index;
    }
    for (int j = 0; j < offset; j++) {
     if (((int) strBytes[index + j] & 0x80) != 0) {
      minusByteNum++;
     }
    }
    if (minusByteNum % hangulByteNum != 0) {
     offset -= minusByteNum % hangulByteNum;
    }
    return new String(strBytes, index, offset, encoding);
   } else {
    return str;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 
- 원본 소스

public String[] parseStringByBytes(String raw, int len, String encoding) {
  if (raw == null)
   return null;
  String[] ary = null;
  try {
   // raw 의 byte
   byte[] rawBytes = raw.getBytes(encoding);
   int rawLength = rawBytes.length;

   int index = 0;
   int minus_byte_num = 0;
   int offset = 0;

   int hangul_byte_num = encoding.equals("UTF-8") ? 3 : 2;

   if (rawLength > len) {
    int aryLength = (rawLength / len) + (rawLength % len != 0 ? 1 : 0);
    ary = new String[aryLength];

    for (int i = 0; i < aryLength; i++) {
     minus_byte_num = 0;
     offset = len;
     if (index + offset > rawBytes.length) {
      offset = rawBytes.length - index;
     }
     for (int j = 0; j < offset; j++) {
      if (((int) rawBytes[index + j] & 0x80) != 0) {
       minus_byte_num++;
      }
     }
     if (minus_byte_num % hangul_byte_num != 0) {
      offset -= minus_byte_num % hangul_byte_num;
     }
     ary[i] = new String(rawBytes, index, offset, encoding);
     index += offset;

    }
   } else {
    ary = new String[] { raw };
   }
  } catch (Exception e) {

  }
  return ary;
 } 



 

참고 : http://ichbintaeeun.tistory.com/16

모바일, 태블릿 프로젝트를 하다보니, 변수가 이만저만이 아니다.

안드로이드, IOS 디바이스마다 맞춰주는 것이 여간 피곤한게 아니다.

이럴때보면 오히려 크로스브라우징이 그나마 나은 거구나 하는 생각이 들 정도다.


모바일에서는 체크박스나 라디오버튼의 디폴트 사이즈가 작아 터치하는데 애로사항이 있다.

그냥 width="15px";height="15px" 이렇게 css에 박아주면? 일단 갤럭시 S3에선 통과!

그런데 문제는 먹는 디바이스가 있고, 안먹는 디바이스가 있는 것이다. 한마디로 일관되게 적용되지 않는 다는 것!

그래서 보통 선택 전 이미지와 선택 후 이미지로 대체해서 퍼블리싱을 하는 경우가 많다.


대표적인 예로 다음 모바일의 로그인 페이지이다.


Daum 이용약관 동의, 개인정보 수집 및 이용 동의 체크 부분을 background 속성을 이용해서 작성되어있다.

하지만 굳이 이미지로 박지않아도, CSS를 이용해서 체크박스의 스타일을 변경할 수 있다.



HTML

<input type="checkbox" id="divECI_ISDVSAVE" class="checkbox-style" /><label for="divECI_ISDVSAVE">담당자 정보를 계속 저장</label>
    

// 반드시 input의 id와 label의 for값을 맞춰 작성해야한다.


CSS

input[type=checkbox] {  
    display: none;  
}

input[type=checkbox] + label{
    display: inline-block;  
    cursor: pointer;  
    position: relative;  
    padding-left: 25px;  
    margin-right: 15px;  
    font-size: 13px;
}

input[type=checkbox]+ label:before {     

    content: "";  
    display: inline-block;  
  
    width: 20px;  
    height: 20px;  
  
    margin-right: 10px;  
    position: absolute;  
    left: 0;  
    bottom: 1px;  
    background-color: #ccc;  
    border-radius: 2px; 
    box-shadow: inset 0px 1px 1px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);  
}
input[type=checkbox]:checked + label:before { 

    content: "\2713";  /* 체크모양 */
    text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);  
    font-size: 18px; 
    font-weight:800; 
    color: #fff;  
    background:#2f87c1;
    text-align: center;  
    line-height: 18px;  

} 

// css를 설명하자면, label 옆의 checkbox를 보이지않게 한 후, 가상요소 :before를 이용하여 체크박스자리에 원하는 모양으로 체크박스를 만들어주는 것이다.

그리고 역시 :checked를 이용하여, 체크됐을 때의 모양도 꾸며주면 끝!



참고사이트 http://www.hongkiat.com/blog/css3-checkbox-radio/


========================================================================================================


자바스크립트를 사용하지 않고 CSS로만 적용한 Checkbox, Radio Buttons

IE는 기존 체크박스, 라디오 버튼처럼 보이고 FF, Chrome 등에서 사용가능


출처 : http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/quick-tip-easy-css3-checkboxes-and-radio-buttons/

radio_checkbox_css.zip


The final result

 <!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
    </head>
    <body>
        <div id="show">
            <h1>Easy CSS3 Checkboxes and Radio Buttons</h1>
            <input type="checkbox" id="c1" name="cc" />
            <label for="c1"><span></span>Check Box 1</label>
            <p>
            <input type="checkbox" id="c2" name="cc" />
            <label for="c2"><span></span>Check Box 2</label>
            <p><br/>
            <input type="radio" id="r1" name="rr" />
            <label for="r1"><span></span>Radio Button 1</label>
            <p>
            <input type="radio" id="r2" name="rr" />
            <label for="r2"><span></span>Radio Button 2</label>
        </div>
    </body>
</html>

 

+ Recent posts