SpringData JPA是Spring Data下的多个子项目之一,通过在运行时自动生成Repository实现,Spring Data JPA让JPA的使用过程更简单。Spring Data还提供了对多种NoSQL数据库的支持,包括MongoDB、Redis等,不仅支持自动化的Repository,还支持基于模板的数据访问和映射注解。
使用MongoDB持久化文档数据
有一些数据的最佳表现形式是文档,也就是不要把数据分散到多个表、节点或实体中,将这些信息收集到一个非规范化的结构中会更方便,通常来说,文档是独立的实体。能够按照这种方式优化并处理文档的数据库,被称为文档数据库。
文档数据库不适用的场景:文档数据库不是通用的数据库,所擅长解决的是一个很小的问题集。有些数据具有明显的关联关系,文档数据库并没有针对存储这样的数据进行优化。在文档数据库中存储具有丰富关联关系的数据也不是不行,只是这样做麻烦大于收益。
MongoDB是最流行的开源文档数据库之一,Spring Data MongoDB提供了三种方式在Spring应用中使用MongoDB:
通过注解实现对象-文档映射
使用MongoTemplate实现基于模板的数据库访问
自动化的运行是Repository生成功能
配置MongoDB
@Configuration
//启用MongoDB的Repository
@EnableMongoRepositories(basePackages="com.coder.spring.profile.mongo")
public class MongoConfig extends AbstractMongoConfiguration{
//指定数据库名称
@Override
protected StringgetDatabaseName() {
return "testDB";
}
//创建Mongo客户端
@Override
public Mongomongo() throwsException {
return new MongoClient();
}
}
MongoDB是远程的数据库服务的
@Configuration
//启用MongoDB的Repository
@EnableMongoRepositories(basePackages="com.coder.spring.profile.mongo")
public class MongoConfig extends AbstractMongoConfiguration {
@Autowired
private Environment environment;
//指定数据库名称
@Override
protected String getDatabaseName() {
return "testDB";
}
//创建Mongo客户端 远程验证
@Override
public Mongo mongo() throws Exception {
MongoCredential credential = MongoCredential.createMongoCRCredential(
environment.getProperty("mongo.username"),
"testDB",
environment.getProperty("mongo.password").toCharArray());
return new MongoClient(new ServerAddress("localhost",37000), Arrays.asList(credential));
}
}
XML配置:
xml version="1.0" encoding="utf-8" ?>
xmlns="http://www.springframework.org/schema/beans"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
profile="dev" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<mongo:repositories base-package="com.coder.spring"/>
<mongo:mongo/>
id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
ref="mongo"/>
value="testDB"/>
为模型添加注解,实现MongoDB持久化
MongoDB没有提供对象-文档映射的注解,SpringData MongoDB提供了一些将java类映射为MongoDB的注解。
注解 | 描述 |
@Document | 标示映射到MongoDB文档上的领域对象 |
@Id | 标示某个域为ID域 |
@DbRef | 标示某个域要引用其他的文档,这个文档有可能位于另外的数据库 |
@Field | 为文档域指定自定义的元数据 |
@Version | 标示某个属性用作版本域 |
@Document和@Id注解类似于JPA的@Entity和@Id注解。
@Document(collection = "follow_activity")
public class FollowActivityPO implements Serializable{
@Id
private Long id;
@Field("name")
private String activityName;
}
Java类中,除非将属性设置为瞬时态(transient)的,否则java对象中所有的域都会持久化为文档中的域,并且如果不适用@Field注解进行设置的话,那么文档中的名字将会与对应的Java属性相同。
使用MongoTemplate访问MongoDB
//将MongoTemplate注入到类型为mongoOperations的属性中
@Autowired
MongoOperations mongoOperations;
public Long getCount(){
return mongoOperations.getCollection("order").getCount();
}
MongoOperations是MongoTemplate所实现的接口,暴露了多个使用MongoDB文档数据库的方法。通常,将MongoOperations注入到设计的Repository类中,并使用它操作Repository方法。
编写MongoDB Repository
通过扩展MongoRepository,Repository接口能继承多个CRUD操作,它们会由Spring Data MongoDB自动实现
方法 | 描述 |
long count() | 返回指定Repository类型的文档数量 |
void delete(Iterable extends T> | 删除与指定对象关联的所有文档 |
void delete(T) | 删除与指定对象关联的文档 |
void delete(ID) | 根据ID删除某一个文档 |
void deleteAll() | 删除指定Repository类型的所有文档 |
Boolean exists(Object) | 如果存在于指定对象相关联的文档,则返回true |
Boolean exists(ID) | 如果存在指定ID的文档,则返回true |
List findAll() | 返回指定Repository类型的所有文档 |
List findAll(Iterable) | 返回指定文档ID对应的所有文档 |
List findAll(Pageable) | 为指定的Repository类型,返回分页切排序的文档列表 |
List findAll(Sort) | 为指定的Repository类型,返回排序后的所有文档列表 |
T findOne(ID) | 为指定的ID返回单个文档 |
Iterable save(Iterable)
| 保存指定Iterable中的所有文档 |
S save(s)
| 为给的的对象保存一条文档 |
使用Redis操作Key-Value数据
Redis是一种特殊类型的数据库,被称为key-value存储。
连接到Redis
Redis连接工厂会生成到Redis数据库服务器的连接。SpringData Redis为四种Redis客户端实现提供了工厂
JedisConnectionFactory
JredisConnectionFactory
LettuceConnectionFactory
SrpConnectionFactory
@Bean
public RedisConnectionFactory redisFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName("test-server");
factory.setPort("6973");
factory.setPassword("123456");
return factory;
}
使用RedisTemplate
Redis连接工厂会生成到Rediskey-value存储的连接。借助RedisConnection,可以存储和读取数据。Spring Data Redis 提供了两个模板:
RedisTemplate
StringRedisTemplate
RedisTemplate可以极大的简化Redis数据访问,能够持久化各种类型的key和value,并不局限于字节数组。由于key和value通常都是String类型,StringRedisTemplate扩展了RedisTemplate,只关注String。
RedisTemplate和其子API的很多功能,区分了单个值和集合值
方法 | 子API接口 | 描述 |
opsForValue() | valueOperations | 操作具有简单值的条目 |
opsForList() | listOperations | 操作具有List值的条目 |
opsForSet() | setOperations | 操作具有Set值的条目 |
opsForZSet() | zSetOperations | 操作具有ZSet值的条目(排序的Set) |
opsForHash() | hashOperations | 操作具有hash值的条目 |
boundValueOps(K) | boundValueOperations | 以绑定指定key的方式,操作具有简单值的条目 |
boundListOps(K) | boundListOperations | 以绑定指定key的方式,操作具有list值的条目 |
boundSetOps(K) | boundSetOperations | 以绑定指定key的方式,操作具有set值的条目 |
boundZSet(K) | boundZSetOperations | 以绑定指定key的方式,操作具有Zset值的条目 |
boundHashOps(K) | boundHashOperations | 以绑定指定key的方式,操作具有hash值的条目 |
使用key和value的序列化器
当某个条目保存到Rediskey-value存储的时候,key和value都会使用Redis的序列化器进行序列化。Spring Data Redis提供了多个序列化器:
GenericToStringSerializer:使用Spring转化服务进行序列化
JacksonJsonRedisSerializer:使用Jackson1,将对象序列化为JSON
Jackson2JsonRedisSerializer:使用Jackson2,将对象序列化为JSON
JdkSerializationRedisSerializer:使用Java序列化
OxmSerializer:使用Spring O/X映射的编排器和解排器实现序列化,用于XML序列化
StringRedisSerializer:序列化String类型的key和value
这些序列化器都实现了RedisSerializer接口,如果其中没有符合需求的序列化器,那么还可自行创建。
当想把key和value序列化为不同的类型,如key为String,Value为JSON。可以通过RedisTemplate的setKeySerializer()和setValueSerializer()方法。