EclipseLink的介绍
EclipseLink 是 Eclipse 基金会管理下的开源持久层服务项目,为 Java 开发人员与各种数据服务(比如:数据库、web services、对象XML映射(OXM)、企业信息系统(EIS)等)交互提供了一个可扩展框架,目前支持的持久层标准中包括:
• Java Persistence API (JPA)
• Java Architecture for XML Binding (JAXB)
• Java Connector Architecture (JCA)
• Service Data Objects (SDO)
EclipseLink 前身是 Oracle TopLink,目前 EclipseLink2.5 完全支持 JPA2.1 。
在完整实现 JPA 标准之外,针对 SaaS 环境,在多租户的隔离方面 EclipseLink 提供了很好的支持以及灵活地解决方案。
应用程序隔离
• 隔离的容器/应用服务器
• 共享容器/应用服务器的应用程序隔离
• 同一应用程序内的共享缓存但隔离的 entity manager factory
• 共享的 entity manager factory 但每隔离的 entity manager
数据隔离
• 隔离的数据库
• 隔离的Schema/表空间
• 隔离的表
• 共享表但隔离的行
• 查询过滤
• Oracle Virtual Private Database (VPD)
对于多租户数据源隔离主要方案
• Single-Table Multi-tenancy,依靠租户区分列(tenant discriminator columns)来隔离表的行,实现多租户共享表。
• Table-Per-Tenant Multi-tenancy,依靠表的租户区分(table tenant discriminator)来隔离表,实现一租户一个表,大体类似于上文的共享数据库独立Schema模式。
• Virtual Private Database(VPD ) Multi-tenancy,依靠 Oracle VPD 自身的安全访问策略(基于动态SQL where子句特性),实现多租户共享表。
Demo
我们重点介绍我们在平台中使用的一种模式:一租户一个表(也可以理解为一个租户一个Schema)的实现方法。
这种多租户类型使每个租户的数据可以占据专属它自己的一个或多个表,多租户间的这些表可以共享相同 Schema 也可使用不同的,前者使用前缀(prefix)或后缀(suffix)命名模式的表的租户区分符,后者使用租户专属的 Schema 名来定义表的租户区分符。
@Multitenant注解
与 @Entity 或 @MappedSuperclass 一起使用,表明它们在一个应用程序中被多租户共享。
@Entity
@Table(name="room")
@Multitenant
...
Public class Room {
}
Multitenant 包含两个属性:
1. boolean includeCriteria: 是否将租户限定应用到 select、update、delete 操作上 ,默认值为:true
2. MultitenantType value: 多租户策略,SINGLE_TABLE(共享表), SINGLE_TABLE
TABLE_PER_TENANT(独立Schema), VPD.
实体类:
package mtsample.hotel.model;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.eclipse.persistence.annotations.Multitenant;
import org.eclipse.persistence.annotations.MultitenantType;
import org.eclipse.persistence.annotations.TenantTableDiscriminator;
import org.eclipse.persistence.annotations.TenantTableDiscriminatorType;
/**
*
* @ClassName: HotelGuest
* @Description: 入住客户信息实体
* @author wyj
* @date 2015年6月20日 下午9:20:36
*
*/
@Entity
@Table(name="hotel_guest")