显示导航

使用DATABASE多租户时动态配置数据源

365bet地区了解如何在每位注册用户动态创建新数据源连接的同时使用365bet地区多租户功能DATABASE模式

s塞尔吉奥·德尔阿莫

365bet地区版本 3.3.1

365bet地区培训

365bet地区培训由创建并积极维护365bet地区框架的人们开发和交付

入门

本指南从JWT的自定义租户解析器离开开始阅读本指南之前,请先完成该指南以获取更好的理解

您将需要什么

要完成本指南,您将需要以下内容

  • 花些时间在你手上

  • 体面的文本编辑器或IDE

  • 安装了JDK或更高版本JAVA首页适当配置

如何完成指南

要开始,请执行以下操作

要么

365bet地区指南存储库包含两个文件夹

  • 初始初始项目通常是一个简单的365bet地区应用程序,其中包含一些其他代码,可以帮助您快速入门

  • 完成一个完整的示例它是按照指南中介绍的步骤进行操作并将这些更改应用于文档的结果。初始

要完成指南,请转到初始

  • 光盘进入grails指南grails动态多个数据源初始

并按照下一节中的说明进行操作

您可以直接前往完成的例子如果你光盘进入grails指南grails动态多个数据源完整

编写申请

本指南使用多租户数据库模式以了解更多信息每个租户的数据库多租户指南

本指南显示了使用多租户创建SaaS软件即服务应用程序时将看到的典型流程数据库模式

为了简化本指南,简化了数据库配置过程

使用以下架构创建两个MySQL数据库

创建  `计划` (
  `ID` 比金特(20)  空值,
  `` 比金特(20)  空值,
  `标题` varchar(255)  空值
) 发动机创新数据库默认 字符集utf

第一个数据库应称为起重机第二个向量.

在指南应用程序中,当用户注册与用户名相同的名称的数据库时,每个注册用户将拥有自己的唯一数据库

在现实世界中的应用中,您可能会有一个更复杂的设置,其中可能涉及创建数据库,创建模式以将数据库url和每个用户数据库的凭据以安全方式保存在默认数据源的数据库表等中的模式。

组态

在本指南中,我们将使用MySQL,因此应将MySQL依赖项添加到建立gradle.

建立gradle
运行'MySQL连接器'

在MySQL数据库中创建一个名为奴才.

yml应用程序仅配置默认数据源以指向该数据库。由于配置,该数据库的架构将由Hibernate生成dbCreate更新.

应用程序每个用户的dataSource设置将动态配置并从默认设置继承

涉及安全性的领域类用户, 用户角色, 角色映射到默认的dataSource

grails应用配置会议应用yml
冬眠的:
    :
        查询: 
        使用二级缓存: 
        使用查询缓存: 
数据源:
    派对: 真正
    jmxExport: 真正
    driverClassNamecom mysql jdbc驱动程序方言org休眠方言MySQL InnoDBDialect用户名(1)
    密码(1)
    dbCreate更新网址: 数据库:MySQL的:奴才 (1)
1 根据您的MySQL安装配置这些设置

将多租户模式更改为数据库yml应用程序

grails应用配置会议应用yml
    蓝色的:
        多租户:
            模式数据库(1)
            tenantResolverClass演示CurrentUserByJwtTenantResolver(2)
        反应堆:
            #是否将GORM事件转换为Reactor事件#被禁用默认 对于性能原因大事记: 
1 将多租户模式定义为数据库
2 将Tenant Resolver类设置为您在JWT的自定义租户解析器指南

域类

由于本指南利用数据库多租户,其中每个租户都有一个单独的数据库,您不再需要配置列来处理tenantId因此tenantId财产可以被删除

365bet地区应用程序域演示计划groovy
演示进口 grails gorm多租户

 计划 实施多租户 { (1)
    标题
1 实行多租户将这个领域类别视为多租户的特征

GORM活动

创建一个名为UserInsertedListener当插入新用户时,它将创建一个新的连接源。

它使用听众注释以听同步地GORM活动.

src主要groovy演示UserInsertedListener groovy
演示进口 grails事件注释gorm侦听器
进口 常规转换CompileStatic
进口 groovy util日志记录Slf j
进口 组织grails数据存储区映射引擎事件PostInsertEvent
进口 组织grails orm休眠HibernateDatastore
进口 org springframework bean工厂注释自动装配

静态编译
自我
 UserInsertedListener {

    自动接线HibernateDatastore hibernateDatastore自动接线DatabaseProvisioningService databaseProvisioningService听众用户(1)
    虚空onUserPostInsertEvent PostInsertEvent事件(2)
        用户名事件getEntityAccess getPropertyValue"用户名"DatabaseConfiguration数据库配置databaseProvisioningService findDatabaseConfigurationByUsername用户名(3)hibernateDatastore getConnectionSources addConnectionSource databaseConfiguration dataSourceName databaseConfiguration配置(4)
    }
}
1 同步收听域类的GORM事件用户
2 PostInsertEvent大事记
3 使用协作者检索数据库配置对象见下文
4 采用ConnectionSources API动态配置新的数据源

定义UserInsertedListener作为豆

grails app conf春季资源groovy
导入演示UserInsertedListener Bean userInsertedListener UserInsertedListener

先前的侦听器使用几个类作为协作者

src main groovy演示DatabaseConfiguration groovy
演示进口 常规转换CompileStatic

静态编译
 数据库配置 {
    dataSourceName地图组态
grails应用服务演示DatabaseProvisioningService groovy
演示进口 常规转换CompileStatic

静态编译
 DatabaseProvisioningServiceUserRoleService userRoleService清单findAllDatabaseConfiguration清单<用户名userRoleService findAllUsernameByAuthority VillainService ROLE VILLAIN用户名收集findDatabaseConfigurationByUsernameDatabaseConfiguration findDatabaseConfigurationByUsername用户名数据库配置dataSourceName用户名组态configurationByUsername用户名地图<, 宾语configurationByUsername用户名'休眠hbm ddl自动':'没有', (1)
                '用户名': '', (2)
                '密码': '', (2)
                '网址':"jdbc的mysql$用户名" (2)
        ]  地图<, 宾语>
    }
}
1 当量dbCreate none
2 更改这些配置设置以匹配您的系统
先前的设置未指定MySQL驱动程序或方言。这些设置是从默认数据源继承的,该默认数据源是在yml应用程序

功能测试

我们稍微修改了功能测试JWT的自定义租户解析器验证新连接时是否创建新连接源的指南用户被插入

src集成测试groovy演示PlanControllerSpec groovy
演示进口 grails gorm多租户租户
进口 grails插件rest client RestBuilder
进口 grails测试mixin集成集成
进口 组织grails orm休眠HibernateDatastore
进口 org springframework bean工厂注释自动装配
进口 spock lang规格
进口 spock lang忽略

忽略( { 系统盖滕'特拉维斯')  布尔值 } )
积分
 PlanControllerSpec 延伸规范PlanService planService UserService userService villainService villainService RoleService roleService自动接线HibernateDatastore hibernateDatastore RestBuilder restRestBuilder的accessTokenp定义休息休息"HTTP本地主机${服务器端口}消防登录"接受'应用程序json'内容类型'应用程序json'json用户名u密码p如果状态200 ) {
            返回响应json访问令牌空值
    }

    定义 "检索当前登录用户的计划"() {
        什么时候用户矢量恶棍服务saveVillain'向量', '秘密')

        然后hibernateDatastore connectionSources大小旧的hibernateDatastore connectionSources大小1 (1)

        什么时候用户gru villainService saveVillain'起重机', '秘密')

        然后hibernateDatastore connectionSources大小旧的hibernateDatastore connectionSources大小1 (1)带有ID的租户"起重机"planService保存'偷月亮'带有ID的租户"向量"planService保存'偷金字塔')
        }

        什么时候: '用gru登录'
        gruAccessToken accessToken'起重机', '秘密')

        然后gruAccessToken什么时候:
        定义休息休息"HTTP本地主机${服务器端口}计划"接受'应用程序json'标头'授权书', "承载者${gruAccessToken}")
        }

        然后状态200响应JSON toString'标题偷月球'

        什么时候: '用矢量登录'
        vectorAccessToken accessToken'向量', '秘密')

        然后vectorAccessToken什么时候休息休息"HTTP本地主机${服务器端口}计划"接受'应用程序json'标头'授权书', "承载者${vectorAccessToken}")
        }

        然后状态200响应JSON toString'偷金字塔'

        清理带有ID的租户"起重机"planService deleteByTitle'偷月亮'带有ID的租户"向量"planService deleteByTitle'偷金字塔'userService deleteUser gru userService deleteUser向量roleService delete VillainService ROLE VILLAIN
1 验证是否存在新的连接源

在启动时添加连接源

当应用重启时,我们想为每个注册用户连接一个数据源。BootStrap常规为了实现

365bet地区应用程序初始化演示BootStrap groovy
演示进口 常规转换CompileStatic
进口 组织grails orm休眠HibernateDatastore

静态编译
 引导带HibernateDatastore hibernateDatastore DatabaseProvisioningService databaseProvisioningService定义初始化ServletContext对于DatabaseConfiguration数据库配置databaseProvisioningService findAllDatabaseConfiguration(1)hibernateDatastore getConnectionSources addConnectionSource databaseConfiguration dataSourceName databaseConfiguration配置定义破坏

运行测试

运行测试

grailsw grails测试应用程序grails打开测试报告

要么

gradlew检查打开构建报告测试索引html

帮助365bet地区

OCI赞助了本指南的创建OCI提供了几种365bet地区服务:

免费咨询

OCI 365bet地区团队包括365bet地区联合创始人Jeff Scott Brown和Graeme Rocher检查我们的365bet地区课程并向发展和维护365bet地区的工程师学习

Grails OCI团队