`
liufei.fir
  • 浏览: 687401 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring Data —— 完全统一的API?

阅读更多
Spring Data 作为SpringSource的其中一个父项目, 旨在统一和简化对各类型持久化存储, 而不拘泥于是关系型数据库还是NoSQL 数据存储。
相关厂商内容

白皮书下载:JBoss Enterprise Application Platform 6迁移指南

白皮书下载:利用您的私有或混合云加速业务成果

Amazon五星敏捷图书作者、敏捷教练Amr Elssamadisy确认参加2012QCon杭州!

腾讯Web前端团队TAT(Tencent Alloy Team)负责人屈超确认参加2012QCon杭州!

去哪儿网自动化测试专家,《自动化软件测试实施指南》译者余昭辉确认参加2012QCon杭州!
相关赞助商

QCon杭州2012大会10月25~27,9月15日前报名享受8折优惠,5人以上团购享有更多优惠!

无论是哪种持久化存储, 数据访问对象(或称作为DAO,即Data Access Objects)通常都会提供对单一域对象的CRUD (创建、读取、更新、删除)操作、查询方法、排序和分页方法等。Spring Data则提供了基于这些层面的统一接口(CrudRepository,PagingAndSortingRepository)以及对持久化存储的实现。

你可能接触过某一种Spring 模型对象——比如JdbcTemplate——来编写访问对象的实现。基于Spring Data的数据访问对象, 我们只需定义和编写一些查询方法的接口(基于不同的持续化存储, 定义有可能稍有不同)。Spring Data会在运行时间生成正确的实现。 请看下面的例子:

public interface UserRepository extends MongoRepository<User, String> {         @Query("{ fullName: ?0 }")         List<User> findByTheUsersFullName(String fullName);         List<User> findByFullNameLike(String fullName, Sort sort); } ... Autowired UserRepository repo;

本文将比较两个JPA的子项目, MongoDB和Neo4j。JPA是J2EE的一部分, 它定义了一系列用于操作关系型数据库和O/R映射的API。 MongoDB是一种可扩展的、高性能的、开源的、面向文档的数据库。Neo4j则是一种图形数据库,一种完整的用于存储图形数据的事务性数据库。

所有这些Spring Data的子项目都支持:

    模板
    对象、数据存储映射
    对数据访问对象的支持

其他一些Spring Data 子项目,如Spring Data Redis和Spring Data Riak都只是提供模板, 这是由于其相应的数据存储都只支持非结构化的数据,而不适用于对象的映射和查询。

下面,我们来深入了解一下模板、对象数据映射和数据访问对象。
模板

Spring Data 模板的主要目的, 同时也是所有其他Spring 模板的目的, 就是资源分配和异常处理。

这里所说的资源就是数据存储资源, 通常来说会通过远程TCP/IP连接访问。下面的实例展示了如果配置MongoDB的模板:

<!-- Connection to MongoDB server --> <mongo:db-factory host="localhost" port="27017" dbname="test" /> <!-- MongoDB Template --> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean>

首先我们需要定义连接工厂,MongoTemplate会引用这个连接工厂。这个例子中, Spring Data采用了较底层的数据库驱动,MongoDB Java driver。

一般来说, 这类较底层的数据库驱动会有自己的一套异常处理策略。 Spring的异常处理采用的是未检查异常(unchecked exception),因此开发人员可以自己决定是否须要捕获异常。MongoDB的模板的实现方式是把捕获到的底层的异常封装成未检查异常, 这些异常都是Spring里DataAccessException的子类。

模板提供了基于数据存储的操作, 诸如保存、更新、删除单一记录或执行查询的方法。但所有这些方法只能用于相应的底层数据存储。

由于JPA的实现本身已经是位于JDBC API上层的抽象层,Spring Data JPA 并没有提供模板。和模板概念相对应的是JPA的EntityManager, 而异常处理则是由数据访问对象来负责的。
对象、数据映射

JPA引入了O/R映射的标准(如关系型数据库中表和对象的映射)。Hibernate很有可能是被最为广泛使用的JPA标准的实现。

Spring Data采用类对象的方式将O/R映射的支持延伸到了NoSQL数据库。但在各种NoSQL数据库中, 数据结构差异较大, 所以很难形成一种通用的API。 每一种数据存储都有各自一套注释用以标注映射所需要的元信息。下面我们来看一个简单的例子,如何映射一个简单领域对象:
JPA MongoDB Neo4j
@Entity
@Table(name="TUSR")
public class User {
    @Id
    private String id;
    @Column(name="fn")
    private String name;
    private Date lastLogin;
...
} @Document(collection="usr")
public class User {
    @Id
    private String id;
    @Field("fn")
    private String name;
    private Date lastLogin;
    ..
} @NodeEntity
public class User {
    @GraphId
    Long id;
    private String name;
    private Date lastLogin;
...
}

如果你已经熟悉JPA实体,不难看出这里用了标准的JPA注释。Spring Data复用了这些标准的注释, 而且没有引入其他新的内容。对象的映射正是由这些JPA的实现完成的。 MangoDB和Neo4j各种需要一套类似的注释。在上面的例子中, 我们使用了类级别的注释collection和nodetype. MangoDB中, collection就相当于关系型数据库的表, 而node和edge则是图形数据库(如Neo4j)的主要数据类型。

每个JPA实体都需要有唯一标识符,即便是MongoDB的文档和Neo4j的节点也是如此。

MongoDB使用@Id这个注释作为唯一标识符(这@Id是在org.springframework.data.annotation包中, 和JPA的@Id并不相同)。Neo4j则使用了@GraphId这个注释。这些属性的值是在域对象成功存储后被设置的。 当类属性的名称和MongoDB的文档中的属性名称不同时, 可以使用@Field注释标注。

同样这两种映射也支持对其他对象的引用,请看下面的例子:
JPA MongoDB Neo4j
@OneToMany
private List<Role> roles; private List<Role> roles; @RelatedTo( type = "has", direction = Direction.OUTGOING)
private List<Role> roles;

在JPA中, 我们使用@OneToMany来标识一对多的关系, 通常多的一端的数据存放在子表中, 通过联合查询获得。MongoDB并不支持文档间的联合查询,默认情况下, 被引用的对象和主对象存储在同一个文档中。当然, 我们也可以通过客户端的虚拟联合查询引用其他文档的数据。在Neo4j中, 关系被称作edges, 而edge也是一个基本的数据类型。

总结来说, MongoDB和Neo4j所使用的对象映射和我们大家所熟悉的JPA O/R映射非常类似, 但由于不同的数据结构,两者存在着显著的区别。但不管怎么说, 基本概念都是实现对象和数据结构的映射。
数据访问对象

你一定写过这样的DAO对象,针对单一记录的CRUD操作、针对多记录的CRUD操作, 基于各种查询条件的查询方法。

随着JPA的引入, 虽然EntityManager接口已经包含了CRUD操作,但 编写查询方法仍然是一件麻烦事, 为此, 完成一次查询需要创建命名查询, 设置参数, 执行查询。请看下面的例子:

@Entity @NamedQuery( name="myQuery", query = "SELECT u FROM User u where u.name = :name" ) public class User { ... } @Repository public class ClassicUserRepository { @PersistenceContext EntityManager em; public List<User> findByName(String Name) { TypedQuery<User> q = getEntityManger().createNamedQuery("myQuery", User.class); q.setParameter("name", fullName); return q.getResultList(); } ...

TypedQuery可以略微简化这个过程,如:

@Repository public class ClassicUserRepository { @PersistenceContext EntityManager em; public List<User> findByName(String name) { return getEntityManger().createNamedQuery("myQuery", User.class) .setParameter("name", fullName) .getResultList(); } ...

我们仍然须要编写类似这样的查询方法,为查询赋值, 执行查询。如果可以引入Spring Data JPA,要实现这类的查询, 编码就可以大大简化, 如下:

package repositories; public interface UserRepository extends JpaRepository<User, String> { List<User> findByName(String name); }

在Spring Data JPA中, 我们将不再需要在JPA实体类中定义@NamedQuerys, 来实现JPQL的查询。 相反, 我们可以为数据访问对象的各方法加上@Query这样的注释。如:

@Transactional(timeout = 2, propagation = Propagation.REQUIRED) @Query("SELECT u FROM User u WHERE u.name = 'User 3'") List<User> findByGivenQuery();

Spring Data MongoDB和Spring Data Neo4j可以使上述方法同样适用于MangoDB和Neo4j数据库。下面的例子的是通过Cipher查询语言来实现对Neo4j数据库的查询。

public interface UserRepository extends GraphRepository<User> { User findByLogin(String login); @Query("START root=node:User(login = 'root') MATCH root-[:knows]->friends RETURN friends") List<User> findFriendsOfRoot(); }

当然,各个持久化层的方的命名规则稍有差异。比如说, MongoDB支持一种叫geospatial queries的查询语言, 通常我们可以这样写查询:

public interface LocationRepository extends MongoRepository<Location, String> { List<Location> findByPositionWithin(Circle c); List<Location> findByPositionWithin(Box b); List<Location> findByPositionNear(Point p, Distance d); }

Spring Data也提供对分页和排序的通用方法,这需要在查询方法中加入特殊的参数。

支持数据访问对象的优势在于:

    减少相似代码的编写
    定义方法的同时, 可以定义查询语句,这也使文档变得更清晰
    另外一个优点是, 查询语句将和Spring上下文同时编译并组装,而不是在初次使用的时候编译, 这样可以大大减少代码编写中的语法错误。

总结

本文只是简单介绍了Spring Data 的这些新内容, 意在阐明和普通JPA的相似点和不同之处。下面这些链接可以帮助大家对Spring Data的相关项目做更输入的了解。

    Spring Data JPA
    Spring Data MongoDB
    Spring Data Neo4j

对标题中问题的回答显然是否定的, 不可能存在支持所有持久存储的通用API, 其原因也是不言而喻的。Spring Data 项目旨在为大家提供一种通用的编码模式。

数据访问对象实现了对物理数据层的抽象, 为编写查询方法提供了方便。通过对象映射, 实现域对象和持续化存储之间的转换, 而模板提供的是对底层存储实体的访问实现。
分享到:
评论

相关推荐

    SpringDataRedis的jar包.rar

    Spring Data Redis提供了丰富的API,使得在Spring应用程序中操作Redis变得非常便捷。 首先,让我们了解Spring Data Redis的核心特性: 1. **自动配置**:Spring Boot通过自动配置类`RedisAutoConfiguration`和`...

    商城项目——goods-api

    【标题】"商城项目——goods-api"所涉及的是一个电商系统的商品管理API接口部分,它主要负责处理与商品相关的各种操作,包括但不限于商品的创建、删除、更新以及查询等核心功能。在电商平台上,商品是交易的核心元素...

    spring-data源码

    在本篇文章中,我们将聚焦于Spring Data的一个重要模块——Spring Data Elasticsearch,这是针对流行搜索引擎Elasticsearch的Java开发插件。通过对Spring Data Elasticsearch 2.1.10.RELEASE的源码分析,我们可以...

    spring-data + jedis + redis代码

    Spring Data是一个模块化的项目,它的主要目标是通过提供统一的API来减少数据访问层的开发工作。这个框架支持多种数据存储,包括MongoDB、Hadoop、Cassandra等,以及我们的关注点——Redis。Spring Data Redis模块...

    spring-data-redis最新架包

    Spring Data Redis的核心目标是简化Redis操作,提供一套统一的API,覆盖了Redis的各种数据结构,如字符串、哈希、列表、集合和有序集合。通过使用Spring Data Redis,开发者可以避免直接与Redis命令行交互,而是通过...

    spring data jpa 动态更新@DynamicUpdate

    在Java世界中,Spring Data JPA是一个非常流行的框架,它为开发者提供了与关系数据库交互的便利,通过简化JPA(Java Persistence API)的使用。在处理大量数据时,提高性能和效率是至关重要的,这就是`@...

    spring——第十四节素材.rar

    Spring Data JPA则是Spring提供的一个模块,用于简化JPA(Java Persistence API)的使用,使数据访问层的编写变得更加便捷。 Spring Security则专注于提供安全解决方案,包括认证(验证用户身份)和授权(控制用户...

    Spring4.1.5-javadoc-api.rar

    数据访问与集成(Data Access/Integration)模块是Spring处理数据库操作的关键,包括JDBC、ORM(对象关系映射)支持如Hibernate、MyBatis等,以及JPA(Java Persistence API)。Spring MVC作为Web开发的一部分,提供...

    spring-data-redis-1.6.0.RELEASE.jar + jedis-2.7.2.jar包

    Spring Data Redis使得在应用程序中集成Redis变得简单,提供了丰富的API和抽象层,让开发者能够利用Redis的高速缓存、持久化和分布式特性。这个“spring-data-redis-1.6.0.RELEASE.jar”是该库的特定版本,1.6.0....

    spring data jpa -reference 使用指南(2014年9月版)

    Spring Data JPA是Spring Data项目的一个模块,它提供了一种简单的方式来与JPA(Java Persistence API)实体进行交互。该指南详细介绍了如何定义和使用存储库接口,以及如何通过声明式方法来执行常见的数据访问操作...

    用MongoDB和Spring_Data创建Java应用

    Spring Data,则是Spring框架旗下的一系列子项目之一,旨在简化数据访问层的开发,提供统一的编程模型来操作各种类型的数据存储,包括关系型数据库和NoSQL数据库。 #### Spring Data for MongoDB详解 Spring Data ...

    spring-boot-redis-annotation-demo:spring boot —— redis 缓存注解使用示例项目

    spring boot —— redis 缓存注解使用教程 示例项目地址: 依赖 在pom文件添加如下依赖 &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-starter-data-redis 配置 在application.yml配置文件添加...

    spring boot整合JPA——demo

    Spring Boot 整合 JPA(Java Persistence API)是现代Java应用程序中常见的数据访问技术,它提供了简化数据库操作的抽象层,让开发者可以更专注于业务逻辑而不是底层的SQL语句。本示例“spring boot整合JPA——demo...

    java面试——SpringCloud面试专题.zip

    3. **Zuul边缘服务与API网关**:Zuul是Spring Cloud中的边缘服务和API网关,负责路由转发、过滤器处理、限流、熔断等,起到保护内部服务和提供统一入口的作用。 4. **Hystrix断路器**:Hystrix是Netflix开源的容错...

    Spring Data JPA中文文档[1.4.3]

    SpringData扩展部分主要介绍了对Web层面的支持,如DomainClassConverter将领域类转换为控制器参数,HandlerMethodArgumentResolver参数解析器等。还包括了Repository填充、LegacyWebSupport,以及如何在SpringMVC中...

    pring-data-redisjar和源文件

    1. **Jedis和Lettuce客户端**:Spring Data Redis支持两种主流的Redis Java客户端——Jedis和Lettuce。Jedis轻量级且稳定,适合小规模应用;Lettuce则提供了更丰富的功能和更好的可扩展性,适合大型分布式系统。 2....

    方志朋版——深入理解Spring Cloud与微服务构建.pdf

    最后,书中可能还会涵盖Spring Cloud Gateway,它是Spring Cloud的新一代API网关,相比Zuul,它提供了更强大的路由规则和过滤器功能。 总的来说,这本《深入理解Spring Cloud与微服务构建》将带领读者深入探索...

    spring——mvc

    Spring MVC 是一款基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的重要组成部分,主要用于构建 ...随着经验的增长,可以进一步探索 Spring Security、Spring Data、Spring Boot 等高级特性,提升你的开发技能。

    征服 Redis + Jedis + Spring (三)—— 列表操作

    总的来说,“征服 Redis + Jedis + Spring (三)—— 列表操作”这个主题涵盖了 Redis 的列表数据类型、Jedis 的客户端操作以及 Spring Data Redis 提供的高级抽象。理解并掌握这些知识点,将有助于你在开发过程中...

Global site tag (gtag.js) - Google Analytics