下面列出了怎么用javax.persistence.criteria.MapJoin的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* @param action
* @param params
*
* @return the query for the given parameters
* */
private <T> T buildQuery(Class<? extends MCRJobAction> action, Map<String, String> params,
Function<TypedQuery<MCRJob>, T> consumer) {
EntityManager em = MCREntityManagerProvider.getCurrentEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MCRJob> query = cb.createQuery(MCRJob.class);
Root<MCRJob> jobRoot = query.from(MCRJob.class);
query.select(jobRoot);
params.keySet().forEach(key -> {
MapJoin<MCRJob, String, String> parameterJoin = jobRoot.join(MCRJob_.parameters, JoinType.INNER);
Path<String> keyPath = parameterJoin.key();
Path<String> valuePath = parameterJoin.value();
parameterJoin.on(cb.equal(keyPath, key), cb.equal(valuePath, params.get(key)));
});
query.where(cb.equal(jobRoot.get(MCRJob_.action), action));
T result = consumer.apply(em.createQuery(query));
clearPreFetch();
return result;
}
@SuppressWarnings("unchecked")
private Predicate mapToMapPredicate(final ComparisonNode node, final Path<Object> fieldPath,
final A enumField) {
if (!enumField.isMap()) {
return null;
}
final String[] graph = getSubAttributesFrom(node.getSelector());
final String keyValue = graph[graph.length - 1];
if (fieldPath instanceof MapJoin) {
// Currently we support only string key .So below cast is safe.
return cb.equal(cb.upper((Expression<String>) (((MapJoin<?, ?, ?>) fieldPath).key())),
keyValue.toUpperCase());
}
final String keyFieldName = enumField.getSubEntityMapTuple().map(Entry::getKey)
.orElseThrow(() -> new UnsupportedOperationException(
"For the fields, defined as Map, only Map java type or tuple in the form of SimpleImmutableEntry are allowed. Neither of those could be found!"));
return cb.equal(cb.upper(fieldPath.get(keyFieldName)), keyValue.toUpperCase());
}
@Override
public Expression<?> joinMapValue(Expression<?> currentCriteriaPath, MetaAttribute pathElement, Object key) {
MapJoin<Object, Object, Object> mapJoin = ((From<?, ?>) currentCriteriaPath).joinMap(pathElement.getName(),
JoinType.LEFT);
Predicate mapJoinCondition = cb.equal(mapJoin.key(), key);
Predicate nullCondition = cb.isNull(mapJoin.key());
addPredicate(cb.or(mapJoinCondition, nullCondition));
return mapJoin;
}
@Override
@SuppressWarnings({"unchecked"})
public <X, K, V> MapJoin<X, K, V> joinMap(String attributeName, JoinType jt) {
final Attribute<X, ?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( !attribute.isCollection() ) {
throw new IllegalArgumentException( "Requested attribute was not a map" );
}
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if ( !PluralAttribute.CollectionType.MAP.equals( pluralAttribute.getCollectionType() ) ) {
throw new IllegalArgumentException( "Requested attribute was not a map" );
}
return (MapJoin<X, K, V>) join( (MapAttribute) attribute, jt );
}
@Override
public Expression<?> joinMapValue(Expression<?> currentCriteriaPath, MetaAttribute pathElement, Object key) {
MapJoin<Object, Object, Object> mapJoin = ((From<?, ?>) currentCriteriaPath).joinMap(pathElement.getName(),
JoinType.LEFT);
Predicate mapJoinCondition = cb.equal(mapJoin.key(), key);
Predicate nullCondition = cb.isNull(mapJoin.key());
addPredicate(cb.or(mapJoinCondition, nullCondition));
return mapJoin;
}
/**
* {@link Specification} for retrieving {@link Target}s by "like attribute
* value".
*
* @param searchText
* to be filtered on
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> likeAttributeValue(final String searchText) {
return (targetRoot, query, cb) -> {
final String searchTextToLower = searchText.toLowerCase();
final MapJoin<JpaTarget, String, String> attributeMap = targetRoot.join(JpaTarget_.controllerAttributes,
JoinType.LEFT);
query.distinct(true);
return cb.like(cb.lower(attributeMap.value()), searchTextToLower);
};
}
private Expression<String> getExpressionToCompare(final Path innerFieldPath, final A enumField) {
if (!enumField.isMap()) {
return pathOfString(innerFieldPath);
}
if (innerFieldPath instanceof MapJoin) {
// Currently we support only string key .So below cast
// is safe.
return (Expression<String>) (((MapJoin<?, ?, ?>) pathOfString(innerFieldPath)).value());
}
final String valueFieldName = enumField.getSubEntityMapTuple().map(Entry::getValue)
.orElseThrow(() -> new UnsupportedOperationException(
"For the fields, defined as Map, only Map java type or tuple in the form of SimpleImmutableEntry are allowed. Neither of those could be found!"));
return pathOfString(innerFieldPath).get(valueFieldName);
}
@Override
@SuppressWarnings("unchecked")
public <X, K, T, V extends T> MapJoin<X, K, V> treat(MapJoin<X, K, T> join, Class<V> type) {
return treat( join, type, (j, t) -> ((MapJoinImplementor) join).treatAs( type ) );
}
@Override
public <X, K, V> MapJoin<X, K, V> correlate(MapJoin<X, K, V> source) {
final MapJoinImplementor<X, K, V> correlation = ( (MapJoinImplementor<X, K, V>) source ).correlateTo( this );
queryStructure.addCorrelationRoot( correlation );
return correlation;
}
@Override
public <K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map) {
return join( map, DEFAULT_JOIN_TYPE );
}
@Override
public <X, K, V> MapJoin<X, K, V> joinMap(String attributeName) {
return joinMap( attributeName, DEFAULT_JOIN_TYPE );
}