extend:http://www.jianshu.com/p/bef0e52067d2html
Redis存儲機制分紅兩種Snapshot 和 AOF。不管是那種機制,Redis都是將數據存儲在內存中。java
Snapshot工做原理: 是將數據先存儲在內存,而後當數據累計達到某些設定的伐值的時候,就會觸發一次DUMP操做,將變化的數據一次性寫入數據文件(RDB文件)。mysql
AOF 工做原理 : 是將數據也是先存在內存,可是在存儲的時候會使用調用fsync來完成對本次寫操做的日誌記錄,這個日誌揭露文件實際上是一個基於Redis網絡交互協議的文本文件。AOF調用fsync也不是說所有都是無阻塞的,在某些系統上可能出現fsync阻塞進程的狀況,對於這種狀況能夠經過配置修改,但默認狀況不要修改。AOF最關鍵的配置就是關於調用fsync追加日誌文件的平率,有兩種預設頻率,always每次記錄進來都添加,everysecond 每秒添加一次。兩個配置各有所長後面分析。因爲是採用日誌追加的方式來持久話數據,因此引出了第二個日誌的概念:rewrite. 後面介紹它的由來。redis
1.性能:Snapshot方式的性能是要明顯高於AOF方式的,緣由有兩點:sql
Snapshot採用2進制方式存儲數據,數據文件比較小,加載快速.
存儲的時候是按照配置中的save策略來存儲,每次都是聚合不少數據批量存儲,寫入的效率很好數據庫
而AOF則通常都是工做在實時存儲或者準實時模式下。相對來講存儲的頻率高,效率卻偏低。緩存
2.數據安全:AOL數據安全性高於Snapshot存儲,緣由:安全
Snapshot存儲是基於累計批量的思想,也就是說在容許的狀況下,累計的數據越多那麼寫入效率也就越高,但數據的累計是靠時間的積累完成的,那麼若是在長時間數據不寫入RDB,但Redis又遇到了崩潰,那麼沒有寫入的數據就沒法恢復了,可是AOF方式恰恰相反,根據AOF配置的存儲頻率的策略能夠作到最少的數據丟失和較高的數據恢復能力。
說完了性能和安全,這裏不得不提的就是在Redis中的Rewrite的功能,AOF的存儲是按照記錄日誌的方式去工做的,那麼成千上萬的數據插入必然致使日誌文件的擴大,Redis這個時候會根據配置合理觸發Rewrite操做,所謂Rewrite就是將日誌文件中的全部數據都從新寫到另一個新的日誌文件中,可是不一樣的是,對於老日誌文件中對於Key的屢次操做,只保留最終的值的那次操做記錄到日誌文件中,從而縮小日誌文件的大小。這裏有兩個配置須要注意:網絡
auto-aof-rewrite-percentage 100 (當前寫入日誌文件的大小佔到初始日誌文件大小的某個百分比時觸發Rewrite)
auto-aof-rewrite-min-size 64mb (本次Rewrite最小的寫入數據良)session
兩個條件須要同時知足。
Redis不支持Java的HashMap,Redis有本身的數據結構
但可使用Jedis (Jedis是redis的java版本的客戶端實現) 來處理HashMap
/** * redis操做Map */ @Test public void testMap() { //-----添加數據---------- Map<String, String> map = new HashMap<String, String>(); map.put("name", "xinxin"); map.put("age", "22"); map.put("qq", "123456"); jedis.hmset("user",map); //取出user中的name,執行結果:[minxr]-->注意結果是一個泛型的List //第一個參數是存入redis中map對象的key,後面跟的是放入map中的對象的key,後面的key能夠跟多個,是可變參數 List<String> rsmap = jedis.hmget("user", "name", "age", "qq"); System.out.println(rsmap); //刪除map中的某個鍵值 jedis.hdel("user","age"); System.out.println(jedis.hmget("user", "age")); //由於刪除了,因此返回的是null System.out.println(jedis.hlen("user")); //返回key爲user的鍵中存放的值的個數2 System.out.println(jedis.exists("user"));//是否存在key爲user的記錄 返回true System.out.println(jedis.hkeys("user"));//返回map對象中的全部key System.out.println(jedis.hvals("user"));//返回map對象中的全部value Iterator<String> iter=jedis.hkeys("user").iterator(); while (iter.hasNext()){ String key = iter.next(); System.out.println(key+":"+jedis.hmget("user",key)); } }
Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲;
Redis支持數據的備份,即master-slave模式的數據備份。
Redis支持數據的持久化。
Redis在不少方面支持數據庫的特性,能夠這樣說他就是一個數據庫系統,而memcached只是簡單地K/V緩存。
它們在性能方面差異不是很大,讀取方面尤爲是針對批量讀取性能方面memcached佔據優點。固然redis也有他的優勢,如持久性、支持更多的數據結構。
Redis和Memcache都是將數據存放在內存中,都是內存數據庫。不過memcache還可用於緩存其餘東西,例如圖片、視頻等等;
虛擬內存--Redis當物理內存用完時,能夠將一些好久沒用到的value 交換到磁盤;
過時策略--memcache在set時就指定,例如set key1 0 0 8,即永不過時。Redis能夠經過例如expire 設定,例如expire name 10;
分佈式--設定memcache集羣,利用magent作一主多從; redis能夠作一主多從。均可以一主一從;
存儲數據安全--memcache掛掉後,數據不可恢復;redis能夠按期保存到磁盤(持久化),數據丟失後能夠經過aof恢復;
Redis支持數據的備份,即master-slave模式的數據備份;
應用場景不同:Redis出來做爲NoSQL數據庫使用外,還能用作消息隊列、數據堆棧和數據緩存等;Memcached適合於緩存SQL語句、數據集、用戶臨時性數據、延遲查詢數據和session等。
因此在選擇方面若是有持久方面的需求或對數據類型和處理有要求的應該選擇redis。若是簡單的key/value 存儲應該選擇memcached。
MySQL 中order by 與group by的順序 是:
select -> from -> where -> group by -> order by
注意:group by 比order by先執行,order by不會對group by 內部進行排序,若是group by後只有一條記錄,那麼order by 將無效。要查出group by中最大的或最小的某一字段使用 max或min函數。
例:
select sum(click_num) as totalnum, max(update_time) as update_time, count(*) as totalarticle from article_detail where userid =1 group by userid order by update_time desc
開發對比
開發速度Hibernate的真正掌握要比Mybatis來得難些。
Mybatis框架相對簡單很容易上手,但也相對簡陋些。
我的以爲要用好Mybatis仍是首先要先理解好Hibernate。
開發社區
Hibernate 與Mybatis都是流行的持久層開發框架,但Hibernate開發社區相對多熱鬧些,支持的工具也多,更新也快,當前最高版本4.1.8。
而Mybatis相對平靜,工具較少,當前最高版本3.2。
開發工做量Hibernate和MyBatis都有相應的代碼生成工具。能夠生成簡單基本的DAO層方法。
針對高級查詢,Mybatis須要手動編寫SQL語句,以及ResultMap。而Hibernate有良好的映射機制,開發者無需關心SQL的生成與結果映射,能夠更專一於業務流程。
Mybatis優點MyBatis能夠進行更爲細緻的SQL優化,能夠減小查詢字段。-
MyBatis容易掌握,而Hibernate門檻較高。
Hibernate優點Hibernate的DAO層開發比MyBatis簡單,Mybatis須要維護SQL和結果映射。
Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
Hibernate數據庫移植性很好,MyBatis的數據庫移植性很差,不一樣的數據庫須要寫不一樣SQL。
Hibernate有更好的二級緩存機制,可使用第三方緩存。MyBatis自己提供的緩存機制不佳。
hibernate是在jdbc上進行了一次封裝,而mybatis基於原生的jdbc,所以mybatis天生就有運行速度上的優點。
mybatis開放了插件接口,把不少功能接口都開放了,網上大神寫的插件多得很;按註解生成自動生成sql的插件早就有了;還有緩存的插件等等。能夠說,只要肯在mybatis上花時間,你會發現orm這一塊的全部問題它都有解決方案。這方面不是說hibernate很差,可是我還真沒據說過hibernate有插件了
需求:使用MyBatis往MySQL數據庫中插入一條記錄後,須要返回該條記錄的自增主鍵值。
useGeneratedKeys="true":設置是否使用JDBC的getGenereatedKeys方法獲取主鍵並賦值到keyProperty設置的領域模型屬性中。(適用於MySQL、sqlserver數據庫,Oracle不能使用,使用selectkey子節點作)
keyProperty="userId":賦值的對象的屬性名稱。
添加完成後,直接根據對象屬性取值
<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User"> insert into user(userName,password,comment) values(#{userName},#{password},#{comment}) </insert>
如上所示,咱們在insert中指定了keyProperty="userId",其中userId表明插入的User對象的主鍵屬性。
User.java
public class User { private int userId; private String userName; private String password; private String comment; //setter and getter }
UserDao.java
public interface UserDao { public int insertAndGetId(User user); }
測試:
User user = new User(); user.setUserName("chenzhou"); user.setPassword("xxxx"); user.setComment("測試插入數據返回主鍵功能"); System.out.println("插入前主鍵爲:"+user.getUserId()); userDao.insertAndGetId(user);//插入操做 System.out.println("插入後主鍵爲:"+user.getUserId());
輸出:
插入前主鍵爲:0 插入後主鍵爲:15
查詢數據庫:
如上所示,剛剛插入的記錄主鍵id爲15
<insert id="insertUser" parameterType="com.entity.user"> insert into test (name) values (#{name}) <selectKey keyProperty="id" resultType="java.lang.Integer"> select LAST_INSERT_ID() as id </selectKey> </insert>
後臺代碼不變。各個數據庫獲取方式不同,本例根據mysql爲例。其餘請各自根據須要查詢。