spring-boot - 使用枚举过滤状态
问题描述
嗨,我有弹簧服务,在存储库中我试图按枚举过滤
List<Organization> findAllByStatus(StatusType type);
由于某种原因,这个枚举参数没有传递给 sql 查询。
我where organizati0_.status=?
在 SQL 中看到,但没有传递任何参数。
知道可能是什么原因吗?
枚举:
public enum StatusType {
ACTIVE,
TO_BE_DELETED,
@Deprecated IN_ACTIVE
}
服务:
public List<Organization> getAllOrganizations() {
return Lists.newArrayList(organizationRepository.findAllByStatus(StatusType.TO_BE_DELETED));
}
解决方案
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.example.demo.jobs.CustomQueryParamMethodInterceptor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
import org.springframework.util.Assert;
public class MyJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
private EntityManager entityManager;
private static final CustomQueryParamMethodInterceptor interceptor = new CustomQueryParamMethodInterceptor();
/**
* Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
*
* @param repositoryInterface must not be {@literal null}.
*/
public MyJpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
}
/**
* The {@link EntityManager} to be used.
*
* @param entityManager the entityManager to set
*/
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext)
*/
@Override
public void setMappingContext(MappingContext<?, ?> mappingContext) {
super.setMappingContext(mappingContext);
}
/*
* (non-Javadoc)
*
* @see org.springframework.data.repository.support.
* TransactionalRepositoryFactoryBeanSupport#doCreateRepositoryFactory()
*/
@Override
protected RepositoryFactorySupport doCreateRepositoryFactory() {
RepositoryFactorySupport support = createRepositoryFactory(entityManager);
support.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
factory.addAdvice(interceptor);
}
});
return support;
}
/**
* Returns a {@link RepositoryFactorySupport}.
*
* @param entityManager
* @return
*/
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new JpaRepositoryFactory(entityManager);
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() {
Assert.notNull(entityManager, "EntityManager must not be null!");
super.afterPropertiesSet();
}
}
然后将注释添加到您的spring应用程序类
@EnableJpaRepositories(repositoryFactoryBeanClass = MyJpaRepositoryFactoryBean.class)
并创建一个方法拦截器以将枚举参数转换为特定类型
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import com.example.demo.dto.ParamWrapper;
import com.example.demo.dto.StatusType;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
public class CustomQueryParamMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
if (invocation instanceof ReflectiveMethodInvocation) {
ReflectiveMethodInvocation rmi = (ReflectiveMethodInvocation)invocation;
Object[] args = invocation.getArguments();
if (args != null && args.length > 0) {
Object[] newArgs = new Object[args.length];
for (int i=0 ;i<args.length; i++) {
if (args[i] instanceof ParamWrapper) {
ParamWrapper p = (ParamWrapper)args[i];
newArgs[i] = p.getValue();
} else {
newArgs[i] = args[i];
}
}
rmi.setArguments(newArgs);
}
}
return invocation.proceed();
}
}
ParamWrapper 是您的枚举应实现的泛型类型
public interface ParamWrapper<T> {
T getValue();
}
那么你的枚举应该像这样改变
public enum StatusType implements ParamWrapper<Integer> {
ACTIVE,
TO_BE_DELETED,
@Deprecated IN_ACTIVE;
@Override
public Integer getValue() {
//you should determine your value
return 1;
}
}
推荐阅读
- algorithm - 实现音译和音译建议的标准算法
- mysql - 如何在 MySQL 中使用 max
- python - 从数据帧列表中将数据帧合并到 for 循环中
- javascript - 如何为 blob/容器生成 azure 共享访问签名?
- go - go 如何知道从哪里获取包裹
- time-complexity - 这段代码的时间复杂度是多少?我的老师和我不能同意
- ios - 下拉菜单更新视图
- sql - 将带有 Join 的 SQL 查询转换为 X++ Dynamics AX 脚本
- angular - 如何在 Angular 内部调用关键事件
- python - 如何连接黑白图像(骨架图像)中的虚线,然后使其平滑?