项目中有增加多租户的需求,原有的代码都固定了,现在进行更改的话比较麻烦,因此直接采用拦截sql并改写的方式,将对应的表增加 where tenantId = xxx。hibernate有两种拦截器:
代码语言:java复制package org.hibernate;
import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.type.Type;
public interface Interceptor {
boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) throws CallbackException;
boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
void onCollectionRecreate(Object collection, Serializable key) throws CallbackException;
void onCollectionRemove(Object collection, Serializable key) throws CallbackException;
void onCollectionUpdate(Object collection, Serializable key) throws CallbackException;
void preFlush(Iterator entities) throws CallbackException;
void postFlush(Iterator entities) throws CallbackException;
Boolean isTransient(Object entity);
int[] findDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types);
Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException;
String getEntityName(Object object) throws CallbackException;
Object getEntity(String entityName, Serializable id) throws CallbackException;
void afterTransactionBegin(Transaction tx);
void beforeTransactionCompletion(Transaction tx);
void afterTransactionCompletion(Transaction tx);
/**
* Called when sql string is being prepared.
* @param sql sql to be prepared
* @return original or modified sql
*
* @deprecated Supply a {@link org.hibernate.resource.jdbc.spi.StatementInspector} instead, if you wish
* to inspect and alter SQL statements.
*/
@Deprecated
String onPrepareStatement(String sql);
}
Interceptor 正常用于拦截实体类操作,我们项目很多都是手写sql,可以通过实现onPrepareStatement方法来达到我们的目的。单此方法已经标记为过期,注释里面提到了新的接口类: StatementInspector
代码语言:java复制public interface StatementInspector extends Serializable {
/**
* Inspect the given SQL, possibly returning a different SQL to be used instead. Note that returning {@code null}
* is interpreted as returning the same SQL as was passed.
*
* @param sql The SQL to inspect
*
* @return The SQL to use; may be {@code null}
*/
public String inspect(String sql);
}
我们实现此类即可。在springboot中增加配置:
代码语言:txt复制spring.jpa.properties.hibernate.session_factory.statement_inspector=拦截器类
即可完成拦截并改写