2019年3月27日 星期三

Lombok 的使用

lombok 有很多註解,可以節省代碼,方便開發,但使用 Lombok 時,IDE 必須設定,否則編譯會過,但沒有效果(叫出 outline 活頁標籤可知道)


※Eclipse

maven:
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.6</version>
    <scope>provided</scope>
</dependency>
    
    
    
gradle:
provided group: 'org.projectlombok', name: 'lombok', version: '1.18.6'




maven 或 gradle 下載後,注意下載的位置

找到 jar 檔後,點兩下打開,然後 install/update,但安裝完成也沒提示,重啟 eclipse 才可以

可參考 官方文檔,比較重要的幾乎都在 lombok 包中

@Getter:可寫在 field 和 type,寫在 field 表示生成 getter;寫在 type 表示為所有 field 生成 getter
@Setter:可寫在 field 和 type,寫在 field 表示生成 setter;寫在 type 表示為所有 field 生成 setter
@RequiredArgsConstructor:只能寫在 type,如果有 final 欄位,建構子就必須要加,如果有多個 final 欄位,依寫的順序;都沒有 final 欄位,就等於空的建構子,不能與 @NoArgsConstructor 一起使用
@ToString:只能寫在 type,預設格式是「類名(欄位一=值, 欄位二=值…)」
@EqualsAndHashCode:生成 equals(Object)、hashCode()、canEqual(Object) 三個方法
@Data:以上五個註解合起來

@AllArgsConstructor:只能寫在 type,生成全部 field 的建構子,順序以寫的先後為主
@NoArgsConstructor:只能寫在 type,生成無參數的建構子,不能與@RequiredArgsConstructor 一起使用
@Accessors(chain=true):使用 setter 時,可以一直 set,這個和上面幾個註解是不同的包



※Intellij

1.Settings/Plugins 搜尋 lombok 並安裝好後重啟 Intellij
2.
3.增加 maven 或 gradle jar 檔

2019年3月16日 星期六

農曆年與天干地支轉換

<html>
    <head>
        <title>農曆年與天干地支轉換程式</title>
        <script>
            /**
            *    民國13年為甲子年,並不是民國1年為甲子年
            */
            window.onload = function() {
                document.getElementById('sl').checked = false;
            }
    
            var sky = ["", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
            var land = ["", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
            
            function sWord() {
                let sw = sky[document.getElementById('s').value];
                document.getElementById('sWord').innerText = typeof sw != 'undefined' ? sw : '';
            }
    
            function lWord() {
                let lw = land[document.getElementById('l').value];
                document.getElementById('lWord').innerText = typeof lw != 'undefined' ? lw : '';
            }
    
            /**
            *    勾選天干地支的顯示隱藏
            */
            function slCheck() {
                let sl = document.getElementById('sl').checked;
                let slView = document.getElementById('slView');
                let lunarSolarYear = document.getElementById('lunarSolarYear');
    
                if(sl) {
                    slView.style.display = 'block';
                    lunarSolarYear.style.display = 'none';
                    sWord();
                    lWord();
                } else {
                    slView.style.display = 'none';
                    lunarSolarYear.style.display = 'block';
                }
            }
    
            function display() {
                var num = document.getElementById('num').value;
                var sl = document.getElementById('sl').checked;
    
                if(!sl) {
                    // 農曆年轉天干地支
                    if(num <= 0) {
                        alert('請輸入正確的農曆年');
                        return;
                    }
                    if(num.length > 3) {
                        alert('輸入的農曆年不可超過千年');
                        return;
                    }
    
                    num = subtract60(num);
                    if(num.length == 1) num = '0' + num;
                    var skyResult = Number(num[1])-2 <= 0 ? sky[Number(num[1])+10-2]: sky[Number(num[1])-2];
                    alert(skyResult + land[getLandWord(Number(num))] + '年');
                } else {
                    // 天干地支轉農曆年
                    var s = document.getElementById('s').value;
                    var l = document.getElementById('l').value;
    
                    if(s > 10 || s <= 0) {
                        alert('天干必須在1~10之間');
                        return;
                    }
                    if(l > 12 || l <= 0) {
                        alert('地支必須在1~12之間');
                        return;
                    }
                    if((s % 2 == 1 && l % 2 == 0) || (s % 2 == 0 && l % 2 == 1)) {
                        alert('不正確的天干地支組合');
                        return;
                    }
    
                    var skyResult = Number(s) + 2;
                    if(skyResult >= 10) skyResult = skyResult - 10;
                    if(l.length == 1) l = '0' + l;
                    alert('農曆年為:' + getLandNumber(skyResult, l) + ' (或加減 60 的倍數)');
                }
            }
    
            /**
            *    取得地支數字
            */
            function getLandNumber(sky, land) {
                if(land.toString()[1] != sky) {
                    land = Number(land) + 12;
                    land = getLandNumber(sky, land)
                }
                return Number(land);
            }
    
            /**
            *    取得地支文字
            */
            function getLandWord(n){
                if(n>12) n = getLandWord(n-12);
                return n;
            }
    
            /**
            *    將農曆年縮小到60年之內
            */
            function subtract60(n){
                if(n>60) n = subtract60(n-60);
                return n.toString();
            }
        </script>
    </head>
    
    <body>
        <h1>農曆年與天干地支轉換程式</h1>
    
        是否使用天干地支轉農曆年<input type="checkbox" id="sl" onclick="slCheck()"><br />
        <span id='lunarSolarYear'>請輸入農曆年:
            <input type="number" id="num" style="width:70px" min='1' max='999' /><br />
        </span>
        <div id="slView" style='display:none'>
            請輸入天干:<input type="number" id="s" style="width:70px" min='1' max='10' onchange="sWord()" />
            <span id="sWord" style='color:blue'></span><br />
            請輸入地支:<input type="number" id="l" style="width:70px" min='1' max='12' onchange="lWord()" />
            <span id="lWord" style='color:blue'></span><br />
            1=甲, 2=乙, 3=丙, 4=丁, 5=戊, 6=己, 7=庚, 8=辛, 9=壬, 10=癸<br />
            1=子, 2=丑, 3=寅, 4=卯, 5=辰, 6=巳, 7=午, 8=未, 9=申, 10=酉, 11=戌, 12=亥<br />
        </div>
        <input type="button" value="確定" onclick="display()" />
    </body>
</html>

※農曆(陰陽合曆)13、73年為甲子年

※農曆年轉天干地支:個位數-2為天干,一直減到12之內為地支

※天干地支轉農曆年: 天干+2為個位數,地支較麻煩,以戊戌年來說
戊為5,加2為7,所以個位數為7
戌為11,11加多少的個位數會是7(天干的結果),必須加6才行,但還必須是12的倍數才行,60以下12的倍數有12、24、36、48,所以只有36,結果為11+36=47

2019年3月14日 星期四

Transaction (Spring 4.x 三)


<context:annotation-config />
<context:component-scan base-package="bean, dao, service" />
    
<bean id="ds"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="oracle.jdbc.driver.OracleDriver"
    p:url="jdbc:oracle:thin:@127.0.0.1:1521:orcl" p:username="user-name"
    p:password="password" />
    
<bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate"
    p:dataSource-ref="ds" />
    
<bean id="txm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="ds" />
</bean>
    
<tx:annotation-driven transaction-manager="txm"/>

※事務在第3版就有了,更之前的版本我不知道有沒有,寫在 4 並不代表 4 才有

※@Transaction 要配合<tx:annotation driven transaction-manager="" />,且只能使用在 public,否則不啟作用,也不報錯

※在這裡已經設定 JdbcTemplate,如果在下SQL時,自己用 DriverManagerDataSource 取得 JdbcTemplate 也是不啟作用的

※@Transaction 有個屬性 rollbackFor,不設定時為所有例外都會 rollback,如設定 RuntimeException.class,那只有 RuntimeException 時才會 rollback

※還有一些陷阱,高手已經寫好,可參考看看