歡迎光臨
每天分享高質量文章

Java Web技術經驗總結(五)

  1. ViewResolver體系:大部分的ViewResolver實現類,除了BeanNameViewResolverContentNegotiatingViewResolver會直接實現ViewResolver接口,都會直接或間接繼承AbstractCachingViewResolver,如下圖所示: 

  2. BeanNameViewResolver的工作原理是:當Controller中的請求處理方法傳回content字串時,就會在web背景關係中查找id為”content”的view bean,然後用該view渲染模型中的資料,該ViewResolver的使用場景不多,因為我們一般傾向於將Controller與View解耦合。

  3. String中的compareTo方法:傳回值是整型,它是先比較對應字符的大小(ASCII碼順序),如果第一個字符和引數的第一個字符不等,結束比較,傳回他們之間的差值,如果第一個字符和引數的第一個字符相等,則以第二個字符和引數的第二個字符做比較,以此類推,直至比較的字符或被比較的字符有一方全比較完,這時就比較字符的長度。 “` package com.javadu.strings; /** * Created by duqi on 16/6/2. */ public class StringExample { public static void main(String[] args) { String str1 = “abcde”; String str2 = “cbdef”; String str3 = “abcdef”;

    System.out.println(str1.compareTo(str2)); //比較ASICC碼的值: 'a'為97,'c'為99
    System.out.println(str1.compareTo(str3)); //比較長度
    System.out.println(str2.compareTo(str3)); //比較ASICC

    } } “`

  4. Spring + Spring MVC + MyBatis組合是現在J2EE開發常用的組合,MyBatis的常用配置包括以下幾個方面:

  • MyBatis的使用應該重點關註SQL陳述句的位置,即SqlSessionFactionBean如何為DAO創建代理、如何找到對應的SQL陳述句。一般而言,SQL陳述句寫在XML檔案中(
    ),sqlSessionFactionBean的mapperLocations屬性設這些mapper檔案的位置;

  • 在mybatis-spring 1.3以後,也支持在DAO接口的方法上利用註解標註對應的SQL陳述句

  • 只要涉及到字串,就要明確該字串用什麼編碼,要顯式指明!不要相信預設值,例如:IOUtils.toString(in);這麼用就可能有問題,你跟蹤這個toString()的實現可以看到:public static String toString(InputStream input) throws IOException { return toString(input, Charset.defaultCharset()); }但是,這個Charset.defaultCharset()再跟進去,可以看到:/** * Returns the default charset of this Java virtual machine. * *

    The default charset is determined during virtual-machine startup and * typically depends upon the locale and charset of the underlying * operating system. * * @return A charset object for the default charset * * @since 1.5 */ public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { String csn = AccessController.doPrivileged( new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else defaultCharset = forName("UTF-8"); } } return defaultCharset; }

    按照註釋中的說法,字符編碼取決於JVM啟動引數、Locale和底層的系統編碼,因此我再回去看我的JVM的啟動引數(命令:ps -ef | grep java): -Dfile.encoding=GB18030 好吧,因此回到開頭,這個函式的正確用法是:IOUtils.toString(in, Charset.forName("UTF-8"));

  • ThreadLocal的設計理念與作用

    • ThreadLocal的作用是提供執行緒內的區域性變數,在多執行緒環境下訪問時能保證各個執行緒內的ThreadLocal變數各自獨立。

    • 在多執行緒環境下,多個執行緒經常需要共同訪問同一個變數,那麼如何保證多執行緒訪問共享變數的正確性就是我們的首要目的。為了實現這個目的,我們有兩種實現策略:

    • 使用同步(synchronization)的方式來管理多執行緒對共享變數的訪問;

    • 通過避免物件的共享來實現執行緒安全,也就是這裡的ThreadLocal變數。

  • 給List集合中的物件按照某個欄位排序,如何實現? 將指定的類實現Comparable接口,並實現compareTo方法;利用Collections.sort(dataList)進行排序:package com.javadu.collections; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ListSort { public static void main(String[] args) { List calllogNumberOutgoingCounts = new ArrayList(); calllogNumberOutgoingCounts.add(new CalllogNumberOutgoingCount("111", 2)); calllogNumberOutgoingCounts.add(new CalllogNumberOutgoingCount("222", 3)); calllogNumberOutgoingCounts.add(new CalllogNumberOutgoingCount("333", 19)); System.out.println("before sort:"); for (CalllogNumberOutgoingCount bean : calllogNumberOutgoingCounts) { System.out.println("number: " + bean.getNumber()); } Collections.sort(calllogNumberOutgoingCounts); System.out.println("after sort:"); for (CalllogNumberOutgoingCount bean : calllogNumberOutgoingCounts) { System.out.println("number: " + bean.getNumber()); } } } class CalllogNumberOutgoingCount implements Comparable { private String number; private Integer outgoingCount; public CalllogNumberOutgoingCount(String number, Integer outgoingCount) { this.number = number; this.outgoingCount = outgoingCount; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public Integer getOutgoingCount() { return outgoingCount; } public void setOutgoingCount(Integer outgoingCount) { this.outgoingCount = outgoingCount; } //o的outgoing_count小於this的對應欄位,則傳回負數;大於則傳回正數;在這裡懶得瞭解背後的原理的話,則可以嘗試下結果即可。 public int compareTo(CalllogNumberOutgoingCount o) { return o.getOutgoingCount().compareTo(this.getOutgoingCount()); } }

  • 資料庫查詢,SQL調優原則

    • 增大分批查詢的每批數量(也不是越大越好),MySQL一般在1000左右是最佳資料;

    • 利用多表連接查詢,不同情況下應該用不同的連接查詢,參考SQL的幾種連接:內連接、左聯接、右連接、全連接、交叉連接

    • 正確使用索引,避免全表掃描

    • 保證邏輯正確;

    • 減少資料庫查詢次數;

    • 簡化SQL陳述句,儘量將複雜SQL用記憶體操作代替;

  • MyBatis的insert陳述句,如何傳回剛剛插入的記錄的主鍵? 通過陳述句,根據官方文件:“keyProperty表示selectKey陳述句應該設置的標的屬性。”例子如下所示,該陳述句的執行結果,將會把新插入記錄的id值賦值給bean物件。 select last_insert_id() as id INSERT INTO examples (name,reject,ask,source,ctime,mtime) VALUES (#{name},#{reject},#{ask},#{source},now(),now())

  • 給List集合中的物件按照某個欄位去重,如何實現? 利用TreeSet,併為TreeSet中的物件定義對應的Comparator。

  • package com.javadu.collections;
    import java.util.*;
    public class ListQuchong {
        public static void main(String[] args) {
            List userList = new ArrayList<>();
            User user1 = new User("duqi", "456");
            userList.add(user1);
            User user2 = new User("temp", "456");
            userList.add(user2);
            User user3 = new User("dddd", "234");
            userList.add(user3);
            for (User u : userList) {
                System.out.println(u.getName());
            }
            List userListNoDupAndSort = removeDuplicateUser(userList);
            for (User u : userListNoDupAndSort) {
                System.out.println(u.getName());
            }
        }
        private static ArrayList removeDuplicateUser(List users) {
            Set set = new TreeSet<>(new Comparator() {
                @Override
                public int compare(User o1, User o2) {
                    return o1.getUserId().compareTo(o2.getUserId()); //字串,則按照asicc碼升序排列
                }
            });
            set.addAll(users);
            return new ArrayList<>(set);
        }
    }
    class User {
        private String name;
        private String userId;
    
        public User(String name, String userId) {
            this.name = name;
            this.userId = userId;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    }

    赞(0)

    分享創造快樂