1

SESSION変数とAPPLICATION変数の使用を避けるためにすべてのCFCをリファクタリングしようとしています(簡単な作業ではありません)。

ただし、このアプリケーションでは、ログインしているさまざまなユーザーがさまざまなデータベースやスキーマにアクセスしている可能性があるため、すべてのデータベース呼び出しでSESSION変数が使用されます。

<cfquery name="qEmployees" datasource="#SESSION.DataSourceName#">
    SELECT *
    FROM #SESSION.DatabaseSchema#.Employees
</cfquery>

データベースにアクセスするすべてのメソッド呼び出しにこれらの2つのSESSION変数を渡すという問題を経験したくありません。リモートAJAX呼び出しでDSNとスキーマ名を渡したくないので、これは特に当てはまります。

これを行うためのベストプラクティスは何ですか?CFCで使用されるべきではないすべてのスコープに対して?

4

5 に答える 5

2

CFC のコンストラクタとして機能する「init」メソッドを作成する必要があります。その後、CFC をインスタンス化し、共有スコープ (ほとんどの場合アプリケーション スコープ) に格納できます。ここから、AJAX 経由でこの CFC を使用するために、通常はリモート ファサードを作成します。基本的に、これはアプリケーション スコープ内の CFC インスタンスに直接アクセスする別の CFC です。Ajax 経由でアクセスする必要があるメソッドを実装し、access="remote"アプリケーションaccess="public"が実際の CFC のメソッドにアクセスできるようにして公開します。この場合、リモート ファサードが設計パターンの一部としてアプリケーション スコープに直接アクセスできることが一般的に認められています。

簡単な例:

例.cfc:

<cfcomponent output="false">
    <cffunction name="init" access="public" output="false" returntype="any">
        <cfargument name="dsn" type="string" required="true" />
        <cfset variables.dsn = arguments.dsn />
        <cfreturn this />
    </cffunction>
    <cffunction name="doStuff" access="public" output="false" returntype="query">
        <cfset var q = "" />
        <cfquery name="q" datasource="#variables.dsn#">
        select stuff from tblStuff
        </cfquery>
        <cfreturn q />
    </cffunction>
</cfcomponent>

Application.cfc onApplicationStart() メソッドで:

<cfset application.example = createObject("component","example").init(dsn = "somedsn") />

リモート.cfc:

<cfcomponent output="false">
    <cffunction name="doStuff" access="remote" returntype="query">
        <cfreturn application.example.doStuff() />
    </cffunction>
</cfcomponent>
于 2011-07-13T16:24:44.923 に答える
2

データソースは本当に変数なので、オプションのパラメーターとしてすべての関数に渡し、デフォルト値を変数スコープの dsn 属性に設定すると思います。CFC のコンストラクターで変数スコープ DSN を設定します。そうすれば、AJAX 呼び出しの DSN を渡すだけで済みます。

<cffunction name="doFoo" access="remote"...>
    <cfargument name="dsn" type="String" required="false" default="#variables.datasource#" />
</cffunction>

アプリのセッション スコープを使用してユーザーの dsn 名を保存し、その変数を使用して AJAX 呼び出しに渡します。

于 2011-07-13T16:02:36.293 に答える
1

Application.cfc の onRequest または onRequestStart 関数でデータソース変数を設定できますか

<cffunction name="onSessionStart">
    <cfset session.dsn = _users_personal_dsn_ />
</cffunction>


<cffunction name="onRequestStart" >
   <cfset dsn = "#session.dsn#" />
</cffunction>

<cfquery name="qEmployees" datasource="#dsn#">
    SELECT *
    FROM #SESSION.DatabaseSchema#.Employees
</cfquery>

それが機能するかどうかわからない [テストされていない - 実際には少しずさんな感じがする] -sean

于 2011-07-13T16:00:40.700 に答える
1

選択するスコープ (DSN だけでなく、この質問のあらゆるバリエーションについて) は、値の有効期間がスコープの有効期間と同じであるかどうかに基づいている必要があります。

私たちのアプリケーションでは、DSN はアプリケーションの存続期間中に 1 回だけ設定されるため、onApplicationStart で作成される (ファイルから解析される) application.config 構造体があり、その中に application.config.dsn があります。

値がセッション間で実際に変化するが、セッションの存続期間中は変化しない場合は、セッション スコープを使用してください。

特定のリクエストで値が変更される可能性があるが、リクエストの途中ではない場合は、それをリクエストスコープに入れます。

とはいえ、依然として ryan のアドバイスに耳を傾け、デフォルトでこの値にのみ設定されるオプションの引数を追加してください。柔軟であることは常に最善です。

于 2011-07-13T16:19:39.503 に答える
0

これに対する私の提案は、基本クラスを作成し、データベースへのアクセスが必要なコンポーネントにそのコンポーネントを拡張させることです。直接の親階層にある必要はありませんが、その下のどこかにあります。

彼らの目標は、cfc をメイン プログラムから抽象化することと、簡単に構成できるようにすることの 2 つを行うことです。これにより、両方が実現します。

したがって、データベースを照会する CFC は次のようになります。

<cfcomponent extends="DataAccessBase">
<cffunction name="myFunction" access="public" returntype="string">
    <cfquery datasource="#getDSN()#" name="qStuff">select * from table</cfquery>
</cffunction>

上記のキーはそのextends="DataAccessBase"部分です。これにより、1 つの構成可能なポイントでデータ アクセスを制御できる抽象化のレイヤーが追加されますが、アプリケーション自体には関連付けられていないため、コンポーネントは実装された場所から抽象化されたままになります。

次のDataAccessBase.cfcようになります。

<cfcomponent>
<cffunction name="loadSettings">
    <cfparam name="request.settings" default="#structNew()#">
    <cfparam name="request.settigns.loaded" default="false">
    <cfif request.settings.loaded eq false>
        <!--- load settings from resource bundle etc --->
        <cfset request.settings.dsn     = 'myDSN'>
        <cfset request.settings.loaded  = true>
    </cfif>
</cffunction>
<cffunction name="getDsn" access="public" returntype="string">
    <cfset loadSettings()>
    <cfreturn request.settings.dsn>
</cffunction>

もちろん、設定の構成方法や保存方法などをより複雑にすることもできますが、それは私が思う質問の範囲外です。:)

すべてのメソッド呼び出しで DSN を渡す理由がわかりません。はい、動作しますが、必須ではありません。コンポーネントは、組み込みのデータ構造を想定して開発されているため、addItem() 呼び出しから updateItem() 呼び出しに変更されないことがわかっているため、作業が重複し、追加の障害点を意味します。:P

わかる?

于 2011-07-13T16:19:46.277 に答える