Запрос JCR SQL2: привязка параметра ISDESCENDANTNODE - PullRequest
0 голосов
/ 13 мая 2019

Я пишу запрос JCR SQL2, в котором перечислены все узлы данного типа, которые являются потомками определенного пути. Когда я пишу свой запрос так:

Query query = queryManager.createQuery(
    "SELECT * FROM [cq:PageContent] where ISDESCENDANTNODE(\"/content\") AND ([sling:resourceType] = $resourceType)", Query.JCR_SQL2);
query.bindValue("resourceType", session.getValueFactory().createValue("my-type"));

работает нормально, но когда я пытаюсь связать то, что находится под ISDESCENDANTNODE, вот так:

Query query = queryManager.createQuery(
    "SELECT * FROM [cq:PageContent] where ISDESCENDANTNODE($base) AND ([sling:resourceType] = $resourceType)", Query.JCR_SQL2);
query.bindValue("base", session.getValueFactory().createValue("/content"));
query.bindValue("resourceType", session.getValueFactory().createValue("my-type"));

исключение выдается в query.bindValue ("base", ...):

"javax.jcr.query.InvalidQueryException: java.text.ParseException: Query: SELECT * FROM [cq: PageContent] где ISDESCENDANTNODE ($ base (*)) AND ([sling: resourceType] = $ resourceType); ожидается :) "

Я знаю, что могу просто объединить значение параметра в запросе, но я считаю, что это плохая практика.

1 Ответ

1 голос
/ 05 июня 2019

Насколько я могу судить, читая спецификацию JSR-283 path в ISDESCENDANTOF не разрешает привязки переменных. Та же самая грамматика описана в документации Jackrabbit , которая включает в себя довольно удобочитаемые железнодорожные схемы.

Вы правы, что в SQL крайне плохая практика непосредственного объединения запросов с пользовательским вводом. Однако, в отличие от SQL, JCR-SQL2 не позволяет выполнять обновления в хранилище содержимого. Вы должны явно использовать JCR API, чтобы сделать это, как только вы получите результирующий набор, содержащий узлы. Поэтому немного безопаснее. С другой стороны, вы все равно можете ввести запрос, который крайне плох с точки зрения производительности.

Если путь исходит от пользовательского ввода, вы можете сделать следующее:

  1. Считать параметр path откуда бы он ни исходил
  2. Кодируйте путь с помощью org.jackrabbit.util.Text или используйте другой метод проверки / сброса по вашему выбору.
  3. Объединить путь с остальной частью запроса и подготовить его, связав остальные переменные (или просто не делайте, если путь неверен)
...