spring data 简介
DESCRIPTION
Spring Data 简介. Mark Pollack 博士. 议题. 当前的数据形态 项目目标 项目概览. 企业数据趋势. 企业数据趋势. 非结构化数据 无预定义的数据模型 经常不大适合于 RDBMS 预聚合数据 在数据收集期间进行计算 计数器 运行平均数. 数据的价值. Mozilla/5.0 ( Macintosh ; U ; Intel Mac OS X; en ) AppleWebKit/418.9 ( KHTML ,比如 Gecko ) Safari/419.3. 数据的价值超越了软硬件成本 连接数据集的价值 - PowerPoint PPT PresentationTRANSCRIPT
Spring Data 简介Mark Pollack 博士
• 当前的数据形态• 项目目标• 项目概览
议题
2
企业数据趋势
3
企业数据趋势
4
非结构化数据•无预定义的数据模型•经常不大适合于 RDBMS
预聚合数据•在数据收集期间进行计算•计数器•运行平均数
• 数据的价值超越了软硬件成本
• 连接数据集的价值– 通过用户代理程序将电子商务用户组合起来
数据的价值
5
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 …
数据革命
6
NoSQL
7
“不仅仅 SQL”NOSQL \no-seek-wool\ n. 描述当下的趋势,即开发人员越多越多地选择用非关系数据库来帮助解决其问题,试图使用合适的工具来完成合适的工作。
查询机制
关键字查询、映射缩减、按示例查询、查询语言、遍历
• “大数据”是指规模过大,以至一般数据库软件工具无法进行数据捕获、存储、管理和分析的数据集。
• 一个主观性和不断移动的目标。• 当今许多领域中的大数据的大小范围为从几十个 TB 到多
个 PB
大数据
8
现实检验
9
现实检验
10
项目目标
11
• 数据访问形态已经发生天翻地覆的变化• RDBMS 仍然占据重要和支配性的地位
– 但不再被视作“万金油”解决方案• 但 RMBMS 具有局限性
– 难以扩展• 新的数据访问技术正在解决 RMBMS 所无法解决的问题
– 更高的性能和可扩展性,不同的数据模型– 常常受到限制的事务模型和松弛的一致性
• 坚持使用多种语言变得更普遍– 在一个解决方案中将 RDBMS 与其他数据库相结合
Spring Data – 背景和动机
12
• Spring 一直提供出色的数据访问支持– 事务管理– 可移植的数据访问异常层次结构– JDBC – JdbcTemplate– ORM – 支持 Hibernate 、 JPA 、 JDO 、 Ibatis– 支持缓存 (Spring 3.1)
• Spring Data 项目于 2010 年启动• 目标是“刷新” Spring 的数据访问支持
– 参照新的数据访问形态
Spring 和数据访问
Spring Data 使命声明
14
89% of all virtualized applications in the world run on VMware.
Gartner, December 2008“为大数据、 NoSQL 和关系存储提供熟
悉、一致且基于 Spring 的编程模型,同时保留特定于存储的特性和功能。
Spring Data 使命声明
15
89% of all virtualized applications in the world run on VMware.
Gartner, December 2008“为大数据、 NoSQL 和关系存储提供
熟悉、一致且基于 Spring 的编程模型,同时保留特定于存储的特性和功能。
Spring Data 使命声明
16
89% of all virtualized applications in the world run on VMware.
Gartner, December 2008“特定于存储的特性和功能。
• 关系型– JPA– JDBC 扩展
• NoSQL– Redis– HBase– Mongo– Neo4j– Lucene– Gemfire
• 大数据– Hadoop
• HDFS 和 M/R• Hive• Pig• Cascading
– Splunk
• 访问– 资源库– QueryDSL
– REST
Spring Data – 支持的技术
17
• 通过熟悉的 Spring 模板样式访问特定于数据库的特性– RedisTemplate– HBaseTemplate– MongoTemplate– Neo4jTemplate– GemfireTemplate
• 共享的编程模型和数据访问机制– 资源库模型
• 跨数据存储的公用 CRUD
– 与 QueryDSL 集成• 类型安全的查询语言
– REST 导出器• 以基于 REST 的方式通过
HTTP 公开资源库。
Spring Data – 一切由您做主
项目概览
19
JDBC 和 JPA
• 快速连接故障转移• 高级队列 JMS 支持和数据源的
简化配置• 消息传送和数据库访问的单一本
地事务
• 轻松访问本机 XML 、 Struct 、 Array 数据类型
• 用于自定义连接环境的 API
Spring Data JDBC 扩展 – Oracle 支持
QueryDSL
22
“支持为多个后端(包括 JPA 、 JDO 、MongoDB 、 Lucence 、 SQL 和 Java 中的普通集合)构造类型安全的类似 SQL 的查询
http://www.querydsl.com/ - 开源, Apache 2.0
• 使用字符串容易出错• 必须记住查询语法、域类、属性和关系• 按照名称或位置的冗长参数绑定• 每个后端都拥有其自身的查询语言和 API• 注释: .NET 含有 LINQ
使用字符串作为查询语言的问题
• 在 IDE 中完成编码• 几乎完全禁止语法无效的查询• 域类型和属性可以安全引用(无字符串)• 通过 Java 注释处理程序生成帮助程序类• 冗长性远小于 JPA2 标准的 API
QueryDSL 特性
24
QCustomer customer = QCustomer.customer;JPQLQuery query = new JPAQuery(entityManger)Customer bob = query.from(customer) .where(customer.firstName.eq(“Bob”) .uniqueResult(customer)
• 将代码生成融入到构建流程中– 以创建域类或表格 (JDBC) 的查询元数据模型
• 对于 SQL
将 QueryDSL 用于 JDBC
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 判定
• 支持的 JdbcTemplate 打包程序– 使用 Querydsl SQLQuery 类来执行查询– 与 Spring 的事务管理集成– 自动检测数据库类型并设置 SQLTemplates 方言– 用于映射到 POJO 的 Spring RowMapper 和 ResultSetExtractors
– 通过 Querds 的 SQLInsertClause 、 SQLUpdateClause 和 SQLDeleteClause 执行插入、更新和删除
Spring JDBC 扩展 – QueryDslJdbcTemplate
Spring JDBC 扩展 – QueryDslJdbcTemplate// Query with joinQCustomer qCustomer = QCustomer.customer;SQLQuery findByIdQuery = qdslTemplate.newSqlQuery()
.from(qCustomer)
.leftJoin(qCustomer._addressCustomerRef, qAddress)
.where(qCustomer.id.eq(id));
JPA 和资源库
28
资源库
29
通过使用类似集合的接口来访问域对象,在域和数据映射层之间进行调解。http://martinfowler.com/eaaCatalog/repository.html
• 有了 Spring Data 资源库,您将不必忙于开发资源库
Spring Data 资源库
30
例如…public interface CustomerRepository {
Customer findOne(Long id);
Customer save(Customer customer);
Customer findByEmailAddress(EmailAddress emailAddress);}
@Entitypublic 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 实施@Repositorypublic 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(); }}
• 简单的方法1. 使用 JPA 来映射 POJO
2. 扩展资源库(标记)接口或使用注释3. 添加查询程序方法4. 配置 Spring 来扫描资源库接口并创建实施
• 将实施注入到服务中,并正常使用…
Spring Data 资源库
Spring Data 资源库示例
或
public interface CustomerRepository extends Repository<Customer, Long> { // Marker Interface
Customer findOne(Long id);
Customer save(Customer customer);
Customer findByEmailAddress(EmailAddress emailAddress);}
@RepositoryDefinition(domainClass=Customer.class, idClass=Long.class)public interface CustomerRepository { . . . }
• 具有 JavaConfig 的 Boostratp
• 或 XML
• Spring 将创建接口实施
Spring Data 资源库示例
@Configuration@EnableJpaRepositories@Import(InfrastructureConfig.class)public class ApplicationConfig {
}
<jpa:repositories base-package="com.oreilly.springdata.jpa" />
• 正常地融入到事务服务层中
Spring Data JPA – 用法
• findByEmailAddres 的工作原理…
查询方法关键字
Spring Data 资源库 – CRUD
39
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();}
切换、排序和自定义查找程序
40
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);}
• 查询方法使用方法命名约定– 可以用查询注释覆盖– 或者方法名称引用 JPA 命名的查询
Spring Data JPA –自定义查询方法
• 使用 JPA 标准的 API 进行指定• 锁定模式,覆盖事务元数据、查询提示• 审查、 CDI 集成• 支持 QueryDSL
Spring Data JPA – 其他特性
42
• 更简单、冗长性更低和 JPA2 标准的 API– “等于属性值”与“属性等于值”– 通过构建程序对象进行操作
Querydsl 和 JPA
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");
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 判定
QueryDSL – 资源库
45
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);
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);
}
工具支持
46
代码概览 – JPA
47
NoSQL 数据模型
48
• 比较熟悉,与哈希表格非常类似• Redis 、 Riak 、 Voldemort,…• 受 Amazon Dynamo 启发
键 / 值
49
• 扩展的键 / 值模型– 值可以为键 / 值对
• HBase 、 Cassandra• 受 Google Bigtable 启发
列系列
• 包含半结构化数据的集合: XML/JSON• CouchDB 、 MongoDB
文档
51
{ 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
图形
52
• 高级键值存储• 值可以为
– 字符串(例如在普通的键值存储中)。– 字符串列表,具有 O(1) pop 和 push 操作。– 字符串集,具有 O(1) 元素添加、删除和存在测试。– 有序集,类似于集,但是具有可将元素排序的评分。– 哈希,由设置为字符串值的字符串字段组成。
Redis
53
• 操作– 对每种数据类型均具有独特性 – 附加到列表 / 集,检索列表的
一部分…– 许多操作在 (1) 时间执行 – 入门级硬件上为 10 万操作 /秒– 集的交集、联合、区别– Redis 是单线程的原子操作
• 可选持久性• 主从复制• HA 支持即将推出
Redis
54
• 在多个驱动程序上提供“实际的” API• RedisTemplate
– 连接资源管理– 描述性方法名称,分组为数据类型类别
• ListOps、 ZSetOps、 HashOps…
– 无需处理字节数组• 支持 Java JDK 、字符串、 JSON 、 XML 和自定义序列化
– 转换为 Spring 的 DataAccessException 层次结构• 以 Redis 为后盾的集、列表、映射、具有限制的集合、原子计数器• Redis 消息• Spring 3.1 @Cacheable 支持
Spring Data Redis
55
• 列表操作
RedisTemplate
56
@AutowiredRedisTemplate<String, Person> redisTemplate;
Person p = new Person("George", "Carlin");redisTemplate.opsForList().leftPush("hosts", p);
• JDK 集合( java.util 和 java.util.concurrent)– 列表 / 集 /(阻塞)队列 /(阻塞)双队列
• 原子计数器– 以 Redis 为后盾的 AtomicLong 和 AtomicInteger
Redis 支持类
57
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 commonSet s3 = fJ.intersect(fB);
代码概览 – Redis
58
• 面向列的数据库– 指向实际为键值对的“列”– 列可以全部分组为“列系列”
• 已优化的存储和 I/O
• 存储在模仿 Google BigTable 而来的 HDFS 中的数据• 需要首先定义列系列的架构
– 列系列内的键值对不用首先定义
HBase
59
使用 HBase
60
$ ./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+CELLrow-1 column=cfInfo:qEmail, timestamp=1346326115599, [email protected] column=cfInfo:qPassword, timestamp=1346326128125, value=user1pwdrow-1 column=cfInfo:qUser, timestamp=1346326078830, value=user1row-1 column=cfStatus:
Configuration configuration = new Configuration(); // Hadoop configuration objectHTable 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);
• HTable 类并非线程安全• 引发特定于 HBase 的异常
HBase API
61
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);
• 配置支持• HBaseTemplate
– 资源管理– 转换为 Spring 的 DataAccessException 层次结构– 轻量对象映射类似于 JdbcTemplate
• RowMapper 、 ResultsExtractor
– 访问底层资源• TableCallback
Spring Hadoop - HBase
62
HBaseTemplate – 配置
63
<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 – 保存
64
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 映射
65
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
66
• 文档数据库– JSON 风格的文档– 无架构
• 组织在集合中的文档• 全部或部分文档更新• 索引支持 – 辅助和复合• 动态查询的丰富查询语言• 用于高效存储大型文件的 GridFS• 地理空间功能• 聚合查询的映射 / 缩减
– 2.2 中的新聚合框架• 复制和自动分区
MongoDB
67
• MongoTemplate– 流畅的查询、标准、更新 API
– 转换为 Spring 的 DataAccessException 层次结构• GridFSTemplate• 资源库• QueryDSL• 跨存储持久性• JMX• Log4J 登录适配器
Spring Data – MongoDB
68
MongoOperations 接口
69
MongoTemplate – 用法
70
• 示例文档
• MapFunction – 对每个字母在数组中出现的次数进行计数
MongoTemplate – MapReduce
71
{ "_id" : ObjectId("4e5ff893c0277826074ec533"), "x" : [ "a", "b" ] }{ "_id" : ObjectId("4e5ff893c0277826074ec534"), "x" : [ "b", "c" ] }{ "_id" : ObjectId("4e5ff893c0277826074ec535"), "x" : [ "c", "d" ] }
function () { for (var i = 0; i < this.x.length; i++) { emit(this.x[i], 1); }}
• Reduce Function – 计算每个字母在所有文档中出现次数的总和
• 执行 MapReduce
MongoTemplate – MapReduce
72
function (key, values) { var sum = 0; for (var i = 0; i < values.length; i++) sum += values[i]; return sum;}
MapReduceResults<ValueObject> results = mongoOperations.mapReduce("collection", "classpath:map.js",
"classpath:reduce.js", ValueObject.class);
• @Document– 标记要映射到文档的实体(可选)– 允许对实体应持久保留的集合进行定义– 集合名称默认为简单的类名称
• @Id– 区分 ID 属性– 自动检测到名称 ID 和 _id 的属性
映射注释
73
• @Index / @CompoundIndex– 为一个或多个属性创建索引
• @Field– 允许自定义要在文档内使用的键– 定义字段顺序
• @DBRef– 在不同集合内创建实体引用– 相反于在文档中嵌入实体(默认)
映射注释
74
• 与之前 JPA 的相同• 添加了特定于 MongoDB 的功能
– Geolocation 、 @Query
Mongo 资源库
75
代码概览 – Mongo
76
• 图形数据库 – 专注于已连接的数据– 社交图…
• 无架构的属性图• ACID 事务• 索引• 约 340 亿可扩展的节点和关系,约 1M/ 遍历 /秒• REST API 或可在 JVN 上嵌入• 高可用性• 公布的查询语言 – Cypher
Neo4j
77
• 使用注释定义图形实体• 以图形数据库为后盾的实体状态
• JSR-303 Bean 验证• 查询和遍历 API 支持• 跨存储持久性
– 部分对象位于 RDBMS ,其他对象位于 Neo4j
• 异常转换• 公布的事务管理• 资源库• QueryDSL• Spring XML 命名空间• Neo4j-Server 支持
Spring Data Neo4j
78
经典 Neo4j 域类
79
Spring Data Neo4j 域类
80
@NodeEntitypublic class Tag { @GraphId private Long id; @Indexed(unique = true) private String name;}
• @NodeEntity– 代表图形中的一个节点– 另存为节点上属性的字段– 使用 Java“ 新”关键字(例
如任何 POJO) 的实例化– 同样由查询机制返回– 存储在图形中的类型信息
Spring Data Neo4j 域类
81
@NodeEntitypublic class Tag { @GraphId private Long id; @Indexed(unique = true) private String name;}
Spring Data Neo4j 域类
82
@NodeEntitypublic 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>();}
• 资源管理• 便利方法• 公布的事务管理• 异常转换为 DataAccessException 层次结构• 同样通过具有 Neo4j-Server 的 REST 起作用• 多种查询语言
– Cypher 、 Gremlin
• 流畅的查询结果处理
Neo4jTemplate
83
• 在应用程序中隐式地创建 Neo4jTemplate 实例
Neo4jTemplate – 用法
84
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" />
• 通过 REST 语义导出 CrudRepository 方法– PUT, POST = save()
– GET = find*()
– DELETE = delete*()
• 支持作为一流数据格式的 JSON• JSONP 和 JSONP+E 支持• 作为 Spring MVC 应用程序实施
Spring Data REST
85
• 可发现性– 此级别可用的资源列表中的“ GET /” 结果
• 资源之间通过“链接”相互关联– 链接在不同上下文中具有特定的意思– HTML 和原子联合格式具有 <link rel=“” href=“”/>
• 将 Spring HATEOAS 用作创建表示的基础– https://github.com/SpringSource/spring-hateoas
Spring Data REST
86
Spring Data REST – 示例
87
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 – 示例
88
curl -v http://localhost:8080/spring-data-rest-webmvc/person/search
{ "links" : [ { "rel" : "person.findByName", "href" : "http://localhost:8080/spring-data-rest-webmvc/person/search/findByName" } ]}
curl -v http://localhost:8080/spring-data-rest-webmvc/person/search/findByName?name=John+Doe
[ { "rel" : "person.Person", "href" : "http://localhost:8080/spring-data-rest-webmvc/person/1"} ]
Spring Data REST – 示例
89
curl -v http://localhost:8080/spring-data-rest-webmvc/person/1
{ "name" : "John Doe", "links" : [ { "rel" : "profiles", "href" : "http://localhost:8080/spring-data-rest-webmvc/person/1/profiles" }, { "rel" : "addresses", "href" : "http://localhost:8080/spring-data-rest-webmvc/person/1/addresses" }, { "rel" : "self", "href" : "http://localhost:8080/spring-data-rest-webmvc/person/1" } ], "version" : 1}
• Hadoop 现成的编程模型效果较差
• 应用程序通常为调用命令行应用的脚本集合
• Spring 简化了 Hadoop 应用程序的开发
• 通过提供熟悉并一致的编程和配置模型
• 可用于多种使用情形– HDFS 使用– 数据分析
(MR/Pig/Hive/Cascading)• PigTemplate• HiveTemplate
– 工作流 (Spring Batch)– 事件流 (Spring Integration)
• 让您能够从小处开始并取得发展
Spring for Hadoop – 目标
90
与其他 Spring 项目的关系
91
书籍
92
免费的 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– 各个项目页面上列出了更多示例
资源
93
谢谢!