2016-07-25 4 views
0

OK、面白い問題があります。私はjava/maven/spring-boot/cassandraを使用しています...そして、彼らが使用するMapperセットアップの動的インスタンス化を作成しようとしています。 I.E。Javaの親クラスの子定数にアクセス

//Users.java 
import com.datastax.driver.mapping.annotations.Table; 

@Table(keyspace="mykeyspace", name="users") 
public class Users { 
    @PartitionKey 
    public UUID id; 
    //... 
} 

さて、これを使用するために、私は明示的に

Users user = (DB).mapper(Users.class); 

は明らかに私のデシベルクラスで(DB)を交換...と言わざるを得ない。 これは素晴らしいモデルですが、私はコードの繰り返しの問題にぶち当たっています。私のCassandraデータベースには2つのキースペースがあり、どちらのキースペースもテーブルとまったく同じカラムを持つ同じテーブルを持っています(これは私の選択ではありません。だから私は、フォームの送信に基づいて、どちらか一方にアクセスする必要がある場合には、重複したコード、例の混乱になり:

//myWebController.java 
import ...; 

@RestController 
public class MyRestController { 

@RequestMapping(value="/orders", method=RequestMethod.POST) 
public string getOrders(...) { 
    if(Objects.equals(client, "first_client_name") { 
     //do all the things to get first keyspace objects like.... 
     FirstClientUsers users = (db).Mapper(FirstClientUsers.class); 
     //... 
    } else if(Objects.equals(client, "second_client_name") { 
     SecondClientUsers users = (db).Mapper(SecondClientUsers.class); 
     //.... 
    } 
    return ""; 
} 

は、私のようなメソッドを使用しようとしているが...

Class cls = Class.forName(STRING_INPUT_VARIABLE_HERE); 

それは基本クラスではうまくいきますが、アクセサを使用しようとすると、アクセサはインターフェイスでなければならないので機能しなくなります。クラスclを実行すると、インターフェイスはなくなります。

私は動的にこの作業を行い、可能なすべてのクライアントにコードを重複させる必要はありません。各クライアントは、カサンドラに独自のネームスペースを持ち、他のすべてのものと全く同じテーブルを持ちます。

私はデータベースモデルを変更することはできませんが、これは会社に準拠している必要があります。 PHPで これは、それが同じくらい型キャストを気にしていないので、私は簡単に行うことができ、非常に簡単です...

function getData($name) { 
    $className = $name . 'Accessor'; 
    $class = new $className(); 
} 

とパッ私は、動的なクラスを持っていますが、私はに実行している問題がタイプです私は明示的に言わなければならない仕様...

FirstClientUsers users = new FirstClientUsers(); 
//or even 
FirstClientUsers users = Class.forName("FirstClientUsers"); 

私はこれが意味を作っている願って、私はこの問題を持っている最初の人ですが、私はオンライン任意の解決策を見つけることができないことを想像することはできません。だから私は、私たちが持っているすべてのキースペースに対して全く同じロジックを複製せずに、これをどのように達成できるかを誰かが知っていることを本当に期待しています。これは、コードを保守不能にし、不必要に長くします。

ありがとうございます。ご協力いただきありがとうございます。

答えて

1

モデルクラスにキースペースを指定せず、いわゆる「キースペースごとのセッション」パターンを使用します。

あなたのモデルクラスは次のようになります(キースペースが未定義のままにしていることに注意してください):

Map<String, Mapper<Users>> mappers = new ConcurrentHashMap<String, Mapper<Users>>(); 

Cluster cluster = ...; 

Session firstClientSession = cluster.connect("keyspace_first_client"); 
Session secondClientSession = cluster.connect("keyspace_second_client"); 

MappingManager firstClientManager = new MappingManager(firstClientSession); 
MappingManager secondClientManager = new MappingManager(secondClientSession); 

mappers.put("first_client", firstClientManager.mapper(Users.class)); 
mappers.put("second_client", secondClientManager.mapper(Users.class)); 

// etc. for all clients 

あなたはその後、mappersを格納します:

@Table(name = "users") 
public class Users { 
    @PartitionKey 
    public UUID id; 
    //... 
} 

あなたの初期化コードは、このようなものを持っているでしょうオブジェクトを作成し、アプリケーションの他のコンポーネントへの依存性注入によって利用可能にします。mappersオブジェクトが注入される方法

import ... 

@RestController 
public class MyRestController { 

    @javax.inject.Inject 
    private Map<String, Mapper<Users>> mappers; 

    @RequestMapping(value = "/orders", method = RequestMethod.POST) 
    public string getOrders(...) { 
     Mapper<Users> usersMapper = getUsersMapperForClient(client); 
     // process the request with the right client's mapper 
    } 

    private Mapper<Users> getUsersMapperForClient(String client) { 
     if (mappers.containsKey(client)) 
      return mappers.get(client); 
     throw new RuntimeException("Unknown client: " + client); 
    } 
} 

注:

最後に、あなたのRESTサービスは、このようになります。

小さいニート:私はあなたのクラスUserUsers(複数形ではなく)の単数で指定します。

+0

純粋なgenuis!本当にありがとう、それはちょうど美しいです! –

+0

最後に最後に質問がありました....どのようにアクセサを処理しますか?アクセサーであなたのインタフェースの上に@Accessorタグがある場合は、あなたが使用しているクエリを書く必要があります。 atQuery( "Select * from keyspace_first_client.users WHERE email =:email") 結果 getByEmail(atParam "電子メール")文字列電子メール); クエリのキースペースをハードコードする必要があります。アクセサーのための同様のモデルのマップを作成するだけでよいのですか?正しいクライアントマップ上で実行するだけで、クエリ表記法でキースペースを定義しなくてもうまくいくと思いますか?大変ありがとうございます。あなたは非常に役に立ちます –

+1

はい、アクセサは同じ方法で動作します。クエリのキースペースを指定しないと、セッションのキースペースが使用されます。ですから、基本的には同じパターン(各クライアント/キースペースごとに1つのセッション)を使用することになります。 – adutra

関連する問題