Spring Data 使命声明

Download Report

Transcript Spring Data 使命声明

Spring Data 简介
Mark Pollack 博士
议题
• 当前的数据形态
• 项目目标
• 项目概览
企业数据趋势
企业数据趋势
非结构化数据
•无预定义的数据模型
•经常不大适合于 RDBMS
预聚合数据
•在数据收集期间进行计算
•计数器
•运行平均数
数据的价值
• 数据的价值超越了软硬件成本
• 连接数据集的价值
– 通过用户代理程序将电子商务用户组合起来
Mozilla/5.0(Macintosh; U; Intel Mac OS X; en)AppleWebKit/418.9(KHTML,比如 Gecko)Safari/419.3
数据革命
• 极其难以/不可能在 RDBMS 中扩展写操作
– 纵向扩展受限制/成本高昂
– 横向扩展受限制或耗费资金
• 从 ACID 转换到 BASE
– 基本可用、可扩展、最终一致性
• NoSQL 数据存储成为新兴的“点解决方案”
– Amazon/Google 论文
– Facebook、LinkedIn …
NoSQL
“不仅仅 SQL”
NOSQL \no-seek-wool\ n. 描述当下的趋势,即开发人员
越多越多地选择用非关系数据库来帮助解决其问题,试图
使用合适的工具来完成合适的工作。
查询机制
关键字查询、映射缩减、按示例查询、查询语言、遍历
大数据
• “大数据”是指规模过大,以至一般数据库软件工具无法
进行数据捕获、存储、管理和分析的数据集。
• 一个主观性和不断移动的目标。
• 当今许多领域中的大数据的大小范围为从几十个 TB 到多
个 PB
现实检验
现实检验
项目目标
Spring Data – 背景和动机
• 数据访问形态已经发生天翻地覆的变化
• RDBMS 仍然占据重要和支配性的地位
– 但不再被视作“万金油”解决方案
• 但 RMBMS 具有局限性
– 难以扩展
• 新的数据访问技术正在解决 RMBMS 所无法解决的问题
– 更高的性能和可扩展性,不同的数据模型
– 常常受到限制的事务模型和松弛的一致性
• 坚持使用多种语言变得更普遍
– 在一个解决方案中将 RDBMS 与其他数据库相结合
Spring 和数据访问
• Spring 一直提供出色的数据访问支持
–
–
–
–
–
事务管理
可移植的数据访问异常层次结构
JDBC – JdbcTemplate
ORM – 支持 Hibernate、JPA、JDO、Ibatis
支持缓存 (Spring 3.1)
• Spring Data 项目于 2010 年启动
• 目标是“刷新”Spring 的数据访问支持
– 参照新的数据访问形态
Spring Data 使命声明
“
89% of all virtualized applications
为大数据、NoSQL 和关系存储提供熟
in the world run on VMware.
悉、一致且基于 Spring 的编程模型,
Gartner, December 2008
同时保留特定于存储的特性和功能。
Spring Data 使命声明
“
89% of all virtualized applications
为大数据、NoSQL 和关系存储提供熟
in the world run on VMware.
悉、一致且基于 Spring 的编程模型,
Gartner, December 2008
同时保留特定于存储的特性和功能。
Spring Data 使命声明
“特定于存储的
89% of all virtualized applications
in the world run on VMware.
Gartner, December 2008
特性和功能。
Spring Data – 支持的技术
• 关系型
– JPA
– JDBC 扩展
• NoSQL
–
–
–
–
–
–
Redis
HBase
Mongo
Neo4j
Lucene
Gemfire
• 大数据
– Hadoop
•
•
•
•
HDFS 和 M/R
Hive
Pig
Cascading
– Splunk
• 访问
– 资源库
– QueryDSL
– REST
Spring Data – 一切由您做主
• 通过熟悉的 Spring 模板
样式访问特定于数据库的
特性
–
–
–
–
–
RedisTemplate
HBaseTemplate
MongoTemplate
Neo4jTemplate
GemfireTemplate
• 共享的编程模型和数据访
问机制
– 资源库模型
• 跨数据存储的公用 CRUD
– 与 QueryDSL 集成
• 类型安全的查询语言
– REST 导出器
• 以基于 REST 的方式通过
HTTP 公开资源库。
项目概览
JDBC 和 JPA
Spring Data JDBC 扩展 – Oracle 支持
• 快速连接故障转移
• 高级队列 JMS 支持和数据源的
简化配置
• 消息传送和数据库访问的单一本
地事务
• 轻松访问本机 XML、Struct、
Array 数据类型
• 用于自定义连接环境的 API
QueryDSL
“
支持为多个后端(包括 JPA、JDO、
MongoDB、Lucence、SQL 和 Java
中的普通集合)构造类型安全的类似
SQL 的查询
http://www.querydsl.com/ - 开源,Apache 2.0
使用字符串作为查询语言的问题
•
•
•
•
•
使用字符串容易出错
必须记住查询语法、域类、属性和关系
按照名称或位置的冗长参数绑定
每个后端都拥有其自身的查询语言和 API
注释:.NET 含有 LINQ
QueryDSL 特性
•
•
•
•
•
在 IDE 中完成编码
几乎完全禁止语法无效的查询
域类型和属性可以安全引用(无字符串)
通过 Java 注释处理程序生成帮助程序类
冗长性远小于 JPA2 标准的 API
QCustomer customer = QCustomer.customer;
JPQLQuery query = new JPAQuery(entityManger)
Customer bob = query.from(customer)
.where(customer.firstName.eq(“Bob”)
.uniqueResult(customer)
将 QueryDSL 用于 JDBC
• 将代码生成融入到构建流程中
– 以创建域类或表格 (JDBC) 的查询元数据模型
• 对于 SQL
QAddress qAddress = QAddress.address;
SQLTemplates dialect = new HSQLDBTemplates();
SQLQuery query = new SQLQueryImpl(connection, dialect)
.from(qAddress)
.where(qAddress.city.eq("London"));
List<Address> results = query.list(new QBean<Address>(Address.class,
qAddress.street, qAddress.city, qAddress.country));
Querydsl 判定
Spring JDBC 扩展 – QueryDslJdbcTemplate
• 支持的 JdbcTemplate打包程序
– 使用 Querydsl SQLQuery 类来执行查询
– 与 Spring 的事务管理集成
– 自动检测数据库类型并设置 SQLTemplates 方言
– 用于映射到 POJO 的 Spring RowMapper 和
ResultSetExtractors
– 通过 Querds 的 SQLInsertClause、SQLUpdateClause
和 SQLDeleteClause 执行插入、更新和删除
Spring JDBC 扩展 – QueryDslJdbcTemplate
// Query with join
QCustomer qCustomer = QCustomer.customer;
SQLQuery findByIdQuery = qdslTemplate.newSqlQuery()
.from(qCustomer)
.leftJoin(qCustomer._addressCustomerRef, qAddress)
.where(qCustomer.id.eq(id));
JPA 和资源库
资源库
通过使用类似集合的接口来访问域对象,在域和数据映射
层之间进行调解。
http://martinfowler.com/eaaCatalog/repository.html
Spring Data 资源库
• 有了 Spring Data 资源库,您将不必忙于开发资源库
例如…
public interface CustomerRepository {
Customer findOne(Long id);
Customer save(Customer customer);
Customer findByEmailAddress(EmailAddress emailAddress);
}
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
private EmailAddress emailAddress;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "customer_id")
private Set<Address> addresses = new HashSet<Address>();
// constructor, properties, equals, hashcode omitted for brevity
}
传统 JPA 实施
@Repository
public class JpaCustomerRepository implements CustomerRepository {
@PersistenceContext
private EntityManager em;
@Override
public Customer findOne(Long id) {
return em.find(Customer.class, id);
}
public Customer save(Customer customer) {
if (customer.getId() == null) {
em.persist(customer);
return customer;
} else {
return em.merge(customer);
}
}
...
传统 JPA 实施
. . .
@Override
public Customer findByEmailAddress(EmailAddress emailAddress) {
TypedQuery<Customer> query =
em.createQuery("select c from Customer c where c.emailAddress = :email", Customer.class);
query.setParameter("email", emailAddress);
return query.getSingleResult();
}
}
Spring Data 资源库
• 简单的方法
1.
2.
3.
4.
使用 JPA 来映射 POJO
扩展资源库(标记)接口或使用注释
添加查询程序方法
配置 Spring 来扫描资源库接口并创建实施
• 将实施注入到服务中,并正常使用…
Spring Data 资源库示例
public interface CustomerRepository extends Repository<Customer, Long> {
Customer findOne(Long id);
Customer save(Customer customer);
Customer findByEmailAddress(EmailAddress emailAddress);
}
或
@RepositoryDefinition(domainClass=Customer.class, idClass=Long.class)
public interface CustomerRepository { . . . }
// Marker Interface
Spring Data 资源库示例
• 具有 JavaConfig 的 Boostratp
@Configuration
@EnableJpaRepositories
@Import(InfrastructureConfig.class)
public class ApplicationConfig {
}
• 或 XML
<jpa:repositories base-package="com.oreilly.springdata.jpa" />
• Spring 将创建接口实施
Spring Data JPA – 用法
• 正常地融入到事务服务层中
查询方法关键字
• findByEmailAddres 的工作原理…
Spring Data 资源库 – CRUD
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
T save(T entity);
Iterable<T> save(Iterable<? extends T> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
切换、排序和自定义查找程序
public interface PagingAndSortingRepository<T, ID extends Serializable> extends
CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
public interface PersonRepository extends CrudRepository<Person,BigInteger> {
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for a multiple entities
List<Person> findByLastnameLike(String lastName);
// Finder with pagination
Page<Person> findByFirstnameLike(String firstName, Pageable page);
}
Spring Data JPA –自定义查询方法
• 查询方法使用方法命名约定
– 可以用查询注释覆盖
– 或者方法名称引用 JPA 命名的查询
public interface CustomerRepository extends CrudRepository<Customer,Long> {
// previous methods omitted…
@Query("select p from Person p where p.emailAddress = ?1")
Person findByEmailAddress(String emailAddress);
@Query("select p from Person p where p.firstname = :firstname or p.lastname = :lastname")
Person findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}
Spring Data JPA – 其他特性
•
•
•
•
使用 JPA 标准的 API 进行指定
锁定模式,覆盖事务元数据、查询提示
审查、 CDI 集成
支持 QueryDSL
Querydsl 和 JPA
• 更简单、冗长性更低和 JPA2 标准的 API
– “等于属性值”与“属性等于值”
– 通过构建程序对象进行操作
CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();
CriteriaQuery<Person> query = builder.createQuery(Person.class);
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
builder.equal( men.get( Person_.gender ), Gender.MALE ),
builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
Predicate womenRestriction = builder.and(
builder.equal( women.get( Person_.gender ), Gender.FEMALE ),
builder.equal( women.get( Person_.relationshipStatus ),RelationshipStatus.SINGLE )
);
query.where( builder.and( menRestriction, womenRestriction ) );
Querydsl 和 JPA
与…
JPAQuery query = new JPAQuery(entityManager);
QPerson men = new QPerson("men");
QPerson women = new QPerson("women");
Querydsl 判定
query.from(men, women).where(men.gender.eq(Gender.MALE),
men.relationshipStatus.eq(RelationshipStatus.SINGLE),
women.gender.eq(Gender.FEMALE),
women.relationshipStatus.eq(RelationshipStatus.SINGLE));
QueryDSL – 资源库
public interface QueryDSLPredicateExecutor<T>
{
long count(com.mysema.query.types.Predicate predicate);
T findOne(Predicate predicate);
List<T> findAll(Predicate predicate);
List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);
Page<T> findAll(Predicate predicate, Pageable pageable);
}
public interface ProductRepository extends Repository<Product,Long>,
QueryDslPredicateExecutor<Product> { … }
Product iPad = productRepository.findOne(product.name.eq("iPad"));
Predicate tablets = product.description.contains("tablet");
Iterable<Product> result = productRepository.findAll(tablets);
工具支持
代码概览 – JPA
NoSQL 数据模型
键/值
• 比较熟悉,与哈希表格非常类似
• Redis、Riak、Voldemort,…
• 受 Amazon Dynamo 启发
列系列
• 扩展的键/值模型
– 值可以为键/值对
• HBase、Cassandra
• 受 Google Bigtable 启发
文档
• 包含半结构化数据的集合:XML/JSON
• CouchDB、MongoDB
{ id: ‘4b2b9f67a1f631733d917a7b"),’
author: ‘joe’,
tags : [‘example’, ‘db’],
comments : [ { author: 'jim', comment: 'OK' },
{ author: ‘ida', comment: ‘Bad' }
]
{ id: ‘4b2b9f67a1f631733d917a7c"),
author: ‘ida’, ...
{ id: ‘4b2b9f67a1f631733d917a7d"),
author: ‘jim’, ...
图形
• 节点和边缘,每一个可能均具有属性
• Neo4j、Sones、InfiniteGraph
Redis
• 高级键值存储
• 值可以为
– 字符串(例如在普通的键值存储中)。
– 字符串列表,具有 O(1) pop 和 push 操作。
– 字符串集,具有 O(1) 元素添加、删除和存在测试。
– 有序集,类似于集,但是具有可将元素排序的评分。
– 哈希,由设置为字符串值的字符串字段组成。
Redis
• 操作
– 对每种数据类型均具有独特性 – 附加到列表/集,检索列表的
一部分…
– 许多操作在 (1) 时间执行 – 入门级硬件上为 10万操作/秒
– 集的交集、联合、区别
– Redis 是单线程的原子操作
• 可选持久性
• 主从复制
• HA 支持即将推出
Spring Data Redis
• 在多个驱动程序上提供“实际的”API
• RedisTemplate
– 连接资源管理
– 描述性方法名称,分组为数据类型类别
• ListOps、ZSetOps、HashOps…
– 无需处理字节数组
• 支持 Java JDK、字符串、JSON、XML 和自定义序列化
– 转换为 Spring 的 DataAccessException 层次结构
• 以 Redis 为后盾的集、列表、映射、具有限制的集合、原子计数器
• Redis 消息
• Spring 3.1 @Cacheable 支持
RedisTemplate
• 列表操作
@Autowired
RedisTemplate<String, Person> redisTemplate;
Person p = new Person("George", "Carlin");
redisTemplate.opsForList().leftPush("hosts", p);
Redis 支持类
• JDK 集合(java.util 和 java.util.concurrent)
– 列表/集/(阻塞)队列/(阻塞)双队列
Set<String> t = new DefaultRedisSet<String>(“timeline“, connection);
t.add(new Post("john", "Hello World"));
RedisSet<String> fJ = new DefaultRedisSet<String>("john:following", template);
RedisSet<String> fB = new DefaultRedisSet<String>("bob:following", template);
// followers in common
Set s3 = fJ.intersect(fB);
• 原子计数器
– 以 Redis 为后盾的 AtomicLong 和 AtomicInteger
代码概览 – Redis
HBase
• 面向列的数据库
– 指向实际为键值对的“列”
– 列可以全部分组为“列系列”
• 已优化的存储和 I/O
• 存储在模仿 Google BigTable 而来的 HDFS 中的数据
• 需要首先定义列系列的架构
– 列系列内的键值对不用首先定义
使用 HBase
$ ./bin/hbase shell
> create 'users', { NAME => 'cfInfo'}, { NAME => 'cfStatus' }
> put 'users', 'row-1', 'cfInfo:qUser', 'user1'
> put 'users', 'row-1', 'cfInfo:qEmail', '[email protected]'
> put 'users', 'row-1', 'cfInfo:qPassword', 'user1pwd'
> put 'users', 'row-1', 'cfStatus:qEmailValidated', 'true‘
> scan 'users'
ROW COLUMN+CELL
row-1 column=cfInfo:qEmail, timestamp=1346326115599, [email protected]
row-1 column=cfInfo:qPassword, timestamp=1346326128125, value=user1pwd
row-1 column=cfInfo:qUser, timestamp=1346326078830, value=user1
row-1 column=cfStatus:
Configuration configuration = new Configuration(); // Hadoop configuration
object
HTable table = new HTable(configuration, "users");
Put p = new Put(Bytes.toBytes("user1"));
p.add(Bytes.toBytes("cfInfo"), Bytes.toBytes("qUser"), Bytes.toBytes("user1"));
table.put(p);
HBase API
Configuration configuration = new Configuration(); // Hadoop configuration
HTable table = new HTable(configuration, "users");
Put p = new Put(Bytes.toBytes("user1"));
p.add(Bytes.toBytes("cfInfo"), Bytes.toBytes("qUser"),
Bytes.toBytes("user1"));
p.add(Bytes.toBytes("cfInfo"), Bytes.toBytes("qEmail"),
Bytes.toBytes("[email protected]"));
p.add(Bytes.toBytes("cfInfo"), Bytes.toBytes("qPassword"),
Bytes.toBytes("user1pwd"));
table.put(p);
• HTable 类并非线程安全
• 引发特定于 HBase 的异常
Spring Hadoop - HBase
• 配置支持
• HBaseTemplate
– 资源管理
– 转换为 Spring 的 DataAccessException 层次结构
– 轻量对象映射类似于 JdbcTemplate
• RowMapper、ResultsExtractor
– 访问底层资源
• TableCallback
HBaseTemplate – 配置
<configuration id="hadoopConfiguration">
fs.default.name=hdfs://localhost:9000
</configuration>
<hbase-configuration id="hbaseConfiguration"
configuration-ref="hadoopConfiguration" />
<beans:bean id="hbaseTemplate"
class="org.springframework.data.hadoop.hbase.HbaseTemplate">
<beans:property name="configuration" ref="hbaseConfiguration" />
</beans:bean>
HBaseTemplate – 保存
public User save(final String userName, final String email, final String password) {
return hbaseTemplate.execute(tableName, new TableCallback<User>() {
public User doInTable(HTable table) throws Throwable {
User user = new User(userName, email, password);
Put p = new Put(Bytes.toBytes(user.getName()));
p.add(CF_INFO, qUser, Bytes.toBytes(user.getName()));
p.add(CF_INFO, qEmail, Bytes.toBytes(user.getEmail()));
p.add(CF_INFO, qPassword, Bytes.toBytes(user.getPassword()));
table.put(p);
return user;
}
});
}
HBaseTemplate – POJO 映射
private byte[] qUser = Bytes.toBytes("user");
private byte[] qEmail = Bytes.toBytes("email");
private byte[] qPassword = Bytes.toBytes("password");
public List<User> findAll() {
return hbaseTemplate.find(tableName, "cfInfo", new RowMapper<User>() {
@Override
public User mapRow(Result result, int rowNum) throws Exception {
return new User(Bytes.toString(result.getValue(CF_INFO, qUser)),
Bytes.toString(result.getValue(CF_INFO, qEmail)),
Bytes.toString(result.getValue(CF_INFO, qPassword)));
}
});
}
代码概览 – HBase
MongoDB
•
•
•
•
•
•
•
•
文档数据库
– JSON 风格的文档
– 无架构
组织在集合中的文档
全部或部分文档更新
索引支持 – 辅助和复合
动态查询的丰富查询语言
用于高效存储大型文件的 GridFS
地理空间功能
聚合查询的映射/缩减
– 2.2 中的新聚合框架
•
复制和自动分区
Spring Data – MongoDB
• MongoTemplate
– 流畅的查询、标准、更新 API
•
•
•
•
•
•
– 转换为 Spring 的 DataAccessException 层次结构
GridFSTemplate
资源库
QueryDSL
跨存储持久性
JMX
Log4J 登录适配器
MongoOperations 接口
MongoTemplate – 用法
MongoTemplate – MapReduce
• 示例文档
{ "_id" : ObjectId("4e5ff893c0277826074ec533"), "x" : [ "a", "b" ] }
{ "_id" : ObjectId("4e5ff893c0277826074ec534"), "x" : [ "b", "c" ] }
{ "_id" : ObjectId("4e5ff893c0277826074ec535"), "x" : [ "c", "d" ] }
• MapFunction – 对每个字母在数组中出现的次数进行计数
function () {
for (var i = 0; i < this.x.length; i++) {
emit(this.x[i], 1);
}
}
MongoTemplate – MapReduce
• Reduce Function – 计算每个字母在所有文档中出现次数的
总和
function (key, values) {
var sum = 0;
for (var i = 0; i < values.length; i++)
sum += values[i];
return sum;
}
• 执行 MapReduce
MapReduceResults<ValueObject> results = mongoOperations.mapReduce("collection",
"classpath:map.js",
"classpath:reduce.js",
ValueObject.class);
映射注释
• @Document
– 标记要映射到文档的实体(可选)
– 允许对实体应持久保留的集合进行定义
– 集合名称默认为简单的类名称
• @Id
– 区分 ID 属性
– 自动检测到名称 ID 和 _id 的属性
映射注释
• @Index / @CompoundIndex
– 为一个或多个属性创建索引
• @Field
– 允许自定义要在文档内使用的键
– 定义字段顺序
• @DBRef
– 在不同集合内创建实体引用
– 相反于在文档中嵌入实体(默认)
Mongo 资源库
• 与之前 JPA 的相同
• 添加了特定于 MongoDB 的功能
– Geolocation、@Query
public interface ProductRepository extends CrudRepository<Product, Long>,
QueryDslPredicateExecutor<Product> {
Page<Product> findByDescriptionContaining(String description, Pageable pageable);
@Query("{ ?0 : ?1 }")
List<Product> findByAttributes(String key, String value);
}
代码概览 – Mongo
Neo4j
• 图形数据库 – 专注于已连接的数据
– 社交图…
• 无架构的属性图
• ACID 事务
• 索引
• 约 340 亿可扩展的节点和关系,约 1M/遍历/秒
• REST API 或可在 JVN 上嵌入
• 高可用性
• 公布的查询语言 – Cypher
Spring Data Neo4j
• 使用注释定义图形实体
• 以图形数据库为后盾的实
体状态
• JSR-303 Bean 验证
• 查询和遍历 API 支持
• 跨存储持久性
– 部分对象位于 RDBMS,其
他对象位于 Neo4j
•
•
•
•
•
•
异常转换
公布的事务管理
资源库
QueryDSL
Spring XML 命名空间
Neo4j-Server 支持
经典 Neo4j 域类
Spring Data Neo4j 域类
@NodeEntity
public class Tag {
@GraphId private Long id;
@Indexed(unique = true)
private String name;
}
Spring Data Neo4j 域类
@NodeEntity
public class Tag {
@GraphId private Long id;
@Indexed(unique = true)
private String name;
}
• @NodeEntity
– 代表图形中的一个节点
– 另存为节点上属性的字段
– 使用 Java“新”关键字(例
如任何 POJO) 的实例化
– 同样由查询机制返回
– 存储在图形中的类型信息
Spring Data Neo4j 域类
@NodeEntity
public class Customer {
@GraphId private Long id;
private String firstName, lastName;
@Indexed(unique=true)
private String emailAddress;
@RelatedTo(type=“ADDRESS”)
private Set<Address> addresses = new HashSet<Address>();
}
Neo4jTemplate
•
•
•
•
•
•
资源管理
便利方法
公布的事务管理
异常转换为 DataAccessException 层次结构
同样通过具有 Neo4j-Server 的 REST 起作用
多种查询语言
– Cypher、Gremlin
• 流畅的查询结果处理
Neo4jTemplate – 用法
Customer dave = neo4jTemplate.save(new Customer("Dave", "Matthews", "[email protected]"));
Product iPad = neo4jTemplate.save(new Product("iPad", "Apple tablet device").withPrice(499));
Product mbp = neo4jTemplate.save(new Product("MacBook Pro", "Apple notebook").withPrice(1299));
neo4jTemplate.save(new Order(dave).withItem(iPad,2).withItem(mbp,1));
<bean id="graphDatabaseService"
class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
<constructor-arg value="http://localhost:7474/db/data" />
</bean>
<neo4j:config graphDatabaseService="graphDatabaseService" />
• 在应用程序中隐式地创建 Neo4jTemplate 实例
Spring Data REST
• 通过 REST 语义导出 CrudRepository 方法
– PUT, POST = save()
– GET = find*()
– DELETE = delete*()
• 支持作为一流数据格式的 JSON
• JSONP 和 JSONP+E 支持
• 作为 Spring MVC 应用程序实施
Spring Data REST
• 可发现性
– 此级别可用的资源列表中的“GET /”结果
• 资源之间通过“链接”相互关联
– 链接在不同上下文中具有特定的意思
– HTML 和原子联合格式具有 <link rel=“” href=“”/>
• 将 Spring HATEOAS 用作创建表示的基础
– https://github.com/SpringSource/spring-hateoas
Spring Data REST – 示例
curl -v http://localhost:8080/spring-data-rest-webmvc/
{
"links" : [{
"rel" : "person",
"href" : "http://localhost:8080/spring-data-rest-webmvc/person"
}]
}
curl -v http://localhost:8080/spring-data-rest-webmvc/person
{
"content": [ ],
"links" : [ {
"rel" : "person.search",
"href" : "http://localhost:8080/spring-data-rest-webmvc/person/search"
} ]
}
Spring Data REST – 示例
curl -v http://localhost:8080/spring-data-rest-webmvc/person/search
{
"links" : [ {
"rel" : "person.findByName",
"href" : "http://localhost:8080/spring-data-restwebmvc/person/search/findByName"
} ]
}
curl -v http://localhost:8080/spring-data-restwebmvc/person/search/findByName?name=John+Doe
[ {
"rel" : "person.Person",
"href" : "http://localhost:8080/spring-data-rest-webmvc/person/1"
} ]
Spring Data REST – 示例
curl -v http://localhost:8080/spring-data-rest-webmvc/person/1
{
"name" : "John Doe",
"links" : [ {
"rel" : "profiles",
"href" : "http://localhost:8080/spring-data-restwebmvc/person/1/profiles"
}, {
"rel" : "addresses",
"href" : "http://localhost:8080/spring-data-restwebmvc/person/1/addresses"
}, {
"rel" : "self",
"href" : "http://localhost:8080/spring-data-rest-webmvc/person/1"
} ],
"version" : 1
}
Spring for Hadoop – 目标
• Hadoop 现成的编程模型效果
较差
•
•
通过提供熟悉并一致的编程和配置
模型
可用于多种使用情形
– HDFS 使用
– 数据分析
(MR/Pig/Hive/Cascading)
• 应用程序通常为调用命令行应用
的脚本集合
•
•
• Spring 简化了 Hadoop 应用程
序的开发
–
–
•
PigTemplate
HiveTemplate
工作流 (Spring Batch)
事件流 (Spring Integration)
让您能够从小处开始并取得发展
与其他 Spring 项目的关系
书籍
免费的 Spring Data JPA 章节 – http://bit.ly/sd-book-chapter
O’Reilly Spring Data 书籍 – http://bit.ly/sd-book
资源
• Spring Data
– http://www.springsource.org/spring-data
– http://www.springsource.org/spring-hadoop
• Querydsl
– http://www.querydsl.com
• 示例代码
– https://github.com/SpringSource/spring-data-book
– https://github.com/SpringSource/spring-data-kickstart
– 各个项目页面上列出了更多示例
谢谢!