2017-03-24 4 views
3
select * from users where id in() 

Die Abfrage ist oben gezeigt.Wie kann ich die Abfrage überspringen, wenn die where_in-Klausel in MyBatis 3 leer ist?

<select id="getByIds" resultMap="BaseResultMap"> 
    SELECT 
    <include refid="BaseColumnList"/> 
    FROM users 
    WHERE id IN 
    <foreach item="id" collection="ids" 
      open="(" separator="," close=")"> 
     #{id} 
    </foreach> 
</select> 

Wenn die Param ids leer ist, wird Mybatis werfen BadSqlGrammarException, die eine Abfrage wie 'select * from users where id in' erzeugen.

Wie kann ich die Abfrage überspringen und leere Liste zurückgeben, wenn ids leer ist?

Antwort

0

Mit Test:

<select id="getByIds" resultMap="BaseResultMap"> 
    SELECT 
    <include refid="BaseColumnList"/> 
    FROM users 
<if test="ids!= null"> 
    WHERE id IN 
    <foreach item="id" collection="ids" 
      open="(" separator="," close=")"> 
     #{id} 
    </foreach> 
</if> 
</select> 
+0

Dies erzeugt eine gültige Abfrage, die ausgeführt wird und alle Benutzer im Gegensatz zu den angeforderten OPs zurückgibt. – blackwizard

2

Wie kann ich Abfrage überspringen und leere Liste zurück, wenn Ids leer ist?

Um überspringen die Abfrage (nicht ausführen), nennen Sie einfach nicht Mybatis. Die Telefonvorwahl sollten überprüfen, ob ids leer ist:

return null == ids || ids.isEmpty() ? new ArrayList<User>() : session.select("getByIds", ids); 

Das ist genau das, was in der Frage gestellt wird.

Wenn Sie wirklich möchten, dass MyBatis dies behandelt, dann muss die erzeugte Abfrage gültig sein, da sie ausgeführt werden muss (dann nicht übersprungen werden), um das leere Ergebnis schnell zurückzugeben. das bedeutet, dass man etwas wie id = <!-- a value that will never exist in the table --> vergisst, weil es sicherlich einen (freien und nutzlosen) vollständigen Scan beinhalten könnte, um den nicht existierenden Wert zu suchen. Dann:

WHERE 
    <choose> 
     <when test="ids==null || ids.isEmpty()"> 
      1 = 0 <!-- a test returning false, to adapt depending on you DB vendor --> 
     </when> 
     <otherwise> 
      id IN <foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach> 
     </otherwise> 
    </choose> 

Eine weitere Möglichkeit würde darin bestehen, zu bestätigen Abfangjäger bei der Verwendung der Abfrage vor der Ausführung auf „Abbrechen“, aber dies ist auf jeden Fall viel die Gute Komplexität für das, was hier erreicht werden.

1

Java-Code-Funktion

List<ApiPriceChlogEntity> getApiAndDevPrice(@Param("apiKeys") List<String> currentApiKey, @Param("devKeys") List<String> currentDevKey, @Param("startDate") Date startDate); 

der Mapper-Datei

<select id="getApiAndDevPrice" resultMap="BaseResultMap"> 
SELECT 
<include refid="Base_Column_List"/> 
FROM t_api_price_chlog tab1 
<where> 
    <if test="apiKeys.size() > 0"> 
     tab1.api_key IN 
     <foreach collection="apiKeys" item="item" separator="," open="(" close=")" index=""> 
     #{item} 
     </foreach> 
    </if> 
    <if test="devKeys.size() > 0"> 
     AND tab1.dev_key IN 
     <foreach collection="devKeys" item="item" separator="," open="(" close=")" index=""> 
     #{item} 
     </foreach> 
    </if> 

    <if test="startDate != null"> 
     AND tab1.change_date >= #{startDate} 
    </if> 
</where> 

Ich habe Test es, Hoffnung u zu helfen.

Verwandte Themen