美文网首页
Spring Boot Mongo (一)

Spring Boot Mongo (一)

作者: luokaiii | 来源:发表于2018-08-16 16:32 被阅读0次

前言

Spring Data

Spring MongoDB 与Spring Framewrok 提供的 JDBC 十分相似,在熟悉本篇文章之前,需要先熟悉 MongoDB 和Spring 的概念

Spring Data 使用了 Spring 框架的核心功能,包括:

  • IOC容器 (IOC container)
  • 类型转换系统 (type conversion system)
  • EL表达式 (expression language)
  • JMX集成
  • Dao异常层次结构

MongoDB

MongoDB作为一种 NOSQL 工具,非 RDMBS 设计范式,官方文档:https://docs.mongodb.com/manual/reference/operator/query/in/index.html

RDMBS设计范式:http://blog.51cto.com/echoroot/1953996

Spring Data MongoDB 2.0

  • 升级至 java8
  • 使用 Document API,而非 DBObject
  • 支持聚合结果流 Stream
  • Kotlin 扩展
  • 支持隔离 Update 操作
  • 使用 Spring 的 @NonNullApi 和 @Nullable 保证 Null 安全

Spring Data MongoDB 支持的注解

@Document   : 文档标识,将 java 类与 Collection 文档对应
@Id         : 文档的唯一标识,在 mongodb 中为 ObjectID,生成规则:时间戳+机器标识+进程ID+自增计数器(确保同一时间内ID不会冲突)
@Field      : 属性注解
@Indexed    : 索引
@CompoundIndex  : 混合索引
@GeoSpatialIndexed  : 声明该字段为地理信息的索引
@Transient  : 映射忽略的字段 (即不会保存到 mongodb)
@Query      :查询

依赖

在使用 SpringDataMongoDB 之前,需要先声明对 SpringData 模块的依赖关系。

既然 SpringData 存储库抽象中的中央接口是 Repository 。 该接口的子类 CrudRepository 实现了实体类的 CRUD 功能,如果需要的话,也可以通过继承该接口来拓展 :

public interface CrudRepository<T, ID extends Serializable>
  extends Repository<T, ID> {

  <S extends T> S save(S entity);      

  Optional<T> findById(ID primaryKey); 

  Iterable<T> findAll();               

  long count();                        

  void delete(T entity);               

  boolean existsById(ID primaryKey);   

  // … more functionality omitted.
}

除了 CrudRepository 之外,还有 JpaRepository 和 MongoRepository。在 CrudRepository 中,有许多抽象方法添加了额外的方法来简化对实体的分页访问。

/**
* PagingAndSortingRepository 方法提供了分页和排序的功能
*/
public interface PagingAndSortingRepository<T, ID extends Serializable>
  extends CrudRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

还有包含:删除查询、计数、查询等相关接口

定义自己的 Repository

声明扩展 Repository 或者其子接口之一的接口,并嵌入需要处理的对象和 ID 类型:

interface UserRepository extends MongoRepository<User,String>{  // UserRepository 默认继承了父类的 CRUD 方法
    List<User> findByName(String name); // 扩展的查询方法
}

repository 方法的 Null 处理

从 Spring Data 2.0 开始,返回单个聚合实例的 Repository 的 CRUD 方法 可以使用 Java8 中的Optional 来只是可能缺少的值,支持返回一下的包装类型:

  • com.google.common.base.Optional
  • scala.Option
  • io.vavr.control.Option
  • javaslang.control.Option (不推荐)

或者,不使用包装类型,直接返回查询结果为 Null。 使用 Optional 的好处在于保证了方法返回的对象永远不会为 Null,而是相应的 空表示。

多 Spring Data 模块的 Repository

interface MyRepository extends JpaRepository<User, Long> { }

@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
  …
}

interface UserRepository extends MyBaseRepository<User, Long> { // MyRepository 与 MyBaseRepository 都继承了 JpaRepository ,所以它们是有效的子类
  …
}
interface AmbiguousRepository extends Repository<User, Long> {
 …
}

@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
  …
}

interface AmbiguousUserRepository extends MyBaseRepository<User, Long> {
    // 而且多个 SpringData 模块导致无法区分这些 Repository 应该绑定到哪个特定的 仓库
  …
}

定义查询方法

仓库代理有两种方式导出指定的查询。

  • 从名字直接导出查询 : 类似 findByName(String name);
  • 手工定义的查询 : 类似 @query("{ name : ?0}")

查询定义策略:
通过 xml 文件中的 query-lookup-strategy 参数或者 Enable 注解中的 queryLookupStrategy 参数。

  • CREATE 尝试从方法名中构造指定仓库的查询方法
  • USE_DECLARED_QUERY 尝试找到声明的查询,若无则抛出异常
  • CREATE_IF_NOT_FOUND 先查找声明的查询,如不能找到,将生成一个基于命名的查询(默认查询策略,一般不用变)

文章总结于:https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#dependencies.spring-framework

相关文章

网友评论

      本文标题:Spring Boot Mongo (一)

      本文链接:https://www.haomeiwen.com/subject/clsobftx.html