億級流量架構|day09-Redis入門

1 Redis命令

1.Hash類型
說明:可以用散列類型保存對象和屬性的值,表現爲value部分爲一個HashMap。
例子:User對象{id:2, name:小明, age:19}
在這裏插入圖片描述

2.List類型
說明:Redis中的List集合是雙端循環列表(雙向列表),分別可以從左右兩個方向插入數據。
List集合可以當做隊列來使用,也可以當做棧來使用。
隊列:先進先出,存/取數據的方向不一致。
棧:先進後出,存/取數據的方向一致。
在這裏插入圖片描述

3.Redis事務命令
業務需求:

  • redis可以當做數據庫使用。
  • 有時插入緩存時,可能多數據一起插入,所以需要事務控制。

說明:redis中操作可以添加事務的支持,一項任務可以由多個redis命令完成,如果有一個命令失敗導致入庫失敗時,需要實現事務回滾。
在這裏插入圖片描述

2 Redis入門案例

2.1 引入jar包

<!-- jedis -->
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>${jedis.version}</version>
</dependency>

<!--添加spring-datajar包  -->
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>1.4.1.RELEASE</version>
</dependency>

2.2 測試字符串

//測試String類型    IP:端口
/**
 * 1.檢測防火牆是否關閉了
 * 2.檢查IP綁定是否註釋了  默認綁定本機(Linux)  #bind ip 關閉後重啓
 * 3.保護模式是否關閉  默認值yes   改爲no  修改後重啓
 * 4.啓動方式不對...... redis-server redis.conf
 */
@Test
public void testString(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	Long start = System.currentTimeMillis();
	jedis.set("1806","今天星期一困的不行,一週總有那麼7天不想上課");
	Long end = System.currentTimeMillis();
	System.out.println(end-start+"毫秒");
	System.out.println
	("獲取redis內容:"+jedis.get("1806"));
}

2.3 測試Hash

//測試hash值 讀11萬/s  寫8.1萬/s 10萬/s
@Test
public void testHash(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	jedis.hset("person", "id", "100");
	jedis.hset("person", "name", "1806班");
	jedis.hset("person", "age", "4");
	Map<String,String> map = jedis.hgetAll("person");
	System.out.println(map);
}

2.4 測試List

@Test
public void testList(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	//下面代碼中是可變參數 使用,號分割
	jedis.lpush("list","1","2","3","4");
	System.out.println(jedis.rpop("list"));
}

2.5 Redis事務控制

/**
 * redis.clients.jedis.exceptions.JedisDataException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.
 * 說明:因爲使用redis事務控制需要開啓事務/提交事務/回滾事務
 * 這部分代碼如果直接寫入業務層,則代碼的耦合性高
 * 所以可以通過AOP+自定義註解redisTx
 * 抽空說說
 */
@Test
public void testTx(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	//開啓事務控制
	Transaction tansaction = jedis.multi();
	//執行入庫操作
	tansaction.set("aa", "事務測試");
	tansaction.set("bb", "bb");
	//事務提交
	//tansaction.exec();
	//事務回滾
	tansaction.discard();
	System.out.println("獲取數據:"+jedis.get("aa"));
}

3 Spring整合Redis

3.1 編輯pro文件

1.新建redis.properties文件

redis.host=192.168.126.166
redis.port=6379

2.導入配置文件

<list>
	<value>classpath:/property/jdbc.properties</value>
	<value>classpath:/property/redis.properties</value>
</list>

3.2 編輯配置文件

<!--spring整合redis 
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	
	關於構造注入的注意事項
	1.name屬性:代表構造方法中的參數名稱
	注意事項:在使用構造注入時,程序打包部署時最好添加源碼!!!!
	如果沒有導入源碼.那麼程序不會維護形參 則名稱爲arg0,arg1,arg2.
	2.index屬性
		表示下標,從0開始.根據參數位置匹配構造方法.
		User(String a,String b)
		User(int a,String b)
		User(Dog dog,String a)
	3.type=""屬性
		表示參數類型,一般默認不寫.由spring框架內部自動進行強轉.
		所以在爲參數賦值時,必須嚴格的規範構造方法.否則
		注入會有問題.		
 -->
<!--  <bean id="jedis" class="redis.clients.jedis.Jedis">
 	<constructor-arg index="0"  value="${redis.host}"  type="Dog"/>
 	<constructor-arg index="1"  value="${redis.port}"  type="int"/>
 </bean> -->
 <bean id="jedis" class="redis.clients.jedis.Jedis">
 	<constructor-arg name="host"  value="${redis.host}"/>
 	<constructor-arg name="port"  value="${redis.port}"/>
 </bean>

4 JSON回顧

4.1 json官網介紹

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易於人閱讀和編寫。

4.2 object格式

語法:

  • 對象是一個無序的名稱/值對集合
  • 一個對象以"{"(左大括號)開始,"}"(右大括號)結束
  • 每個名稱後跟一個":"(冒號)
  • 名稱/值對之間使用","(逗號)分割

{key:value}
在這裏插入圖片描述

例子:{“id”:“1”,“name”:“tom”}
簡單寫法:key和數字可以不加引號

4.3 array格式

說明:通過數組形式保存數據
格式:數組·是·值(value)的有序集合,一個數組以"["(左中括號)開始,"]"(右中括號)結束,值之間用","(逗號)分隔。
[value1,value2,value3]
圖例:
在這裏插入圖片描述

例子:[1,2,3,4,5,“tom”]

4.4 複雜格式

特點:可以將object格式和array格式進行·無限層級嵌套
說明:值(value)可以是雙括號括起來的字符串(string)、數值(number)、true、false、null、對象(object)或者數組(array)。這些結構可以嵌套。

圖例:
在這裏插入圖片描述

例子:

{
	id:1,
	name:"tomcat",
	hobby:[
		["早點","午飯","下午茶"],
		"喝",
		{
			where:"沙灘",
			time:"半夜",
			with:"鯊魚"
		}
	]
}

5 JSON與對象轉化

5.1 對象轉爲JSON串

//將對象轉化爲JSON
@Test
public void ObjectToJSON() throws JsonProcessingException{
	User user = new User();
	user.setId(1);
	user.setName("tomcat貓");
	user.setAge(19);
	
	ObjectMapper objectMapper = new ObjectMapper();
	//轉化時調用對象的getXXX()
	String json = 
			objectMapper.writeValueAsString(user);
	System.out.println(json);
}

5.2 JSON轉對象

@Test
public void jsonToObject() throws JsonParseException, JsonMappingException, IOException{
	String json = "{\"id\":\"1\",\"name\":\"tomcat\"}";
	ObjectMapper objectMapper = new ObjectMapper();
	User user = objectMapper.readValue(json,User.class);
	System.out.println(user);
}

5.3 複雜格式轉化

@Test
public void jsonOA() throws IOException{
	List<User> userList = new ArrayList<>();
	User user1 = new User();
	user1.setId(1);
	user1.setName("tomcat貓");
	user1.setAge(19);
	user1.setSex("男");
	User user2 = new User();
	user2.setId(2);
	user2.setName("tomcat貓");
	user2.setAge(19);
	user2.setSex("男");
	userList.add(user1);
	userList.add(user2);
	
	ObjectMapper objectMapper = new ObjectMapper();
	String json = objectMapper.writeValueAsString(userList);
	//System.out.println("獲取JSON串:"+json);
	
	//2.將複雜格式的JSON轉化爲對象List
	//List<User> uList = 
			//objectMapper.readValue(json, userList.getClass());
	//System.out.println("獲取對象:"+uList);
	
	User[] users = 
			objectMapper.readValue(json,User[].class);
	
	//將數組轉化爲List集合
	List<User> uList = Arrays.asList(users);
	System.out.println(uList);
}

6 緩存實現商品分類查詢

6.1 緩存實現步驟

1.修改業務邏輯,首先用戶查詢先查詢redis緩存
2.如果無緩存數據,表示第一次查詢該數據,則先從數據庫查找
3.找到數據後,將數據通過API轉化爲JSON串,將數據k-v寫入緩存中
4.如果緩存數據不爲null,則將JSON串轉化爲java對象,直接return返回。

6.2 編輯controller

/**
 * 實現商品分類目錄展現
 * @RequestParam
 * 	defaultValue= 如果沒有傳遞參數 默認值爲...
 *  required=true/false 默認爲false  如果true 那麼前臺必須傳遞該參數.
 *  value 需要轉化變量的名稱
 * @param parentId
 * @return
 */
@RequestMapping("/list")
@ResponseBody
public List<EasyUITree> findItemCatById(
		@RequestParam(value="id",
		defaultValue="0") 
		Long parentId){
	//查詢一級商品分類目錄
	//Long parentId = 0L;
	//return itemCatService.findItemCatById(parentId);
	return itemCatService.findCacheItemCatById(parentId);
}

6.3 編輯service

1.注入對象
在這裏插入圖片描述

2.業務代碼

//通過redis緩存實現信息查詢
@Override
public List<EasyUITree> findCacheItemCatById(Long parentId) {
	List<EasyUITree> treeList = null;
	
	//1.先查詢緩存數據
	String key = "ITEM_CAT_"+parentId;
	String resultJSON = jedis.get(key);
	
	try {
		//2.判斷緩存中是否有數據
		if(StringUtils.isEmpty(resultJSON)){
			//2.1表示緩存中沒有數據,需要查詢後臺數據庫
			treeList = findItemCatById(parentId);
			
			//2.2將java對象轉化爲JSON串
			String jsonData = objectMapper.writeValueAsString(treeList);
			
			//2.3將數據寫入緩存
			jedis.set(key, jsonData);
			System.out.println("第一次查詢數據庫");
		}else {
			//3.緩存中有數據
			//3.1將JSON串轉化爲java對象(List)
			EasyUITree[] trees = 
			objectMapper.readValue(resultJSON,EasyUITree[].class);
			treeList = Arrays.asList(trees);
			System.out.println("查詢緩存數據");
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return treeList;
}

6.4 時間比較

1.沒有添加緩存時
在這裏插入圖片描述

2.添加緩存時
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章