Meetup
实体
Map<String,String> properties
田野 MEETUP_PROPERTY
表@ElementCollection
MeetupRepository
QueryDslPredicateExecutor<Meetup>
网络查询
GET /api/meetup?properties[aKey]=aValue
仅返回具有指定键和值的属性条目的Meetups:aKey = aValue。
但是,这对我不起作用。我想念什么?
简单的字段可以工作,例如名称和描述:
GET /api/meetup?name=whatever
收集字段像参与者一样工作:
GET /api/meetup?participants.name=whatever
但不是此Map字段。
我尝试通过拥有存储库来定制绑定
extend QuerydslBinderCustomizer<QMeetup>
并覆盖
customize(QuerydslBindings bindings, QMeetup meetup)
方法,但是当customize()
方法被点击时,lambda内部的绑定代码却没有。
编辑:了解到这是因为QuerydslBindings
评估查询参数的方法不允许它与pathSpecs
它内部持有的地图相匹配-里面有您的自定义绑定。
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "MEETUP_PROPERTY", joinColumns = @JoinColumn(name = "MEETUP_ID"))
@MapKeyColumn(name = "KEY")
@Column(name = "VALUE", length = 2048)
private Map<String, String> properties = new HashMap<>();
编辑: 见上文;事实证明,这对我的代码无济于事。
public interface MeetupRepository extends PagingAndSortingRepository<Meetup, Long>,
QueryDslPredicateExecutor<Meetup>,
QuerydslBinderCustomizer<QMeetup> {
@Override
default void customize(QuerydslBindings bindings, QMeetup meetup) {
bindings.bind(meetup.properties).first((path, value) -> {
BooleanBuilder builder = new BooleanBuilder();
for (String key : value.keySet()) {
builder.and(path.containsKey(key).and(path.get(key).eq(value.get(key))));
}
return builder;
});
}
QuerydslPredicateBuilder.getPredicate()
要求QuerydslBindings.getPropertyPath()
尝试2种方法从中返回路径,以便它可以使谓词QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver.postProcess()
可用。
QuerydslPredicateBuilder.getPredicate()
自动创建谓词。很好-如果可以加入,我可以手动完成QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver.postProcess()
如何覆盖该类或替换Bean?它被实例化,并在RepositoryRestMvcConfiguration.repoRequestArgumentResolver()
bean声明中作为bean返回。
repoRequestArgumentResolver
bean 来 覆盖该bean ,但是不会被使用。
RepositoryRestMvcConfiguration
s 覆盖。我无法通过设置它或来 强制 它。@Primary``@Ordered(HIGHEST_PRECEDENCE)
RepositoryRestMvcConfiguration.class
,但这也会弄乱Spring Boot的自动配置,因为它会导致 RepositoryRestMvcConfiguration's
在运行任何自动配置之前处理Bean声明。除其他外,这导致响应被杰克逊以不需要的方式序列化。好吧-好像我所期望的支持不存在。
所以问题就变成了: 我该 如何 正确地覆盖repoRequestArgumentResolver
bean?
BTW-
QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver
尴尬的非公开。:/
这就是我在应用html" target="_blank">程序上下文中替换bean的方式。
感觉有点。我希望听到一种更好的方法。
@Configuration
public class CustomQuerydslHandlerMethodArgumentResolverConfig implements ApplicationContextAware {
/**
* This class is originally the class that instantiated QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver and placed it into the Spring Application Context
* as a {@link RootResourceInformationHandlerMethodArgumentResolver} by the name of 'repoRequestArgumentResolver'.<br/>
* By injecting this bean, we can let {@link #meetupApiRepoRequestArgumentResolver} delegate as much as possible to the original code in that bean.
*/
private final RepositoryRestMvcConfiguration repositoryRestMvcConfiguration;
@Autowired
public CustomQuerydslHandlerMethodArgumentResolverConfig(RepositoryRestMvcConfiguration repositoryRestMvcConfiguration) {
this.repositoryRestMvcConfiguration = repositoryRestMvcConfiguration;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) ((GenericApplicationContext) applicationContext).getBeanFactory();
beanFactory.destroySingleton(REPO_REQUEST_ARGUMENT_RESOLVER_BEAN_NAME);
beanFactory.registerSingleton(REPO_REQUEST_ARGUMENT_RESOLVER_BEAN_NAME,
meetupApiRepoRequestArgumentResolver(applicationContext, repositoryRestMvcConfiguration));
}
/**
* This code is mostly copied from {@link RepositoryRestMvcConfiguration#repoRequestArgumentResolver()}, except the if clause checking if the QueryDsl library is
* present has been removed, since we're counting on it anyway.<br/>
* That means that if that code changes in the future, we're going to need to alter this code... :/
*/
@Bean
public RootResourceInformationHandlerMethodArgumentResolver meetupApiRepoRequestArgumentResolver(ApplicationContext applicationContext,
RepositoryRestMvcConfiguration repositoryRestMvcConfiguration) {
QuerydslBindingsFactory factory = applicationContext.getBean(QuerydslBindingsFactory.class);
QuerydslPredicateBuilder predicateBuilder = new QuerydslPredicateBuilder(repositoryRestMvcConfiguration.defaultConversionService(),
factory.getEntityPathResolver());
return new CustomQuerydslHandlerMethodArgumentResolver(repositoryRestMvcConfiguration.repositories(),
repositoryRestMvcConfiguration.repositoryInvokerFactory(repositoryRestMvcConfiguration.defaultConversionService()),
repositoryRestMvcConfiguration.resourceMetadataHandlerMethodArgumentResolver(),
predicateBuilder, factory);
}
}
这些是基于http查询参数创建我自己的Map-search谓词的代码段。再次-很想知道更好的方法。
该postProcess
方法调用:
predicate = addCustomMapPredicates(parameterMap, predicate, domainType).getValue();
就 在将predicate
引用传递到QuerydslRepositoryInvokerAdapter
构造函数并返回之前。
这是该addCustomMapPredicates
方法:
private BooleanBuilder addCustomMapPredicates(MultiValueMap<String, String> parameters, Predicate predicate, Class<?> domainType) {
BooleanBuilder booleanBuilder = new BooleanBuilder();
parameters.keySet()
.stream()
.filter(s -> s.contains("[") && matches(s) && s.endsWith("]"))
.collect(Collectors.toList())
.forEach(paramKey -> {
String property = paramKey.substring(0, paramKey.indexOf("["));
if (ReflectionUtils.findField(domainType, property) == null) {
LOGGER.warn("Skipping predicate matching on [%s]. It is not a known field on domainType %s", property, domainType.getName());
return;
}
String key = paramKey.substring(paramKey.indexOf("[") + 1, paramKey.indexOf("]"));
parameters.get(paramKey).forEach(value -> {
if (!StringUtils.hasLength(value)) {
booleanBuilder.or(matchesProperty(key, null));
} else {
booleanBuilder.or(matchesProperty(key, value));
}
});
});
return booleanBuilder.and(predicate);
}
static boolean matches(String key) {
return PATTERN.matcher(key).matches();
}
和模式:
/**
* disallow a . or ] from preceding a [
*/
private static final Pattern PATTERN = Pattern.compile(".*[^.]\\[.*[^\\[]");
null 扩展 的 的web查询 只返回具有指定键和值的属性条目的Meetups:AKEY=AVALUE。 收集字段工作,如参与者: 但不是这个地图字段。 我尝试通过使用存储库来定制绑定 编辑:见上文;事实证明,这对我的代码没有任何帮助。 要求尝试两种方法返回路径,以便生成可以使用的谓词。 1是在自定义绑定中查找。我看不到任何表达地图查询的方法 2默认为Spring的bean路径。同样的表达问题。
查询是根据用户的请求用可读格式显示从数据库中提取的数据。Navicat 提供强大的查询工具:查询编辑器 - 可直接编辑查询文本,查询创建工具、查找创建工具或聚合创建工具 - 视觉化地创建查询。你可以保存查询,用于设置自动运行任务。在主窗口中,点击 “查询”来打开查询的对象列表。你亦可以在主工具栏点击 “新建查询”来创建一个新的查询而不必打开任何连接。 若要使用外部编辑器打开查询,请右击查询并选择“
查询是根据用户的请求用可读格式显示从数据库中提取的数据。Navicat 提供强大的查询工具:查询编辑器 - 可直接编辑查询文本,查询创建工具、查找创建工具或聚合创建工具 - 视觉化地创建查询。你可以保存查询,用于设置自动运行任务。在主窗口中,点击 “查询”来打开查询的对象列表。你亦可以在主工具栏点击 “新建查询”来创建一个新的查询而不必打开任何连接。 若要使用外部编辑器打开查询,请按住 Contr
查询是根据用户的请求用可读格式显示从数据库中提取的数据。Navicat 提供强大的查询工具:查询编辑器 - 可直接编辑查询文本,查询创建工具、查找创建工具或聚合创建工具 - 视觉化地创建查询。你可以保存查询,用于设置自动运行任务。在主窗口中,点击 “查询”来打开查询的对象列表。你亦可以在主工具栏点击 “新建查询”来创建一个新的查询而不必打开任何连接。 【提示】查询(.sql 或 .js)保存于设置
问题内容: 我想使用Django REST Framework,限制可以在创作的相关字段中使用的值。 例如,考虑以下示例(基于http://django-rest-framework.org/api- guide/filtering.html 上的过滤示例,但已更改为ListCreateAPIView): 在此示例中,如何确保购买者在创建时只能等于self.request.user,并且这是可浏览
在实例详细信息页面中,点击费时查询图表。 “费时查询”页面使用历史数据来帮助你识别消耗资源的长时间运行的查询,并调查性能问题的根本原因。数据是每秒收集并随时间自动压缩。 所有受监控的实例都显示在左侧窗格中。选择一个实例以查看其费时查询图表。 Navicat Monitor 提供了有关查询的几项附加信息。点击选项卡以显示相应的图表。可用选项卡取决于已选择实例的服务器类型。 【提示】当查看 SQL S