Home | 簡體中文 | 繁體中文 | 雜文 | 打賞(Donations) | OSChina 博客 | Facebook | Linkedin | 知乎專欄 | Search | About

第 5 章 Spring Data

目錄

5.1. Spring Data Redis
5.1.1. pom.xml
5.1.2. springframework-servlet.xml
5.1.3. Controller
5.1.4. index.jsp
5.1.5. 刪除 key
5.1.6. 測試
5.1.7. ZSET 數據類型
5.1.8. Hash
5.1.9. List
5.2. Spring Data MongoDB
5.2.1. Example Spring Data MongoDB
5.2.1.1. pom.xml
5.2.1.2. springframework-servlet.xml
5.2.1.3. POJO
5.2.1.4. Controller
5.2.1.5. 查看測試結果
5.2.1.6. 條件查詢
5.2.2. @Document
5.2.2.1. @Indexed
5.2.2.1.1. 普通索引
5.2.2.1.2. 唯一索引
5.2.2.2. @DateTimeFormat
5.2.2.3. @NumberFormat
5.2.2.4. 在 @Document 中使用 Enum 類型
5.2.2.5. 在 @Document 中定義資料結構 List/Map
5.2.3. MongoRepository
5.2.3.1. findAll()
5.2.3.2. deleteAll()
5.2.3.3. save()
5.2.3.4. count()
5.2.3.5. findByXXXX
5.2.3.6. StartingWith 和 EndingWith
5.2.3.7. Between
5.2.3.8. PageRequest
5.2.3.9. @Query
5.2.4. mongoTemplate
5.2.4.1. is
5.2.4.2. Regex 正則表達式搜索
5.2.4.3. lt 和 gt
5.2.4.4. between
5.2.4.5. Criteria
5.2.4.6. Sort
5.2.4.7. Query + PageRequest
5.2.4.8. newAggregation
5.3. Spring Data JPA
5.3.1. @Entity
5.3.1.1. @Id
5.3.1.2. @Table
5.3.1.2.1. catalog
5.3.1.2.2. schema
5.3.1.2.3. uniqueConstraints
5.3.1.3. @Column
5.3.1.3.1. 欄位長度
5.3.1.3.2. 浮點型
5.3.1.3.3. 創建於更新控制
5.3.1.4. @NotNull 不能為空聲明
5.3.1.5. @DateTimeFormat 處理日期時間格式
5.3.1.6. 預設時間規則
5.3.1.6.1. CreatedDate
5.3.1.6.2. 與時間日期有關的 hibernate 註解
5.3.1.6.2.1. 設置預設時間
5.3.1.6.2.2. 創建時間
5.3.1.6.2.3. 更新時間
5.3.1.6.3. 資料庫級別的預設創建日期時間定義
5.3.1.6.4. 資料庫級別的預設創建日期與更新時間定義
5.3.1.6.5. 最後修改時間
5.3.1.7. 索引
5.3.1.8. Enum 枚舉數據類型
5.3.1.8.1. 實體中處理 enum 類型
5.3.1.8.2. 資料庫枚舉類型
5.3.1.9. 整形數據類型
5.3.1.10. @JoinColumn
5.3.1.11. @OneToOne
5.3.1.12. OneToMany 一對多
5.3.1.13. ManyToMany 多對多
5.3.1.14. 外鍵級聯刪除
5.3.1.15. 其他
5.3.1.15.1. Cascade
5.3.1.15.2. @JsonIgnore
5.3.2. 實體整合
5.3.3. Repository
5.3.3.1. 傳遞枚舉參數
5.3.3.2. 翻頁操作
5.3.3.3. 排序操作操作
5.3.3.4. OrderBy
5.3.3.5. Query
5.3.3.5.1. 參數傳遞
5.3.3.6. @Transactional
5.3.3.6.1. 刪除更新需要 @Transactional 註解
5.3.3.6.2. 回滾操作
5.3.4. CrudRepository
5.3.4.1. GreaterThan
5.3.5. JpaRepository
5.4. EntityManager
5.5. JdbcTemplate
5.5.1. execute
5.5.2. queryForInt
5.5.3. queryForObject
5.5.3.1. 返回整形與字元型
5.5.3.2. 查詢 Double 類型資料庫
5.5.3.3. 返回日期
5.5.3.4. 返回結果集
5.5.3.5. 通過 "?" 向SQL傳遞參數
5.5.3.6. RowMapper 記錄映射
5.5.4. queryForList
5.5.5. queryForMap
5.5.6. query
5.5.6.1. ResultSet
5.5.6.2. ResultSetExtractor
5.5.6.3. RowMapper
5.5.7. queryForRowSet
5.5.8. update
5.6. Elasticsearch
5.6.1. 內嵌 Elasticsearch
5.6.1.1. Maven
5.6.1.2. src/main/resources/application.properties
5.6.1.3. Domain Class
5.6.1.4. ElasticsearchRepository
5.6.1.5. SearchRestController
5.6.1.6. 測試
5.6.2. 集群模式
5.6.3. Document
5.6.4. Elasticsearch 刪除操作
5.6.5. FAQ
5.6.5.1. java.lang.IllegalStateException: Received message from unsupported version: [2.0.0] minimal compatible version is: [5.0.0]
5.7. Spring Data FAQ
5.7.1. No identifier specified for entity
5.7.2. Oracle Date 類型顯示日期和時間
5.7.3. java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
5.7.4. Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query

5.1. Spring Data Redis

5.1.1. pom.xml

		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
		</dependency>			
		
		

5.1.2. springframework-servlet.xml

		
	<!-- Redis Connection Factory -->
	<bean id="jedisConnFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" />

	<!-- redis template definition -->
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
		p:connection-factory-ref="jedisConnFactory" />
		
		

例 5.1. Spring Data Redis Example

			
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

	<mvc:resources location="/images/" mapping="/images/**" />
	<mvc:resources location="/css/" mapping="/css/**" />

	<context:component-scan base-package="cn.netkiller.controller" />

	<mvc:annotation-driven />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
		<!-- <property name="viewNames" value="*.jsp" /> -->
	</bean>

	<bean id="configuracion"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:resources/development.properties" />
	</bean>

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>

	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="cn.netkiller.mapper" />
	</bean>

	<bean id="userService" class="cn.netkiller.service.UserService">
	</bean>

	<!-- Redis Connection Factory -->
	<bean id="jedisConnFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" />

	<!-- redis template definition -->
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
		p:connection-factory-ref="jedisConnFactory" />
</beans>				
			
			

5.1.3. Controller

		
package cn.netkiller.controller;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cn.netkiller.model.User;

@Controller
public class CacheController {

	// inject the actual template
	@Autowired
	private RedisTemplate<String, String> template;

	// inject the template as ListOperations
	@Resource(name = "redisTemplate")
	private ListOperations<String, String> listOps;

	@RequestMapping("/cache")
	public ModelAndView cache() {

		String message = "";

		User user = new User();
		user.setId("1");
		user.setName("Neo");
		user.setAge(30);

		String key = "user";
		listOps.leftPush(key, user.toString());
		message = listOps.leftPop(key);

		template.setKeySerializer(new StringRedisSerializer());
		template.setValueSerializer(new StringRedisSerializer());
		template.opsForValue().set("key", user.toString());

		return new ModelAndView("index/index", "variable", message);
	}
}
		
		

5.1.4. index.jsp

		
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<br>
	<div style="text-align:center">
		<h2>
			${variable}
		</h2>
	</div>
</body>
</html>			
		
		

5.1.5. 刪除 key

		
	private void cleanNewToday() {
		long begin = System.currentTimeMillis();
        
		redisTemplate.delete("news:today");
    
        long end = System.currentTimeMillis();
		logger.info("Schedule clean redis {} 耗時 {} 秒", "cleanNewFlash()", (end-begin) / 1000 );
	}
		
		

5.1.6. 測試

請求URL http://your.domain.com/your.html

		
[root@master ~]# redis-cli 
redis 127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x04user"
2) "key"

redis 127.0.0.1:6379> get key
"\xac\xed\x00\x05t\x00\x1dUser [id=1, name=Neo, age=30]"
		
		
[提示]提示

Spring Redis 預設使用 Byte數據類型存儲Key,在redis-cli中會看到 "\xac\xed\x00\x05t\x00\x04" 首碼不方便get操作,所以我們會設置使用字元串,通過 template.setKeySerializer(new StringRedisSerializer()); 實現

5.1.7. ZSET 數據類型

		
//添加 一個 set 集合
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add("Member", "neo");
set.add("Member", "36");
set.add("Member", "178cm");
//輸出 set 集合
System.out.println(set.members("Member"));

//添加有序的 set 集合
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add("zMember", "neo", 0);
zset.add("zMember", "36", 1);
zset.add("zMember", "178cm", 2);
//輸出有序 set 集合
System.out.println(zset.rangeByScore("zMember", 0, 2));		
		
		
		
package cn.netkiller.api.restful;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import common.pojo.ResponseRestful;

@RestController
@RequestMapping("/news")
public class NewsRestController {

	@Autowired
	private RedisTemplate<String, String> redisTemplate;

	@RequestMapping(value = "/flash/{count}")
	public ResponseRestful flash(@PathVariable("count") long count) {
		if(count == 0L) {
			count=10L;
		}
		Set<String> news = this.redisTemplate.opsForZSet().reverseRange("news:flash", 0, count);
		if (news == null) {
			return new ResponseRestful(false, 10, "沒有查詢到結果", news);
		}
		return new ResponseRestful(true, 0, "返回數據: " + news.size() + " 條", news);
	}
	
	public void addRecentUser(long userId, String name) {  
	    String key = RedisKeyGenerator.genRecentBrowsingPositionsKey(String.valueOf(userId));  
	    // 獲取已緩存的最近瀏覽的職位  
	    ZSetOperations<String, String> zSetOperations = redisTempalte.opsForZSet();  
        //zset內部是按分數來排序的,這裡用當前時間做分數  
	    zSetOperations.add(key, name, System.currentTimeMillis());  
	    zSetOperations.removeRange(key, 0, -6);  
	}  
	
}
		
		

5.1.8. Hash

		
HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", "neo");
map.put("age", "36");
hash.putAll("member", map);

System.out.println(hash.entries("member"));		
		
		

5.1.9. List

		
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush("books", "Linux");
list.rightPush("books", "Java");
System.out.println(list.range("books", 0, 1));