/** * Creates a new {@link NativeEbeanQuery} encapsulating the query annotated on the given {@link EbeanQueryMethod}. * * @param method must not be {@literal null}. * @param ebeanServer must not be {@literal null}. * @param queryString must not be {@literal null} or empty. * @param evaluationContextProvider */ public NativeEbeanQuery(EbeanQueryMethod method, EbeanServer ebeanServer, String queryString, EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { super(method, ebeanServer, queryString, evaluationContextProvider, parser); Parameters<?, ?> parameters = method.getParameters(); boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter(); boolean containsPageableOrSortInQueryExpression = queryString.contains("#pageable") || queryString.contains("#sort"); if (hasPagingOrSortingParameter && !containsPageableOrSortInQueryExpression) { throw new InvalidEbeanQueryMethodException( "Cannot use native queries with dynamic sorting and/or pagination in method " + method); } }
private Object bindAndPrepare(Object query, Parameters<?, ?> parameters) { Object result = bind(query); if (!parameters.hasPageableParameter()) { return result; } if (query instanceof Query) { Query ormQuery = (Query) query; ormQuery.setFirstRow((int) getPageable().getOffset()); ormQuery.setMaxRows(getPageable().getPageSize()); } else if (query instanceof SqlQuery) { SqlQuery sqlQuery = (SqlQuery) query; sqlQuery.setFirstRow((int) getPageable().getOffset()); sqlQuery.setMaxRows(getPageable().getPageSize()); } return result; }
/** * Creates a new {@link NativeEbeanUpdate} encapsulating the query annotated on the given {@link EbeanQueryMethod}. * * @param method must not be {@literal null}. * @param ebeanServer must not be {@literal null}. * @param queryString must not be {@literal null} or empty. * @param evaluationContextProvider */ public NativeEbeanUpdate(EbeanQueryMethod method, EbeanServer ebeanServer, String queryString, EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) { super(method, ebeanServer, queryString, evaluationContextProvider, parser); Parameters<?, ?> parameters = method.getParameters(); boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter(); boolean containsPageableOrSortInQueryExpression = queryString.contains("#pageable") || queryString.contains("#sort"); if (hasPagingOrSortingParameter && !containsPageableOrSortInQueryExpression) { throw new InvalidEbeanQueryMethodException( "Cannot use native queries with dynamic sorting and/or pagination in method " + method); } }
static String buildQuery(final String rawQuery, Parameters parameters, Object... parameterValues) { String replacedRawQuery = rawQuery; for (Iterator<Parameter> iterator = parameters.iterator(); iterator .hasNext();) { Parameter eachParameter = iterator.next(); if (Pageable.class.isAssignableFrom(eachParameter.getType()) || Sort.class.isAssignableFrom(eachParameter.getType())) { continue; } replacedRawQuery = replaceOneParameterInQuery(replacedRawQuery, eachParameter, parameterValues[eachParameter.getIndex()]); } return replacedRawQuery.trim(); }
@Test public void buildQueryConditionsWithParameters_should_work_with_the_same_placeholder_values_as_fieldkeys() throws Exception { // @Query(select = {"item_id", "sampleAttribute"}, where = // "sampleAttribute<=:sampleAttribute and item_id = :item_id") final String expectedQuery = "select item_id, sampleAttribute from `testDB.sampleEntity` where sampleAttribute<='3' and item_id = '5'"; SimpleDbQueryMethod repositoryMethod = prepareQueryMethodToTest("selectWithEqualPlaceholders", SampleEntity.class); final String toProcessRawQuery = repositoryMethod.getAnnotatedQuery(); final Parameters parameters = getMockParameters(new String[]{":sampleAttribute", ":item_id"}, new Class[]{String.class, String.class}); String resultedQuery = QueryUtils.buildQuery(toProcessRawQuery, parameters, "3", "5"); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_work_with_different_placeholder_values_as_fieldkeys() throws Exception { // @Query(select = {"item_id", "sampleAttribute"}, where = "sampleAttribute<=:attribute and item_id = :item") final String expectedQuery = "select item_id, sampleAttribute from `testDB.sampleEntity` where sampleAttribute<='3' and item_id = '5'"; SimpleDbQueryMethod repositoryMethod = prepareQueryMethodToTest("selectWithDifferentPlaceholders", SampleEntity.class); final String toProcessRawQuery = repositoryMethod.getAnnotatedQuery(); final Parameters parameters = getMockParameters(new String[]{":attribute", ":item"}, new Class[]{String.class, String.class}); String resultedQuery = QueryUtils.buildQuery(toProcessRawQuery, parameters, "3", "5"); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_work_with_primitive_type_parameter_values() throws Exception { // @Query(select = {"item_id", "sampleAttribute"}, where = "sampleAttribute<=:attribute and item_id = :item") final int age = 5; final String convertedAge = SimpleDBAttributeConverter.encode(age); final String expectedQuery = "select item_id, sampleAttribute from `testDB.sampleEntity` where sampleAttribute<='3' and item_id = '" + convertedAge + "'"; SimpleDbQueryMethod repositoryMethod = prepareQueryMethodToTest("selectWithDifferentPlaceholders", SampleEntity.class); final String toProcessRawQuery = repositoryMethod.getAnnotatedQuery(); final Parameters parameters = getMockParameters(new String[]{":attribute", ":item"}, new Class[]{String.class, int.class}); String resultedQuery = QueryUtils.buildQuery(toProcessRawQuery, parameters, "3", 5); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_construct_correct_bind_query_for_in_operator() { final String bind_query = "select * from customer_all WHERE age in ?"; final long firstAge = 23; final long secondAge = 25; final String convertedFirstAge = SimpleDBAttributeConverter.encode(firstAge); final String convertedSecondAge = SimpleDBAttributeConverter.encode(secondAge); String expectedQuery = "select * from customer_all WHERE age in ('" + convertedFirstAge + "','" + convertedSecondAge + "')"; final Parameters parameters = getMockParameters(new String[] { "?" }, new Class[] { long[].class }); String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, new long[] { firstAge, secondAge }); assertThat(resultedQuery, is(expectedQuery)); }
/** * This test shows that if a named param or an index param is used to replace a field name, this will generate an * invalid query because quotes are added surrounding the field name */ @Ignore @Test public void buildQueryConditionsWithParameters_should_construct_The_trickiest_query_for_in_operator() { final String bind_query = "select * from customer_all WHERE ?=?"; final long firstAge = 23; final String convertedFirstAge = SimpleDBAttributeConverter.encode(firstAge); String expectedQuery = "select * from customer_all WHERE name = '" + convertedFirstAge + "'"; final Parameters parameters = getMockParameters("?", "?"); String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, "name", firstAge); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_construct_correct_named_query_for_in_operator() { final String bind_query = "select * from customer_all WHERE age in :age and x= :name"; final int firstAge = 23; final int secondAge = 25; final String convertedFirstAge = SimpleDBAttributeConverter.encode(firstAge); final String convertedSecondAge = SimpleDBAttributeConverter.encode(secondAge); String expectedQuery = "select * from customer_all WHERE age in ('" + convertedFirstAge + "','"+convertedSecondAge+"') and x= 'name'"; final Parameters parameters = getMockParameters(new String[]{":name", ":age"}, new Class[]{String.class, int[].class}); String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, "name", new int[]{firstAge, secondAge}); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_construct_correct_named_query_for_in_operator_with_no_space() { final String bind_query = "select * from customer_all WHERE age in:age"; final int firstAge = 23; final int secondAge = 25; final String convertedFirstAge = SimpleDBAttributeConverter.encode(firstAge); final String convertedSecondAge = SimpleDBAttributeConverter.encode(secondAge); String expectedQuery = "select * from customer_all WHERE age in('" + convertedFirstAge + "','"+convertedSecondAge+"')"; final Parameters parameters = getMockParameters(new String[]{":age"}, new Class[]{String.class}); String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, new int[]{firstAge, secondAge}); assertThat(resultedQuery, is(expectedQuery)); }
/** * Creates a new {@link ParameterMetadataProvider} from the given {@link Iterable} of all * bindable parameter values. * * @param bindableParameterValues may be {@literal null}. * @param parameters must not be {@literal null}. */ private ParameterMetadataProvider(Iterator<Object> bindableParameterValues, Parameters<?, ?> parameters) { Assert.notNull(parameters, "Parameters must not be null!"); this.parameters = parameters.getBindableParameters().iterator(); this.expressions = new ArrayList<ParameterMetadata<?>>(); this.bindableParameterValues = bindableParameterValues; }
/** * Creates a {@link JpaQueryMethod}. * * @param method * must not be {@literal null} * @param extractor * must not be {@literal null} * @param metadata * must not be {@literal null} */ public GqQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory, JefEntityManagerFactory emf) { super(method, metadata, factory); Assert.notNull(method, "Method must not be null!"); this.method = method; this.emf = emf; Assert.isTrue(!(isModifyingQuery() && getParameters().hasSpecialParameter()), String.format("Modifying method must not contain %s!", Parameters.TYPES)); assertParameterNamesInAnnotatedQuery(); }
/** * <P> * Determine if the arguments to the method need reordered. * </P> * <P> * For searches such as {@code findBySomethingNotNull} there may be more parts than parameters needed to be bound to * them. * </P> * * @param partTree Query parts * @param bindableParameters Parameters expected */ @SuppressWarnings("unchecked") private void prepareRearrange(final PartTree partTree, final Parameters<?, ?> bindableParameters) { this.isRearrangeRequired = false; if (partTree == null || bindableParameters == null) { return; } List<String> queryParams = new ArrayList<>(); List<String> methodParams = new ArrayList<>(); Iterator<Part> partTreeIterator = partTree.getParts().iterator(); while (partTreeIterator.hasNext()) { Part part = partTreeIterator.next(); queryParams.add(part.getProperty().getSegment()); } Iterator<Parameter> bindableParameterIterator = (Iterator<Parameter>) bindableParameters.iterator(); while (bindableParameterIterator.hasNext()) { Parameter parameter = bindableParameterIterator.next(); methodParams.add(parameter.getName()); } this.rearrangeIndex = new int[queryParams.size()]; String[] paramsExpected = queryParams.toArray(new String[queryParams.size()]); String[] paramsProvided = methodParams.toArray(new String[methodParams.size()]); for (int i = 0; i < this.rearrangeIndex.length; i++) { this.rearrangeIndex[i] = i; for (int j = 0; j < paramsProvided.length; j++) { if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { this.rearrangeIndex[i] = j; this.isRearrangeRequired = true; } } } }
public static String bindQueryParameters(SimpleDbQueryMethod queryMethod, Object... parameterValues) { final String rawQuery = queryMethod.getAnnotatedQuery(); if (hasNamedParameter(queryMethod) || hasBindParameter(rawQuery)) { final Parameters parameters = queryMethod.getParameters(); return buildQuery(rawQuery, parameters, parameterValues); } return rawQuery; }
public static void validateBindParametersCount(Parameters parameters, Object... parameterValues) { int numOfParameters = parameters.getNumberOfParameters(); if (numOfParameters != parameterValues.length) { throw new MappingException( "Wrong Number of Parameters to bind in Query! Parameter Values size=" + parameterValues.length + ", Method Bind Parameters size=" + numOfParameters); } }
/** * Supported types: primitives & core java types (Date, primitive arrays, * primitive wrappers) */ public static void validateBindParametersTypes(Parameters parameters) { final Iterator<Parameter> it = parameters.iterator(); while (it.hasNext()) { final Parameter param = it.next(); final Class<?> paramType = param.getType(); if (!(param.isSpecialParameter() || SupportedCoreTypes .isSupported(paramType))) { throw (new IllegalArgumentException("Type " + paramType + " not supported as an annotated query parameter!")); } } }
/** * Creates a new {@link org.springframework.data.simpledb.query.SimpleDbQueryMethod} * * @param method * must not be {@literal null} * @param metadata * must not be {@literal null} * @param simpleDbDomain */ public SimpleDbQueryMethod(Method method, RepositoryMetadata metadata, SimpleDbDomain simpleDbDomain) { super(method, metadata); this.method = method; this.simpleDbDomain = simpleDbDomain; Assert.isTrue(!(isModifyingQuery() && getParameters().hasSpecialParameter()), String.format("Modifying method must not contain %s!", Parameters.TYPES)); }
@SuppressWarnings({ "rawtypes" }) private Parameters getMockParameters(String[] placeHolders, Class[] clazzes) { Parameters mockParameters = Mockito.mock(Parameters.class); List<Parameter> parameters = new ArrayList<Parameter>(placeHolders.length); for(int idx = 0; idx < placeHolders.length; ++idx) { parameters.add(getMockParameter(placeHolders[idx], idx, clazzes[idx])); } Mockito.when(mockParameters.iterator()).thenReturn(parameters.iterator()); Mockito.when(mockParameters.getNumberOfParameters()).thenReturn(parameters.size()); return mockParameters; }
@Test public void buildQueryConditionsWithParameters_should_work_with_WHERE_clause() { final String expectedQuery = "select * from spring_data where type = 'spring-type'"; final String rawQuery = "select * from spring_data where type = :type"; final Parameters parameters = getMockParameters(new String[]{":type"}, new Class[]{String.class}); String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-type"); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_return_a_formatted_query() { final String expectedQuery = "select * from spring_data where name = 'spring-name' and type = 'spring-type' or location = 'Timisoara'"; final String rawQuery = "select * from spring_data where name = :name and type = :type or location = :location "; final Parameters parameters = getMockParameters(new String[]{":name", ":type", ":location"}, new Class[]{String.class, String.class, String.class}); String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-name", "spring-type", "Timisoara"); assertThat(resultedQuery, is(expectedQuery)); }
@Ignore @Test public void buildQueryConditionsWithParameters_should_work_with_complex_parameters() { final String expectedQuery = "select * from spring_data where name = 'spring-name' and type = 'spring-type'"; final String rawQuery = "select * from spring_data where name = ::name and type = :"; final Parameters parameters = getMockParameters(new String[]{"::name", ":"}, new Class[]{String.class, String.class}); String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-name", "spring-type"); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void like_operators_should_be_wrapped_in_quotes() { final String expectedQuery = "select * from spring_data where first_name like '%joe' and last_name like 'dev%' and middle_name like '%o%'"; final String rawQuery = "select * from spring_data where first_name like %:fname and last_name like :lname% and middle_name like %:mname%"; final Parameters parameters = getMockParameters(new String[]{":fname", ":lname", ":mname"}, new Class[]{String.class, String.class, String.class}); String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "joe", "dev", "o"); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void bindIndexPositionParameters_should_construct_correct_query_for_Date_parameter() { final String bindQueryWithDate = "select * from customer_all WHERE date = ?"; final Date date = new Date(); final String convertedDate = SimpleDBAttributeConverter.encode(date); String expectedQuery = "select * from customer_all WHERE date = '" + convertedDate + "'"; final Parameters parameters = getMockParameters(new String[]{"?"}, new Class[]{Date.class}); String resultedQuery = QueryUtils.buildQuery(bindQueryWithDate, parameters, date); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void bindIndexPositionParameters_should_construct_correct_query_for_primitive_array_parameter() { final String bindQueryWithDate = "select * from customer_all WHERE byte_array = ?"; final byte[] byteArray = new byte[] { 1, 2, 5 }; final String convertedByteArray = SimpleDBAttributeConverter.encode(byteArray); String expectedQuery = "select * from customer_all WHERE byte_array = '" + convertedByteArray + "'"; final Parameters parameters = getMockParameters(new String[]{"?"}, new Class[]{byte[].class}); String resultedQuery = QueryUtils.buildQuery(bindQueryWithDate, parameters, byteArray); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void bindIndexPositionParameters() { final String bindQueryWithDate = "select * from customer_all WHERE byte_array = ? and c = 4"; int intValue = 5; final String convertedInt = SimpleDBAttributeConverter.encode(intValue); String expectedQuery = "select * from customer_all WHERE byte_array = '" + convertedInt + "' and c = 4"; final Parameters parameters = getMockParameters(new String[]{"?"}, new Class[]{int.class}); String resultedQuery = QueryUtils.buildQuery(bindQueryWithDate, parameters, intValue); assertThat(resultedQuery, is(expectedQuery)); }
@Test public void buildQueryConditionsWithParameters_should_construct_tricky_query_for_in_operator() { final String bind_query = "select * from customer_all WHERE age in ('1','2') and age=?"; final long firstAge = 23; final String convertedFirstAge = SimpleDBAttributeConverter.encode(firstAge); String expectedQuery = "select * from customer_all WHERE age in ('1','2') and age='" + convertedFirstAge + "'"; final Parameters parameters = getMockParameters(new String[]{"?"}, new Class[]{long.class}); String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, firstAge); assertThat(resultedQuery, is(expectedQuery)); }
/** * This test shows that if there is a String containing a '?' character, this character will be recognised as a * index parameter */ @Ignore @Test(expected = MappingException.class) public void buildQueryConditionsWithParameters_should_fail_for_wrong_string() { final String bind_query = "select * from customer_all WHERE name = 'where?' and age=?"; final Parameters parameters = getMockParameters("?"); System.out.println(QueryUtils.buildQuery(bind_query, parameters, 23)); }
/** * This test shows that a index parameter should not be in quotes * * @Test(expected = MappingException.class) */ public void buildQueryConditionsWithParameters_should_double_quote_for_already_quoted_parameter() { final String bind_query = "select * from customer_all WHERE name = '?'"; final Parameters parameters = getMockParameters("?"); QueryUtils.buildQuery(bind_query, parameters, 23); }
@Override protected Parameters<?, ?> createParameters(Method method) { return new MybatisParameters(method); }
public PagedExecution(Parameters<?, ?> parameters) { this.parameters = parameters; }
private Parameters getMockParameters(String... placeHolders) { return getMockParameters(placeHolders, new Class[placeHolders.length]); }