0

I received an array of columns from Frontend. I need SELECT ---- WHERE [Received Array] = 1. However, the length of the array is dynamic.

That is, a query with a value of 1 should be written for each column received in the array.

@Select("SELECT * FROM reservation WHERE product_type = #{product_type} AND product_location = #{product_location} AND $(myArray) = 1")
    List<product> getOptionedProduct(@Param("product_type") String product_type, @Param("product_location") String product_location, @Param("myArray") List<String> myArray);

myArray has [A, B, C] I want to write like

@Select("SELECT * FROM reservation WHERE product_type = #{product_type} AND product_location = #{product_location} AND A = 1 AND B = 1 AND C = 1")

Is it possible?

1 Answer 1

1

You need to use <foreach /> tag (doc).

To use tags in annotation, you need to enclose the entire statement with <script /> tag.

@Select({
  "<script>",
  "SELECT * FROM reservation WHERE product_type = #{product_type} ",
  "AND product_location = #{product_location} ",
  "<if test='myArray != null'>",
  "  <foreach item='columnName' collection='myArray' separator=' and ' open=' and '>",
  "    ${columnName} = 1",
  "  </foreach>",
  "</if>",
  "</script>"
})
List<product> getOptionedProduct(
  @Param("product_type") String product_type, 
  @Param("product_location") String product_location, 
  @Param("myArray") List<String> myArray);

If you use Java 15 or later, you can benefit from text blocks (JEP-378).

@Select("""
  <script>
  SELECT * FROM reservation WHERE product_type = #{product_type}
  AND product_location = #{product_location}
  <if test="myArray != null">
    <foreach item="columnName" collection="myArray" separator=" and " open=" and ">
      ${columnName} = 1
    </foreach>
  </if>
  </script>
  """)

As myArray is a list of column names (right?), you have to use ${} instead of #{}.
So, you need to make sure that myArray does not contain any unexpected string to avoid SQL injection, etc..
See the FAQ entry for the details.

Sign up to request clarification or add additional context in comments.

2 Comments

Good answer, However, the OP should not consider using an array with a massive number of values. The database engine may have some limits in terms of the length of the resulting SQL statement.
As the example A, B, C is not descriptive enough, I am not so sure, but the requirement implies a bad design. A separate table with two columns (reservation_id and flag), for example, might be more appropriate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.