跟我上“云”端(四)使用eclipselink构建企业级多租户应用

上一篇博客中我们介绍了多租户的数据隔离,文中具体的介绍了hibernate和eclipselink对于多租户的实现情况,博客的最后,我也对hibernate实现多租户的细节上做了解释,这次,我想带大家一起来使用eclipselink构建企业级的多租户项目。

eclipselink的三种实现

由于eclipselink完整实现了jpa规范,我们就可以使用ejb构建一个企业级的多租户项目,首先eclipselink支持3中多租户的模式:

- 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子句特性),实现多租户共享表。

Table-Per-Tenant Multi-tenancy实现

  • 我想将的是第二种方式,因为它在性能、分离度以及灵活性上都是比较合适的。
  • 首先是persistence.xml的内容,经过上一篇博客的介绍,我们应该已经配置好eclipselink的基本使用环境。

Persistence.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <!-- 给定persistence-unit名字-->
    <persistence-unit name="MT_HOTEL_SERVICE"
        transaction-type="JTA">
        <!-- 使用eclipselink的持久化实现-->
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <!-- 使用jboss中配置的数据源-->
        <jta-data-source>java:jboss/datasources/JcMysqlDS</jta-data-source>
        <!-- 由于配置了实体自动扫描此处不用列出系统中的试题-->
        <properties>
            <!-- 修改第一次加载时间长的问题 -->
            <property name="eclipselink.deploy-on-startup" value="True" />
            <!-- 运行执行本地sql查询 -->
            <property name="eclipselink.jdbc.allow-native-sql-queries"
                value="true" />
            <!-- 设置服务器类型 -->
            <property name="eclipselink.target-server" value="JBoss" />
            <!-- logging 级别配置-->
            <property name="eclipselink.logging.level" value="FINE" />
            <!-- 配置静态织入-->
            <property name="eclipselink.weaving" value="static" />
            <!-- 设置自定义主键生成策略-->
            <property name="eclipselink.session.customizer" value="com.tgb.itoo.base.util.uuid.UUIDSequence" />
        </properties>
    </persistence-unit>
</persistence>
  • 配置中每一行的配置都有做出解释,这里就不再多说了。

BaseEntity配置

  • 对于实体的配置:首先是使用的实体继承,BaseEntity的代码如下:
package com.tgb.itoo.base.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@MappedSuperclass
@EntityListeners(value = { EntityListener.class })
public abstract class BaseEntity implements IdEntity {

    private static final long serialVersionUID = 1L;

    public BaseEntity() {
        super();
    }

    @Id
    @GeneratedValue(generator = "system-uuid")//自定义uuid生成策略
    @Column(name = "id")
    protected String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    /**
     * 数据库名称
     */

    @Transient //不进行持久化
    private String dataBaseName;

    public String getDataBaseName() {
        return dataBaseName;
    }

    public void setDataBaseName(String dataBaseName) {
        this.dataBaseName = dataBaseName;
    }

    /**
     * 备注
     */
    @Column(name = "comment", length = 255)
    private String comment;

    /**
     * 操作人
     */
    @Column(name = "operator", length = 20)
    private String operator;
    ……
}
  • BaseEntity中定义了实体的公共属性,其中重点关注两个属性值

    1. id:id使用的是自定义的uuid生成策略,这个在下一篇博客中介绍。
    2. dataBasename:从名字上来说很明了就是数据库名,但是这个属性不是用来持久化的,所以使用@Transient注解,这个属性主要是为了传递参数的,会在实现多租户的时候用到,因为对于任何实体的每一次操作都应该确定是那个承租者的操作,就要使数据的CRUD都要对应自己的数据库。

具体某个实体的设计

package com.tgb.itoo.authority.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
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;

import com.tgb.itoo.base.entity.TimeBaseEntity;

/**
 * 角色实体
 * @author hanyi
 *
 */
@Entity
@Table(name="ta_role")
@Multitenant(value=MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type=TenantTableDiscriminatorType.SCHEMA, contextProperty="tenant_id")
public class Role extends TimeBaseEntity {

    private static final long serialVersionUID = 598970641717338526L;

    /**
     * 角色名称
     */
    @Column(name = "roleName", length = 32)
    private String roleName;

    /**
     * 角色描述
     */
    @Column(name = "roleDescribe", length = 100)
    private String roleDescribe;
    ……
}
  • 应该注意实体中对于多租户的注解,其中设置了MultitenantType.TABLE_PER_TENANT也就是使用依靠表的租户区分,TenantTableDiscriminatorType有三种类型,这里使用SCHEMA,也就是每个租户使用独立的SCHEMA,定义了contextProperty=”tenant_id”,这也就设置了entitymanager可以根据tenant_id属性区别不同的租户。

entitymanager的注入

    //实体管理器,管理实体持久化操作,通过容器注入
    @PersistenceContext(unitName = "MT_HOTEL_SERVICE")
    protected EntityManager em;

设置多租户属性

/**
 * 根据数据库名字,得到当前操作对应的实体管理器的名字
 * @return 实体管理器
 */
protected EntityManager getEntityManager() {
    //dataBaseName的值,给实体管理器赋值,此处的tenant_id是在实体注解时规定,只要统一可以是任何值。
    if (dataBaseName!=null && !dataBaseName.equals(""))
    {
        em.setProperty("tenant_id", dataBaseName);
    }
    //如果dataBaseName的值为空,那么就选择一个默认的库,这里选择的是根库(base)
    else
    {
        em.setProperty("tenant_id", "base);
    }
    return this.em;
}

具体Eao的方法

/**
     * @author hanyi
     * @MethodName : save
     * @Description : 无返回值的泛型保存方法
     * @param t:要保存的实体
     */
    public  void save(Object entity) {
        //从实体类型中拿到当前操作的数据库名字
        getDataBaseName(entity);
        //取得实体管理器,进行持久化操作
        getEntityManager().persist(entity);
    }
  • 这里忽略了从getDataBaseName(entity)方法的代码,其主要作用是通过反射得到前台设置的databasename的值,之后再getEntityManager的时候使用。

完成配置

到此eclipselink+ejb+jpa实现企业级的多租户应用的数据层隔离也就解决了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-28 11:32:03

跟我上“云”端(四)使用eclipselink构建企业级多租户应用的相关文章

跟我上“云”端(三)eclipselink+jboss实现多租户基本配置

本文主要介绍,如何在jboss EAP6.2中使用eclipselink 开发工具:jboss EAP6.2+maven eclipselink版本:2.6.0 添加eclipselink的module 使用预包装的集成库,下载地址:(eclipselink+jobss EAP6.2集成module) 下载完成以后解压,并使用maven编译,解压后的文件: 查看其中的pom.xml文件: 其中properties结点中加入自己想使用的eclipselink版本,并修改 eclipselink.v

跟我上“云”端(二)多租户的数据隔离

多租户两种极端实现方式 启用多租户的方法有很多,我不想做一一的介绍,但是有两个极端我们可以考虑一下: 极端一: 是所有租户共享单一应用程序实例,也就是相同的服务器.中间件和应用程序.实现的方法是用租户标识参数对应用程序的单一实例进行参数化. 图1 在多个租户之间共享应用程序和中间件的单一实例 极端二: 是租户在单独的服务器上运行自己的应用程序实例(当前许多 Application Service Provider [ASP] 采用这种方法). 租户只共享数据中心的基础结构(比如供电和制冷),但是

跟我上“云”端(一)认识多租户

什么是多租户,其优缺点是什么? 从软件的单个共享实例将软件交付给多个客户端组织(或承租者)的能力是 Web 交付解决方案的重要要求.例如,假设有一个由银行服务提供者作为服务提供的简单银行应用程序.本上下文中的多租户 是指从银行应用程序的单个共享实例向多个银行提供银行服务的能力.图 1 说明了从共享的应用程序服务器.数据库.操作系统和物理服务器向两个银行(北卡罗来纳州第一银行和加拿大第二银行)提供的多承租银行服务. 图 1. 使用共享中间件和硬件为银行业务构建的示例 Web 交付的多承租服务 上图

大话企业上云之第四篇

前言:本篇主要讲述应用的分析和迁移过程. 对于业务部门来说,业务应用才是其最关键的. 在评估中,我们需要对应用进行分析. 应用类型 举例 直接迁移型 简单的测试环境,单一的应用 修改平台型 操作系统升级了,应用版本需要统一进行升级 替代类型 采用SAAS模式或者云端的授权应用 重新开发型 数据库的更改.中间件的修改.架构修改 无需上云类型 无需上云的应用或非关键的应用,服务器淘汰类似 这几种类型应用的比较: 应用类型 成本 时间 直接迁移型 一星 一星 修改平台型 二星 二星 替代类型 三星 三

“云”端的语雀:用 JavaScript 全栈打造商业级应用

作者|? 不四(死马)蚂蚁金服 语雀产品技术负责人 语雀是什么? 语雀是一个专业的云端知识库,面向个人和团队,提供与众不同的知识管理,打造轻松流畅的工作协同,它提供各种格式的在线文档(富文本.表格.设计稿等)编辑能力,支持实时在线多人协同编辑,数据云端保存不丢失.而语雀与其他文档工具最大的不同是,它通过知识库来对文档进行组织,让知识创作者更好的管理知识. 语雀技术架构演进 原型阶段 语雀诞生于 2016 年,当时蚂蚁金融云需要一个工具来承载它的文档.当时负责的技术同学利用业余时间,开始搭建这个文

安全狗服云:将服务器安全管理搬上“云”

摘要:如何抵御网络安全问题带来的侵害?如何应对多元化的运维需求?如何从安全角度去考虑运维管理?2014年初安全狗服云依托自身核心安全服务,借力云计算优势,精心打造并推出了基于云计算SaaS(软件即服务)模式的服务器安全运维云服务平台--服云,真正将服务器安全管理搬上了"云. [赛迪网讯]从去年年初至今,网络安全问题便一直围绕着我们的日常生活.从日常出行到社交软件,从门户网站到政务平台,曾经的网络安全隐患已经呈现爆发之势.另外,随着企业运营的多元化,使得租用服务器同样存在多元化的需求,最终导致了管

辛星笔记云计算第四篇即云的四种模式

虽然从技术或者架构角度看,云计算比较单一,但是在实际情况下,为了适应用户不同的需求,它会演变为不同的模式.在NIST(National  Institue  of  Standards  and  Technology,美国国家标准技术研究院)的名为"The  NIST Definition  of  Cloud Computing"的关于云计算概念的文档中,定义了云的四种模式,分别是:公有云.私有云.混合云和行业云. 公有云: (1)公有云是现在最主流也是最受欢迎的云计算模式.它是一

云+端的物联网应用

今天是“互联网+”.“大众创业.万众创新”的时代,宁波市是我国“中国制造2025”的试点城市,以先进技术驱动产业创新与转型的大潮正在催生一场波澜壮阔的“新工业革命”,也当仁不让地将物联网IoT推到了风口浪尖上.从微软智能云Azure到全新的Windows 10,微软一套从云到端的完整物联网架构正在助力各行各业实现技术创新与业务模式的转型升级. 本次讲座为宁波中学的选修课,通过主题演讲和演示相结合的方式为高中生和教师们带来微软 IoT 领域的全新体验.讲师将通过演示和分享具体实践的方式来重点介绍微

《近匠》APICloud:“云”+“端”一体的移动API提供者

CSDN移动:请讲讲你们是谁?你们以往的从业经历? APICloud最开始只有两个创始人刘鑫和邹达,但是半年时间就发展成超过50人的互联网团队.APICloud的两个创始人性格迥异.CEO刘鑫是个典型的叛逆者,大学读到一半就辍学创业,后来又心血来潮的扑到北京重新开始,风风火火十多年见证了中国移动互联网从SP抢钱时代到智能机普及的完整历程.CTO邹达则是同事眼中的“Nice man”,极具个性的光头造型让人印象深刻,倒是这种“穷凶极恶”的硬汉形象配上“Nice man”的个性让人记忆犹新,在API