Webサイト全体で使用されているデータベースクエリの管理
-
21-12-2019 - |
質問
私のアプリケーションが成長したので、私は複数のWebページにわたって多くのデータベースクエリを再利用していることに気付いた。
現時点では、データベースデータを必要とするすべてのページに含まれる<cfstoredproc>
タグが多い.cfmファイルを使用して行いました。私がしているのは、これらのストアドプロシージャの実行を<cfif>
タグでラッピングしています。
私は何も専門家ではありませんが、これは私に正しいとは感じません。 Webサイト全体のCFMページで共有できるように、すべてのデータベースクエリを正しく管理する方法はわかりません。たとえば、1ページの場合、「getUsers」ストアドプロシージャが必要になる場合があり、別のページは「getOrders」が必要な場合があります。
独自の<cfstoredproc>
または<cfstoredproc>
を自身のメソッド/関数に保持するCFCの作成に着手しようとしています。 e.g。:
<cfcomponent name="DBQueries" hint="Everything for DB retrieval">
<cffunction name="GetUsers" returntype="query">
<cfstoredproc procedure="GetUsers">
<cfprocresult name="rsUsers">
</cfstoredproc>
<cfreturn rsUsers>
</cffunction>
.....
<cffunction name="DBQuery100">
<cfstoredproc procedure="GetSomething" returntype="query">
<cfprocresult name="rsSomething">
</cfstoredproc>
<cfreturn rsSomething>
</cffunction>
</cfcomponent>
.
その後、.cfmページでデータを返すために必要なコンポーネントとメソッドを呼び出します。これはDBクエリ管理を達成するための良い方法ですか?
解決
次の2つのDBテーブルを考慮してください
user
useridプライマリキー ファーストネーム LastName
セキュリティ
SecriverIDプライマリキー UserId Freaverke. 許可
すべてのデータベーステーブルに作成、読み取り、更新、削除操作(CRUD)
CRUD操作はいくつかの場所に存在する可能性があります
-
<cfquery>
タグ - ストアドプロシージャの内部
- その他
- application.user= new user();
- session.user= new user();
- request.user= new user();
物事はすべてのCRUD操作が彼ら自身の方法で一緒に属することです。ユーザーオブジェクト(user.cfc
)を作成することを検討してください。
<cfcomponent>
<cffunction name="create"></cffunction>
<cffunction name="read"></cffunction>
<cffunction name="update"></cffunction>
<cffunction name="delete"></cffunction>
</cfcomponent>
.
セキュリティはユーザー管理の一部であるため、DBテーブルに1対1のオブジェクトが一致しませんか?答えのようないくつかの環境では、答えはyes、他のものではありません。
セキュリティをユーザーマネージメントの一部にすると、user.cfc
はこの
<cfcomponent>
<cffunction name="create"></cffunction>
<cffunction name="read" hint="Read will also read security info"></cffunction>
<cffunction name="update" hint="Perhaps this can update security too"></cffunction>
<cffunction name="delete" hint="Delete will also delete security info"></cffunction>
<cffunction name="create_security"></cffunction>
<cffunction name="read_secrity" hint="This may not even be needed"></cffunction>
<cffunction name="update_security"></cffunction>
<cffunction name="delete_security" hint="This may not even be needed"></cffunction>
</cfcomponent>
.
日の終わりに、テーブルよりもはるかに少ないオブジェクト(*.cfc
s)が必要なことがわかります。
OK、今あなたはuser.cfc
あなたはそれをどうしますか?様々な方法であなたのアプリの残りの部分をあなたに添付することができます
これらの一つはそれぞれ次のものです。道路を降りる前に、メンバーデータを検討する必要があります。
<cfcomponent>
<cfset this.userid = ""><!--- This always points to the user I want to interact with --->
<cffunction name="create"></cffunction>
<cffunction name="read"></cffunction>
<cffunction name="update"></cffunction>
<cffunction name="delete"></cffunction>
</cfcomponent>
.
あなたのCRUD操作はすべての彼らの操作に対して同じUserID
と対話する可能性があります。あなたがレコードを更新した後、あなたはそれを読むことがよくあります。どのUserID
と対話しているかを常に述べるのではなく、ただそれを一度設定したいと思うかもしれません、そしてすべての関数を同じものを使うだけです。
OK、今あなたがそれらを使用する場所に戻って戻ってみましょう
application.user
システム全体には、1つのUser
オブジェクトが1つだけ存在します。リクエストがサイトに入ったときに作成されます。このオブジェクトはすべての要求に対して共有されます。ここにuser
オブジェクトを添付した場合、それはすべての要求が同じユーザーを見ていることを示唆しています。
session.user
1つのUser
オブジェクトは、外部の世界の特定のエンドユーザーに存在します。他のすべてのエンドユーザーから分離されます。これは、各エンドユーザーが自分のuser
を見ていることを示唆しているため、サイトをクリックするとまだ同じuser
request.user
要求ごとに1つのUser
オブジェクトが存在します。それは特定の要求に対してのみ存在し、次に廃棄されます。これは、特定のUser
を見ることがこの要求に意味があることを示唆していますが、次の要求はかなり異なる場合があります。
~~~~~~~~~~~~~~~ -
一日の終わりには、DBインタラクションをバンドルする方法を決定する必要があります。また、これらのバンドルされたアクションをまとめて保持する期間
他のヒント
データベース関連の事実は、コードの繰り返しがあるという事実としては関係ありません。コードをより再利用可能にするためのあなたの努力であなたは正しいトラックにあります。
クエリをCFCに入れた場合は、この1ステップをさらに講じることを検討してください。常にそれを呼び出す代わりに、Application.cfcのonApplicationStartメソッドを使用して、すべてのページ上のすべてのユーザーが使用できるアプリケーション変数を作成します。
もう1つの方法は、これらのデータベースタグをすべての.cfmファイルに配置し、application.cfcのOnRequestStartメソッドにcfincludeを置くことです。
両方の方法が機能します。そして、あなたが2つのことを比較するときほとんどのように、それぞれが他のものよりも利点を持っています。
I would have a model per table.
in there you have every query that ever does anything to that table
Lets say the Users table
Users.cfc
would have all the methods which return queries
getUsers - return alll users
getUserById - could be a paramater on the first function also.
Then when you need to work out where something in orders is being updated there is only one place to look.
I get the results like this
<cfset users = new model.Users().getUsers() />
or I use script
users = new model.Users().getUsers();
And if your really brave, try doing all the queries in script also.
One last thing to consider, if the data isn't changing, cache the query.
Things like OrderType or similar, you will get a lot of performance benefit rather than repeating the query over and over.