顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2017年3月16日 星期四

Why 『Map<> = new HashMap()』 not 『HashMap<> = new HashMap()』

Reason
1.less typing
2.more flexible.

For example:
You can see the image below, use Map<> = new HashMap() can easily change HashMap to TreeMap

2017年2月5日 星期日

用 cmd (命令列) 執行java程式

參考
https://caterpillar.gitbooks.io/javase6tutorial/content/c2_2.html

1.環境設定
設定 Path 變數是為了讓作業系統找到指定的工具程式(以 Windows 來說的話就是找到 .exe 檔案),則設定 Classpath 的目的就是為了讓Java執行環境找到指定的 Java 程式(也就是.class檔案)。

-設定path(jdk路徑)
-設定classpath(之後要去哪裡找class檔)

方法一
最簡單的方法是在系統變數中新增 Classpath 環境變數,在上圖中的「系統變數」按下「新增」鈕,在「變數名稱」欄位中輸入「Classpath」,在「變數值」欄位中輸入 Java 類別檔案的位置,例如可以輸入「.;C:\Program Files\Java\jdk1.6.0\ lib\tools.jar; C:\Program Files\Java\jre1.6.0\lib\rt.jar」(jar 檔是 zip 壓縮格式,當中就包括了 .class 檔案以及 jar 中的 Classpath 設定),每一筆資料中間必須以「;」作為分隔。

方法二
使用的 JDK 工具程式有 Classpath 指令選項,在執行工具程式時一併指定 Classpath:

javac -classpath classpath1;classpath2 …

方法三
在文字模式下執行以下的指令,以直接設定目前的環境變數包括 Classpath 變數(這個設定在下次重新開啟文字模式時就不再有效):

set CLASSPATH=.;classpath1;classpath2

重點觀念:
少了 < .; > 會造成執行正確和錯誤的強烈差距
『.』這個小細節是有一些原因的.
在沒有做任何設定之下 , 預設的CLASSPATH就是一個『.』
這個『.』代表 命令提示字元的當前目錄
沒設定比設定錯誤還好一點點(對新手而言) , 只要 .class 在當前目錄 , 你還是可以執行程式

但是你若下了設定 
SET CLASSPATH=C:\j2sdk1.4.1_03\lib;C:\j2sdk1.4.1_03\lib\tools.jar;
少了這個. 若你當前的目錄卻不是 C:\j2sdk1.4.1_03\lib , 就會發生NoClassDefFoundError

正確的設定
SET CLASSPATH=.;C:\j2sdk1.4.1_03\lib;C:\j2sdk1.4.1_03\lib\tools.jar;

1.表示當前的目錄 , 
2.C:\j2sdk1.4.1_03\lib\ , 
3.以及 tools.jar 內的class都可以載入 


2.範例
a.撰寫java程式(帶有package test; → 之後執行時,路徑要特別注意)

b.進行編譯javac (順便指定classpath)
javac -classpath C:\Users\ytchen\Desktop\test test6.java

c.執行class檔
路徑:C:\Users\ytchen\Desktop\test>
命令:java test6
若是在程式碼中,有設定package的情況下,路徑要修改,否則會找不到檔案
(程式會去找test\test\test6)

所以要往上一層
並且利用『.』的方式,設定目錄,告知檔案在哪
路徑:C:\Users\ytchen\Desktop>
命令:java test.test6




2016年12月15日 星期四

Hibernate HQL - DML、DQL、JOIN 範例

HQL
-Select 
1.利用 ? 設定 sql 中的參數,搭配 query.setParameter("第幾個問號",變數);
Session session = BackendHibernateUtil.getSession();
List resultList = new LinkedList<>();
try {
     Query query = session.createQuery("FROM CtrlSourceAreaEntity WHERE source_type = ?");
     query.setParameter(0,sourceType);
     resultList = query.list();
} catch (HibernateException e) {
     log.error("XMLParserDAO @querySourceAreaId Fail:", e);
} finally {
     session.close();
}
return resultList;
2.利用 :Name 設定參數
"FROM CtrlSourceAreaEntity WHERE source_type = :sourceType"
 query.setParameter("sourceType",sourceType);

3.SQL Query In 設定參數
Query query = session.createQuery("FROM ScheduleDownloadEntity WHERE status in (:statusNames)  ORDER BY create_time ");
query.setParameterList("statusNames", statusList);
resultList = query.list();

-Update
1.executeUpdate()是執行DML的意思
 Query query = session.createQuery("UPDATE UserAccountEntity SET password = ? where f_service = ? AND account = ? AND user_email = ?");
 query.setParameter(0, userPasswordMD5);
 query.setParameter(1, serviceId);
 query.setParameter(2, account);
 query.setParameter(3, emailAddress);
 query.executeUpdate(); //這句是commit的意思

-Delete
1.executeUpdate() 是執行DML的意思

2.executeUpdate() 會傳回 int 影響的資料筆數
Query query = session.createQuery("DELETE EdititemEntity WHERE kind = ? AND post_time BETWEEN  ? AND ? ");
query.setParameter(0, taskNumber);
query.setParameter(1, startDate);
query.setParameter(2, endDate);
int resultCount = query.executeUpdate(); //可以取得DML影響的資料筆數

-Insert
1.將傳進來的 entity 實體 透過 session.save() 的方式把資料存進DB
public void insertData(EdititemEntity edititemEntity) {
Session session = Opv_lyHibernateUtil.getSession(); //Hibernate Session Connect
Transaction tx = session.beginTransaction(); //一組交易
try {
     session.save(edititemEntity); //將傳進來的Entity存進DB(透過Hibernate專屬方法)
     tx.commit(); //交易確認
} catch (HibernateException e) {
     tx.rollback(); //交易取消
     log.error("CategoryDAO @insertData Fail,newsId={},error={}", edititemEntity.getId(), e);
} finally {
     session.close();
}
}

HQL-Join

參考:
http://openhome.cc/Gossip/HibernateGossip/ManyToOne.html

多對一:
一個簡單的實體與實體間之關係為『多對一』的關係,例如『使用者』與『房間』的關係就是多對一的關係,多個使用者使用同一房間。

範例目標:

A:每個 user 有特定的 serviceId(f_service) ,多個user會對上同一個serviceId,希望透過HQL的方式,取得user時,順便取得service_account




1.實體設定(UserAccountEntity)

-在多對一的情況下,『多』的實體才需要特別設定,『一』的部份不用調整,因此我們只調整UserAccount
-UserAccountEntity.class
UserAccountEntity類別中有一serviceAccountEntity屬性,將參考至serviceAccountEntity實例,多個User實例可共同參考一個service實例











2.設定檔(UserAccountEntity.hbm.xml)
- class="絕對路徑""
- column="f_service" → userAccount的f_service(FK)會去參考到serviceAccount的id(PK),兩張table才會連結在一起
- cascade表示主控方(User)進行save-pdate、delete等 相關操作時,被控 方(Room)是否也一併進行相關操作,簡單的說,也就是您儲存或更新User實例時,被參考到的Room實例是否一併對資料庫發生儲存或操作,設定為 all,表示主控方任何操作,被控方也進行對應操作。

-把原先的fService先註解掉



-設定mana-to-one的參數















3.查詢結果
- 重要:INNER JOIN 是 userAccount實體中的serviceAccount屬性




- 結果
每個傳回的結果都帶有UserAccountEntity & ServiceAccountEntity

2016年11月7日 星期一

建構子Construct 對 靜態變數 static & 實體變數 instance 操作

1.實作


public class TestClass {
    public String instancePath ;   //實例變數 (需要new出物件才能使用)
    public static String staticPath ; //靜態變數 (類別名稱.變數名稱 即可使用)

    /**
     * Construct
     * @param path 路徑
     */
    public TestClass (String path) {
        this.instancePath = path;
        this.staticPath = path;
    }

    public String getInstancePath () {
        instancePath = "i am instancePath"; //實體被改掉,後面再取會不一樣
        return instancePath;
    }

    public String getStaticPath () {
        staticPath = "i am staticPath";
        return staticPath;
    }
}
public class MainClass {
    public static void main(String[] args) {
        TestClass testClass = new TestClass("c://");

        System.out.println(testClass.instancePath); //一開始取到『建構子』給的值
        System.out.println(testClass.getInstancePath()); //後面方法裡值被修改掉

        System.out.println(TestClass.staticPath); //透過類別方法.變數方法即可取用
        System.out.println(testClass.getStaticPath()); //
    }
}

2.Console

2016年10月18日 星期二

Log4j Java 使用xml設定檔

環境
-Intelj13
-log4j1.2.17

範例實作
1.匯入lo4j jar檔







2.建立log4j.xml 設定檔
- 設定檔名稱『一定要叫log4j』,否則系統會抓取不到
- 開頭前2行做為log4j設定檔的宣告
- 所有設定放在log4j:configuration中
- 放在專案src下方









<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">  <!--宣告log4j.xml的文件型別定義(Document Type Definition, DTD)-->

<!--所有log4j的設定都必須放在 <log4j:configuration>...</log4j:configuration>之內 -->
<log4j:configuration>
</log4j:configuration>

3.Log要輸出到哪裡??要長甚麼樣子??,appender設定
(放在
log4j:configuration中)

- Append 定義 log message 『輸出的裝置』及 『log 內容格式』
- log4j.xml 可以設定多個append
    <appender name="Console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout"> <!-- 設定appender的layout為PatternLayout -->
            <!-- 設定layout的pattern,參數名為conversionPattern,value為想要的輸出格式 -->
            <param name="conversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss} [%C{5}]-[%p] %m%n"/>
        </layout>
    </appender>
    <!-- DailyRollingFileAppender的第一個log檔並不會加上DatePattern的樣式,
                     必須在下一次週期產生的log檔才會加上DatePattern的樣式。
                     所以基本上當天產生的log檔算是第一次的log檔,並不會加上Pattern樣式-->

    <appender name="File" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="D:\system_notice.txt" /> <!--檔案路徑-->
        <!--DatePattern是DailyRollingFileAppender的一個重要參數,用來設定檔案輸出的週期-->
        <param name="DatePattern" value="'.'yyyy-MM-dd-HH'.log'" />  
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%C{5}]-[%p] %m%n" />
        </layout>
    </appender>
4.檔案與Log設定的配對(本範例有三種) logger設定(放在log4j:configuration中)
- 補充-概念等於希望把log印出至console也要同時輸出至檔案
<appender-ref ref="Console"/>
<appender-ref ref="File"/> 
- 全專案套用
- 某個資料夾全部套用
- 指定要使用哪個Logger
    <!--RootLogger(全專案套用)-->
    <!--rootLogger的LEVEL設定為DEBUG,DEBUG以上等級的資訊也都會寫出-->
    <!--主要class搭配:public static Logger logger = Logger.getLogger(MyPractice.class);-->
    <root>
    <priority value="DEBUG"/> <!--印出INFO以上的資訊-->
    <appender-ref ref="Console"/> <!--將rootLogger的appender參考至剛設定好的Console appender-->
    <appender-ref ref="File"/> <!--將rootLogger的appender參考至剛設定好的File appender-->
    </root>
    <!--整個資料夾套用-->
    <!--main class搭配:public static Logger logger = Logger.getLogger("MyPractice.class");-->
    <logger name="MyTest"> <!--指定的資料夾-->
        <level value="ERROR"/> <!--印出ERROR以上的資訊-->
        <appender-ref ref="Console"/> <!--將rootLogger的appender參考至剛設定好的Console appender-->
        <appender-ref ref="File"/> <!--將rootLogger的appender參考至剛設定好的File appender-->
    </logger>
    <!--指定要哪個Logger設定-->
    <!--class搭配:public static Logger logger = Logger.getLogger("aa");-->
    <logger name="aa"> //替logger取名稱
    <level value="INFO"/> <!--印出INFO以上的資訊-->
    <appender-ref ref="Console"/> <!--將rootLogger的appender參考至剛設定好的Console appender-->
    <appender-ref ref="File"/>    <!--將rootLogger的appender參考至剛設定好的File appender-->
    </logger>
5.Java檔實際執行記錄
public class MyPractice{
    public static Logger logger = Logger.getLogger(MyPractice.class);
    public static Logger logger2 = Logger.getLogger("aa");
    public static void main(String[] args) {
        int num = 0;
        try {
            System.out.println(num/0);
        } catch (Exception e) {
            System.out.println(e);
            logger.debug("Here is some DEBUG");
            logger.info("Here is some INFO");
            logger.warn("Here is some WARN");
            logger.error("Here is some ERROR");
            logger.fatal("Here is some FATAL");
            logger2.debug("Here is some aa logger");
            logger2.info("Here is some aa logger");
        }
    }
}

2016年10月10日 星期一

String VS. StringBuffer VS. StringBuilder

1.參考來源:
- http://blog.xuite.net/jane17512001/PenguinDesign/116288109-%E5%AD%97%E4%B8%B2%E8%99%95%E7%90%86(String%E3%80%81StringBuilder%E3%80%81StringBuffer)

- http://puremonkey2010.blogspot.tw/2011/11/java-string-stringbuffer-stringbuilder.html

2.特性介紹:
- String
每次對 String 類型進行改變的時候其實都等同於生成了一個新的 String 對象,然後將指針指向新的 String 對象,所以經常改變內容的字符串最好不要用 String ,因為每次生成對像都會對系統性能產生影響

- StringBuffer
每次結果都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,再改變對象引用。所以在一般情況下我們推薦使用 StringBuffer 
(Java.lang.StringBuffer 可將字符串緩衝區安全地用於多個線程。可以在必要時對這些方法進行同步)

-StringBuilder
從 JDK 5.0 開始,為該類增添了一個單個線程使用的等價類,即 StringBuilder 。與 StringBuffer 相比,通常應該優先使用 StringBuilder 類,因為它支持所有相同的操作,但由於它不執行同步,所以速度更快!

3.結論(效率)
1.在大部分情況下 StringBuffer > String 
例外情況:
- String 較快
String S1 = "This is only a" + "simple" + "test";  
- String 較慢
String S2 = "This is only a";  
String S3 = "simple";  
String S4 = "test";  
String S1 = S2 +S3 + S4;

2.在不考慮多執行緒的情況下 StringBuilder > StringBuffer ,因為它支持所有相同的操作,但由於它不執行同步,所以速度更快!

2016年9月30日 星期五

利用 bat (批次檔) 執行java程式 (待補充..)

參考:
http://oldwuwu.blogspot.tw/2013/05/batjava.html

1.一隻簡單的JAVA程式








2.一隻.bat檔(用記事本寫即可)

SET PATH=C:\Program Files\Java\jdk1.6.0_27\bin  (JDK的位置)
javac xxxxx.java   (要進行編譯的xxxx.java檔)
java xxxxx  (同上編譯過後的class檔)
pause  (執行完後,讓命令提示字元畫面停留在螢幕上)




















3.將兩隻檔案放在同一個資料夾










4.點擊『testBat.bat』批次檔,即可看到成果










2016年9月5日 星期一

Intellj Java Command Line (命令列參數) 使用

1.注意:
- command line 參數以『String [ ]』的方式存放,所以也要用同樣方式『接』
- command line 參數,『最先進入』的地方是『main方法』

2.範例:
a. Intellj 輸入指令 ( Program arguments: Ian Lillian)(指令間用空白隔開)








b.main方法,透過String[] 接到參數













c.看結果












3.補充-cmd 如何帶參數
- command line 輸入指令(帶在要執行的檔案後面)
- 執行前需要先進行javac 編譯
- javac test.java
- 執行java檔


2016年8月16日 星期二

Constructor 建構子 - 初始化應用

1.ConstructorTest.java

有設定『建構子』的class,當該物件被建立(初始化時),建構子(某種特殊的方法)會被自動執行
因此某些『需要初始化的設定』可以寫在建構子內











2.ConstructorTestMain.java
(補充:可以把此main方法寫在 ConstructorTest.java 裡面也行,但記得要設成『靜態方法』同一個類別中,才能直接取用)












3.Result



2016年8月4日 星期四

Generies 泛型

簡易的泛型範例

-泛型參數,不能放『八大基本型態』

-Java 7.0之後允許ClassA<foo> gf = new ClassA<>();

-<T extends Parent> 設定泛型的上限
  表示傳入的類別參數,必為Parent類別或其子類別,其他類別不能亂入


-靜態方法不能是泛型,因為靜態方法不用new


1.Gen.java



































2.GenDemo























3.Result
















4.泛型方法

2016年8月2日 星期二

Java - enum 類別

1.何謂enum?
enum定義的xxxx實際上是個類別

2.為何要有enum?
在interface中,可以定義常數。例如:
public interface Action {
    public static final int STOP = 0;
    public static final int RIGHT = 1;
    public static final int LEFT = 2;
    public static final int UP = 3;
    public static final int DOWN = 4;
} 
但後面在取用時只能透過Action.STOP這種方式取,但其實不易讀 之後發展出enum,使用起來更為方便

3.實際應用

例子1

public class  test {

    //設定建構子
    public enum Level {
        DOWNLOAD_QUANTITY(0, "AA"),
        DOWNLOAD_CONTENT(1, "BB"),
        KEYWORD_LENGTH(2, "CC"),
        STANDARD_PLATFORM_LOGIN(3, "登入"),
        EDUCATION_VIEW(4, "DD");

        private int mode;
        private String Name;

        private Level(int mode, String Name) {
            this.mode = mode;
            this.Name = Name;
        }
    }

    //執行程式(提示:Level.STANDARD_PLATFORM_LOGIN 等於把STANDARD_PLATFORM_LOGIN常數的值塞入建構子內)
    public static void main(String[] args) {
        int n = Level.STANDARD_PLATFORM_LOGIN.mode;
        String s = Level.STANDARD_PLATFORM_LOGIN.Name;
        System.out.println(n); //3
        System.out.println(s); //登入
    }

}
例子2