Home | 简体中文 | 繁体中文 | 杂文 | 打赏(Donations) | OSChina 博客 | Facebook | Linkedin | 知乎专栏 | Search | About

第 8 章 Spring Data

目录

8.1. Spring Data Redis
8.1.1. pom.xml
8.1.2. springframework-servlet.xml
8.1.3. Controller
8.1.4. index.jsp
8.1.5. 删除 key
8.1.6. 测试
8.1.7. ZSET 数据类型
8.1.8. Hash
8.1.9. List
8.2. Spring Data MongoDB
8.2.1. Example Spring Data MongoDB
8.2.1.1. pom.xml
8.2.1.2. springframework-servlet.xml
8.2.1.3. POJO
8.2.1.4. Controller
8.2.1.5. 查看测试结果
8.2.1.6. 条件查询
8.2.2. @Document
8.2.2.1. @Indexed
8.2.2.1.1. 普通索引
8.2.2.1.2. 唯一索引
8.2.2.2. @DateTimeFormat
8.2.2.3. @NumberFormat
8.2.2.4. 在 @Document 中使用 Enum 类型
8.2.2.5. 在 @Document 中定义数据结构 List/Map
8.2.3. MongoRepository
8.2.3.1. findAll()
8.2.3.2. deleteAll()
8.2.3.3. save()
8.2.3.4. count()
8.2.3.5. findByXXXX
8.2.3.6. StartingWith 和 EndingWith
8.2.3.7. Between
8.2.3.8. PageRequest
8.2.3.9. @Query
8.2.4. mongoTemplate
8.2.4.1. is
8.2.4.2. Regex 正则表达式搜索
8.2.4.3. lt 和 gt
8.2.4.4. between
8.2.4.5. Criteria
8.2.4.6. Sort
8.2.4.7. Query + PageRequest
8.2.4.8. newAggregation
8.3. Spring Data JPA
8.3.1. @Entity
8.3.1.1. @Id
8.3.1.2. @Table
8.3.1.2.1. catalog
8.3.1.2.2. schema
8.3.1.2.3. uniqueConstraints
8.3.1.3. @Column
8.3.1.3.1. 字段长度
8.3.1.3.2. 浮点型
8.3.1.3.3. 创建于更新控制
8.3.1.4. @NotNull 不能为空声明
8.3.1.5. @DateTimeFormat 处理日期时间格式
8.3.1.6. 默认时间规则
8.3.1.6.1. CreatedDate
8.3.1.6.2. 与时间日期有关的 hibernate 注解
8.3.1.6.2.1. 设置默认时间
8.3.1.6.2.2. 创建时间
8.3.1.6.2.3. 更新时间
8.3.1.6.3. 数据库级别的默认创建日期时间定义
8.3.1.6.4. 数据库级别的默认创建日期与更新时间定义
8.3.1.6.5. 最后修改时间
8.3.1.7. 索引
8.3.1.8. Enum 枚举数据类型
8.3.1.8.1. 实体中处理 enum 类型
8.3.1.8.2. 数据库枚举类型
8.3.1.9. 整形数据类型
8.3.1.10. @JoinColumn
8.3.1.11. @OneToOne
8.3.1.12. OneToMany 一对多
8.3.1.13. ManyToMany 多对多
8.3.1.14. 外键级联删除
8.3.1.15. 其他
8.3.1.15.1. Cascade
8.3.1.15.2. @JsonIgnore
8.3.2. 实体集成
8.3.3. Repository
8.3.3.1. 传递枚举参数
8.3.3.2. 翻页操作
8.3.3.3. 排序操作操作
8.3.3.4. OrderBy
8.3.3.5. Query
8.3.3.5.1. 参数传递
8.3.3.6. @Transactional
8.3.3.6.1. 删除更新需要 @Transactional 注解
8.3.3.6.2. 回滚操作
8.3.4. CrudRepository
8.3.4.1. GreaterThan
8.3.5. JpaRepository
8.4. EntityManager
8.5. JdbcTemplate
8.5.1. execute
8.5.2. queryForInt
8.5.3. queryForObject
8.5.3.1. 返回整形与字符型
8.5.3.2. 查询 Double 类型数据库
8.5.3.3. 返回日期
8.5.3.4. 返回结果集
8.5.3.5. 通过 "?" 向SQL传递参数
8.5.3.6. RowMapper 记录映射
8.5.4. queryForList
8.5.5. queryForMap
8.5.6. query
8.5.6.1. ResultSet
8.5.6.2. ResultSetExtractor
8.5.6.3. RowMapper
8.5.7. queryForRowSet
8.5.8. update
8.6. Elasticsearch
8.6.1. 内嵌 Elasticsearch
8.6.1.1. Maven
8.6.1.2. src/main/resources/application.properties
8.6.1.3. Domain Class
8.6.1.4. ElasticsearchRepository
8.6.1.5. SearchRestController
8.6.1.6. 测试
8.6.2. 集群模式
8.6.3. Document
8.6.4. Elasticsearch 删除操作
8.6.5. FAQ
8.6.5.1. java.lang.IllegalStateException: Received message from unsupported version: [2.0.0] minimal compatible version is: [5.0.0]
8.7. Spring Data FAQ
8.7.1. No identifier specified for entity
8.7.2. Oracle Date 类型显示日期和时间
8.7.3. java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
8.7.4. Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query

8.1. Spring Data Redis

8.1.1. pom.xml

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

8.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" />
		
		

例 8.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>				
			
			

8.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);
	}
}
		
		

8.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>			
		
		

8.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 );
	}
		
		

8.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()); 实现

8.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);  
	}  
	
}
		
		

8.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"));		
		
		

8.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));