题记
写这系列有点老调重弹的味道,比如ahuaxuan已经在他的博客里对于JackRabbit 1.0做了很详细的阐述。之所以再写,是因为JCR推出了JCR 2.0,个人觉得有必要将一些新的特性再罗列一下。
问题提出
存取各种信息对于任何应用程序来说非常平常,大多数时候我们会把数据保存在关系数据库中。数据库处理规范数据类型十分在行,但是在处理如图像、文档等二进制数据时却不是那么得心应手。
尽管可以用文件系统作为替代——而且它们还提供了更好的性能。但它们既没有提供用于搜索信息的查询语言,也没有提供表示关系或事务的概念。
什么是JSR-170
幸运的是,被称为Java内容仓库(Java Content Repository,JCR)的JSR-170,试图以独立于具体实现的方式解决这些(以及其它)问题。即,不论底层资源(如,数据库,本地或虚拟文件系统)是什么,API都将相同。在数据存储之上,JCR提供诸如访问粒度控制、版本控制、内容事件、全文检索和过滤等内容服务。
采用JCR能带来什么呢?包括如事务、伸缩性、数据库端的查询、使用超大文件带来的真正好处、流、访问控制和文件系统端的层次结构,以及诸如版本标定、全文检索,以及“数据优先”方法。
由Day Software领导的JSR-170背后的专家组付出了艰辛的劳动。2005年6月完成,在javax.jcr包中,API包含了大约50个类(主要是接口和异常)。
2006年早些时候,我们的主角JackRabbit登场了, 它是JCR 1.0版本的参考实现,除了JackRabbit之外,还有许多开源或者商业的JCR 1.0的不同实现。
JCR概览
JCR 建立在内容仓库的概念之上。仓库使用“树结构”保存信息。
树由节点和属性组成。1个节点有且只有1个父亲,有任意数目的孩子(子节点)和任意数目的属性。1个属性有且只有一个父亲(它是节点),它没有子节点,由一个名字和一个或多个值组成。
属性值的类型可以是:布尔(Boolean)、日期(Date)、双精(Double),长整(Long),字符串(String)或流(Stream)。在JCR里,只有属性可以被用来存储信息,节点则被用来创建树内部的“路径”。
你可以把JCR想成类似文件系统的目录结构,节点是目录,属性则是实际的文件。
JSR-170 提供了标准的JCR API接口包 -- javax.jcr包。API的核心类是Session,它代表客户端和仓库之间的连接。这个包还包含了那些组成仓库的接口的定义:Workspace,Credentials,Node,Property,Item(Node和Property的超类)和Value。
- javax.jcr.query包负责处理查询,
- javax.jcr.nodetype包负责定义节点类型。
- javax.jcr.version、javax.jcr.observation、javax.jcr.lock负责可选级别的功能。
JSR 283之后的JCR 2.0
JSR-283 旨在从以下几个方面改进JCR 1.0:
- 访问控制和节点类型的管理
- 通过新的标准节点类型(包括元信息和国际化)改进互操作性
- 扩展内容建模能力
- 联邦、交叉仓库和交叉工作区(Workspace)功能
- 积极发展现有查询语言、版本标定和观察
- Remoting和客户/服务器协议映射(译者注:Remoting是采用分布式进行编程的一种技术,主要用于管理跨应用程序域的同步和异步RPC会话。默认情况下,Remoting使用HTTP或TCP协议,并使用XML编码的SOAP或本机二进制消息格式进行通信。)
因此JCR 2.0的API和JCR 1.0有很大的不同。可以参考:
http://www.day.com/maven/jdiff-jcr1-jcr2/changes.html
JackRabbit与NoSQL
“NoSQL“这个有点浮泛的词现在代表着几大类数据库,比如key-value型数据库,面向文档的数据库等等。
面向文档的非关系数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具有良好的查询性能,一些传统的应用,比如博客、Wiki等等,都是很适合应用面向文档的数据库的场景。
JackRabbit就是一种面向文档的数据库,它和MongoDB,CouchDB的功能十分接近,优势在于JackRabbit遵从JCR标准,日后可以迁移到其他同样兼容JCR的性能更好的商业解决方案上。