【问题标题】:Is there a way to (per request) set a non-persistent Database Bean in Coldbox有没有办法(根据请求)在 Coldbox 中设置非持久性数据库 Bean
【发布时间】:2012-01-25 11:35:39
【问题描述】:

我希望从自定义框架迁移到 Coldbox。

应用程序有 3 个数据源

  1. 核心
  2. 常见
  3. 网站

Core 数据源存储有关网站的信息,公共数据源存储共享信息,如状态表,Site 数据源存储与网站相关的数据。

每个请求都会根据请求的 URL 更改站点数据源,从而允许每个站点被沙箱化到自己的数据库中。

从我的测试看来,由 Coldbox 生成并在其自动装配中使用的 DatasourceBeans 似乎存储/缓存在应用程序范围内。这是我想做的事情,但是对数据源的更改会在请求之间保持不变。

在 Coldbox.cfc 中

datasources = {
    Core   = {name="DSNCore", dbType="mssql", username="", password=""},
    Common   = {name="DSNCommon", dbType="mssql", username="", password=""},
    Site = {name="", dbType="mssql", username="", password=""}
};

interceptors = [{
    class="interceptors.Website",
    properties={}
}];

名为 Website.cfc 的拦截器

<cfcomponent name="Website" output="false" autowire="true">

    <cfproperty name="dsncore" inject="coldbox:datasource:Core">
    <cfproperty name="dsn" inject="coldbox:datasource:Site">

    <cffunction name="Configure" access="public" returntype="void" output="false" >
    </cffunction>

    <cffunction name="preProcess" access="public" returntype="void" output="false" >
        <cfargument name="event" required="true" type="coldbox.system.web.context.RequestContext">
        <cfargument name="interceptData" required="true" type="struct">
        <cfset var q="" />

        <cfdump var="#dsn.getMemento()#" label="DSN before change" />
        <cfquery name="q" datasource="#dsncore.getName()#">
            SELECT
                Datasource
            FROM
                Websites
            WHERE
                Domain = <cfqueryparam cfsqltype="cf_sql_idstamp" value="#cgi.http_host#" />
        </cfquery>
        <cfscript>
        dsn.setName(q.Datasource);
        </cfscript>
        <cfdump var="#dsn.getMemento()#" label="DSN after change" />
        <cfdump var="#q#" label="Results of query" /><cfabort />

    </cffunction>
</cfcomponent>

有什么方法可以让我使用 Coldbox 自动装配数据源 bean?

老实说,这正是我认为我会这样做的方式,如果有人对如何让我的模型根据请求使用非硬编码的不同数据源有任何其他想法,我很想更好地理解框架。

这个问题也延伸到 ORM。有没有办法让 Transfer 为每个请求使用不同的数据源?如果数据库可能有不同的模式怎么办?假设一个数据库已更新到较新的版本,但另一个仍在使用旧版本,我在代码中基本上有一些 if 语句来为更新后的数据库提供增强的功能。

您可能在阅读这些问题时对自己说“您不应该那样做”。好吧,我是,所以请不要回答说不这样做。如果您对将单个代码库附加到不同数据库的更好方法有想法,那么我会全力以赴。

【问题讨论】:

    标签: coldfusion coldbox


    【解决方案1】:

    另一种方法是使用 Coldbox.cfc 中的 requestStartHandler

    <!---config/Coldbox.cfc--->
    requestStartHandler = "Main.onRequestStart"
    
    <!---handlers/Main.cfc--->
    <cffunction name="onRequestStart" returntype="void" output="false">
        <cfargument name="event" required="true">
        <cfquery name="q" datasource="#dsncore.getName()#">
            SELECT
                Datasource
            FROM
                Websites
            WHERE
                Domain = <cfqueryparam cfsqltype="cf_sql_idstamp" value="#cgi.http_host#" />
        </cfquery>
    
        <cfset rc.dataSource = q.Datasource />
    </cffunction>
    

    然后您只需将数据源存储在请求集合中,因为 onRequestStart 将在每个请求上触发。

    【讨论】:

    • 这可能行得通,但它似乎不是很冷酷。当然,它确实做了一件事,它使我不必担心在每个模型 cfc 中执行 DSL。虽然这是否也意味着它破坏了封装,或者使用 DSL 已经这样做了?
    • 这是否意味着每个函数都需要我做 rc=event.getCollection()?
    • 我想说,在这种情况下,我不妨使用基于约定的方法并将数据源信息存储在请求变量中。
    猜你喜欢
    • 1970-01-01
    • 2011-05-06
    • 2011-11-16
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    相关资源
    最近更新 更多