Ci sono diversi modi per scuoiare il gatto qui. In sostanza, tutto si riduce a quale livello ti piacerebbe applicare la locazione.
Basics
L'approccio di base è quello di legare una sorta di chiave che identifica il cliente su una base per-thread, in modo che si può scoprire sul cliente il thread corrente di offerte di esecuzione con. Solitamente questo viene ottenuto popolando un ThreadLocal
con alcune informazioni relative all'autenticazione, poiché in genere è possibile derivare il tenant dall'utente connesso.
Ora se questo è a posto ci sono alcune opzioni su dove applicare la conoscenza dell'inquilino. Mi permetta di illustrare brevemente le più comuni:
Multi-tenancy sul livello di database
Un modo per separare i dati per più client è quello di avere singoli database per ogni inquilino. Dati primaverili L'astrazione principale di MongoDB per questo è l'interfaccia MongoDBFactory
. Il modo più semplice qui è quello di ignorare SimpleMongoDbFactory.getDb(String name)
e chiamare il metodo genitore con il nome del database, ad es. arricchito dal prefisso inquilino o simili.
Multi-tenancy sul livello di raccolta
Un'altra opzione è quella di avere le collezioni specifiche inquilino, per esempio tramite prefisso o postfix. Questo meccanismo può essere sfruttato utilizzando il linguaggio Spring Expression (SpEl) nell'attributo collectionName
dell'annotazione dell'annotazione . In primo luogo, esporre il prefisso inquilino attraverso un bean Spring:
@Component("tenantProvider")
public class TenantProvider {
public String getTenantId() {
// … implement ThreadLocal lookup here
}
}
Quindi utilizzare SPEL nei vostri tipi di dominio @Document
mappatura:
@Document(collectionName = "#{tenantProvider.getTenantId()}_accounts"
public class Account { … }
SPEL consente di fare riferimento a bean Spring per nome e eseguire i metodi su di essi . MongoTemplate
(e quindi l'astrazione del repository in modo transitorio) utilizzerà i metadati di mappatura della classe del documento e il sottosistema di mappatura valuterà l'attributo collectionName
per scoprire la collezione con cui interagire.
fonte
2013-05-01 20:34:03
Grazie mille per la pronta risposta di Oliver. Abbiamo già deciso di seguire il primo approccio, il livello di database. sbzoom aveva sollevato un problema: "MongoTemplate esegue il suo metodo ensureIndexes() dal suo costruttore, che chiama il database per assicurarsi che esistano indici annotati nel database.Il costruttore di MongoTemplate viene chiamato all'avvio di Spring, quindi non ho mai nemmeno la possibilità di impostare una variabile ThreadLocal. "Qual è il lavoro intorno a questo? – nicolasvdb
@Oliver per multi-tenancy a livello di raccolta, ci sarebbe un problema che il Mongo gli indici non verrebbero creati all'avvio per le raccolte? Lo farebbe su richiesta? – robinhowlett
Ma come funziona con '' 'MongoRepositories''', hanno bisogno di un' '' MongoTemplate''' al momento della creazione. mi piacerebbe avere qualche mappatura come '' '' '' per i miei scopi, ma come implementarla? –
Zarathustra