2009-08-12 8 views
8

C#/ .Netの世界では、透過的なキャッシュを含むNHibernateやActiveRecordなどのORMがあります。データベースの更新は透過的にキャッシュに複製され、オブジェクトは利用可能なときにキャッシュから直接取り出されます(しばしばmemcachedで)。DBIx :: Classに透過的なキャッシュがありますか?

透明なキャッシュがPerlでDBIx::Classで利用できるように見えません。私は何か見落としてますか?それは一般的な必要性のように思えますが、私はCPANやGoogleでそれについて何も見つけられなかったことに驚いています。

+0

あなたは、これは非常に限られた使用のためにキャッシュされ、私は理解し何からhttp://www.google.com/search?q=DBIx%3A%3AClass+caching –

答えて

6

DBIx :: Class :: Cursor :: Cached(mstから、DBICのように)が半透明です。あなたはあなたの接続やスキーマオブジェクトにCacheオブジェクトを提供する必要があります。残念なことに、非常に身分証明書がないようです。

Cookbookには、DBIx :: CacheをDBICで使用する例がありますが、DBIx :: Class :: ResultSetに(get | set | clear)_cache関数もありますが、必要。

+1

のためのヒット曲の多くを得ます場合。検索を実行して検索の項目を何回も上書きする場合は、結果セットをキャッシュすることができます。しかし、個々のオブジェクトをキャッシュすることはできません。私はそれをテストしましたが、私の場合は助けにはなりません(実際には検索結果をキャッシュするため実際にはパフォーマンスは悪くなりますが、一度だけ使用します)。 – Julien

+1

実際は、解決策になる可能性があります。問題はリレーションシップにあります。メインの結果セットはキャッシュされますが、リレーションシップはキャッシュされません。 – Julien

5

ここには、CHIでキャッシュを追加する簡単な方法があります。私は実際にこれを試していないので、特にDBICの結果セットのシリアライズに関しては考慮していない落とし穴があるかもしれません。

これはちょっと大変ですが、それは良い出発点だと思います。すべてのDBIx :: Classテーブルクラスの基本クラスでこのようなことを行うと、透明なキャッシングを簡単に構築できるはずです。

+0

ありがとう、それは行く方法のように見えます。 Catalyst :: Model :: DBIC :: SchemaでCatalystを使用しています。検索メソッドをオーバーライドするための適切な場所が見つからないと思います。私はDBIx :: lassとDBIx :: Class :: Schemaで試しました。 $ c-> model( '' ') - > searchは新しい検索メソッドを使用しません – Julien

1

私はDBIx :: Classベースのモデルでこの同じ必要性に遭遇しました。ここで答えを見直した後、私が探している解決策は実際には見当たりません。この問題に苦しんだ後、私は自分のビジネス層がキャッシュを処理すべきだと考え始めました。私はDBIx :: Classをビジネスロジックを実装していないパーシスタンス層として扱います。私は DBIx ::クラススキーマの初期化

時に設定した$のmemcachedのキャッシュから提供され

my $network = SL::Model::App->resultset('Network')->search({ ip => '127.0.0.1' }); 

と$ネットワークオブジェクト:

は例えば、理想的なキャッシングと私の現在のコードは次のようなものになるだろう

新しいコードは次のようになります。

my $network = SL::Network->find_by_ip_or_create({ ip => '127.0.0.1' }); 

一方、近くのモジュールで:

package SL::Network; 
... 
use SL::Model::App; 
use SL::Cache; 

our $cache = SL::Cache->new; 

sub find_by_ip_or_create { 
    my ($class, $args) = @_; 

    my $network; 
    unless ($network = $cache->get('network|' . $args->{ip}) { 
     $network = SL::Model::App->resultset('Network')->find_or_create({ wan_ip => $args->{ip}}); 
     $cache->set('network|' . $args->{ip} => DBIx::Class::Schema->freeze($network)); 
    } 
    return $network; 

} 

あなたはそのアイデアを得ます。

0

私は1つも高めることができることを追加するのではなく、My::Tableで「検索」方法を追加し、

だろう - そうのように、DBIx::Class::ResultSetが提供する>検索方法:また

package Schema::ResultSet::My::Table; 
use base 'DBIx::Class::ResultSet'; 

sub search { 
    my ($self, $args) = (shift, shift); 

    # do what you want here with the args passed to ->search 
    return $self->next::method($args, @_); 
} 

をResultSetをサブクラス化する可能性が非常に高いので、すべてのResultSetにこの変更された(キャッシュされた)検索を提供することができます。したがって、すべてのテーブルのキャッシュ・コードを1つの場所に保持します。 は面倒です。

これはまだテストされていません。

上記の例を動作させるには、ディレクトリ"../Schema/ResultSet/"にスキーマクラスの名前のファイルを挿入し、Schema.pmに"load_namespaces();"が含まれていることを確認します。オーバーロードされたすべてのクラスが自動ロードされますそこに置いてください(私のCatalystインストールはそれを自動的に行いましたが、私は思い出しません)。

DBIx::Class::ResultSet

関連する問題