Skip to content

Commit 2154f49

Browse files
authored
Merge pull request #194 from domaframework/builder-params
SelectBuilder に params メソッドと literals メソッドを追加
2 parents cc1c456 + 24c2e72 commit 2154f49

File tree

3 files changed

+142
-4
lines changed

3 files changed

+142
-4
lines changed

docs/sources/query-builder/index.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
このメソッドでパラメータが渡された場合、SQLインジェクション対策としてのエスケープ処理は実施されません。
2424
しかし、SQLインジェクションを防ぐためにパラメータの値にシングルクォテーションを含めることは禁止しています。
2525

26+
検索においてパラメータのリストを渡す場合は ``params`` メソッドと ``literals`` メソッドを利用できます。
27+
パラメータはカンマで連結されたSQLに変換されます。
28+
これらは、IN句と一緒に利用されることを想定されたメソッドです。
29+
2630
検索
2731
====
2832

@@ -43,8 +47,8 @@
4347
builder.sql("and");
4448
builder.sql("name like ").param(String.class, "S%");
4549
builder.sql("and");
46-
builder.sql("age > ").param(int.class, 20);
47-
Emp emp = builder.getEntitySingleResult(Emp.class);
50+
builder.sql("age in (").params(Integer.class, Arrays.asList(20, 30, 40)).sql(")");
51+
List<Emp> employees = builder.getEntityResultList(Emp.class);
4852
4953
組み立てたSQLのいくつかの方法で取得できます。
5054

src/main/java/org/seasar/doma/jdbc/builder/SelectBuilder.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,32 @@ public <P> SelectBuilder param(Class<P> paramClass, P param) {
192192
return appendParam(paramClass, param, false);
193193
}
194194

195+
/**
196+
* パラメータのリストを追加します。
197+
* <p>
198+
* パラメータのリストの要素の型には、基本型とドメインクラスを指定できます。
199+
*
200+
* @param <E>
201+
* リストの要素の型
202+
* @param elementClass
203+
* リストの要素のクラス
204+
* @param params
205+
* パラメータのリスト
206+
*
207+
* @return クエリビルダ
208+
* @throws DomaNullPointerException
209+
* {@code elementClass} もしくは {@code params} が {@code null} の場合
210+
*/
211+
public <E> SelectBuilder params(Class<E> elementClass, List<E> params) {
212+
if (elementClass == null) {
213+
throw new DomaNullPointerException("elementClass");
214+
}
215+
if (params == null) {
216+
throw new DomaNullPointerException("params");
217+
}
218+
return appendParams(elementClass, params, false);
219+
}
220+
195221
/**
196222
* リテラルとしてパラメータを追加します。
197223
* <p>
@@ -214,13 +240,55 @@ public <P> SelectBuilder literal(Class<P> paramClass, P param) {
214240
return appendParam(paramClass, param, true);
215241
}
216242

243+
/**
244+
* リテラルとしてパラメータのリストを追加します。
245+
* <p>
246+
* パラメータのリストの要素の型には、基本型とドメインクラスを指定できます。
247+
*
248+
* @param <E>
249+
* リストの要素の型
250+
* @param elementClass
251+
* リストの要素のクラス
252+
* @param params
253+
* パラメータのリスト
254+
* @return クエリビルダ
255+
* @throws DomaNullPointerException
256+
* {@code elementClass} もしくは {@code params} が {@code null} の場合
257+
*/
258+
public <E> SelectBuilder literals(Class<E> elementClass, List<E> params) {
259+
if (elementClass == null) {
260+
throw new DomaNullPointerException("elementClass");
261+
}
262+
if (params == null) {
263+
throw new DomaNullPointerException("params");
264+
}
265+
return appendParams(elementClass, params, true);
266+
}
267+
217268
private <P> SelectBuilder appendParam(Class<P> paramClass, P param,
218269
boolean literal) {
219270
helper.appendParam(new Param(paramClass, param, paramIndex, literal));
220271
paramIndex.increment();
221272
return new SubsequentSelectBuilder(config, helper, query, paramIndex);
222273
}
223274

275+
private <E> SelectBuilder appendParams(Class<E> elementClass,
276+
List<E> params, boolean literal) {
277+
SelectBuilder builder = this;
278+
int index = 0;
279+
for (E param : params) {
280+
builder = builder.appendParam(elementClass, param, literal)
281+
.sql(", ");
282+
index++;
283+
}
284+
if (index == 0) {
285+
builder = builder.sql("null");
286+
} else {
287+
builder = builder.removeLast();
288+
}
289+
return builder;
290+
}
291+
224292
/**
225293
* エンティティのインスタンスを1件返します。
226294
* <p>

src/test/java/org/seasar/doma/jdbc/builder/SelectBuilderTest.java

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,22 @@
1515
*/
1616
package org.seasar.doma.jdbc.builder;
1717

18+
import java.util.Arrays;
19+
import java.util.Collections;
1820
import java.util.List;
1921
import java.util.Map;
2022

21-
import junit.framework.TestCase;
22-
2323
import org.seasar.doma.DomaIllegalArgumentException;
2424
import org.seasar.doma.MapKeyNamingType;
2525
import org.seasar.doma.internal.jdbc.mock.MockConfig;
2626
import org.seasar.doma.jdbc.JdbcException;
27+
import org.seasar.doma.jdbc.Sql;
28+
import org.seasar.doma.jdbc.SqlParameter;
2729
import org.seasar.doma.message.Message;
2830

2931
import example.domain.PhoneNumber;
3032
import example.entity.Emp;
33+
import junit.framework.TestCase;
3134

3235
/**
3336
* @author taedium
@@ -216,4 +219,67 @@ public void testLiteral_singleQuoteIncluded() throws Exception {
216219
}
217220
}
218221

222+
public void testParams() throws Exception {
223+
SelectBuilder builder = SelectBuilder.newInstance(new MockConfig());
224+
builder.sql("select ccc from Emp");
225+
builder.sql("where");
226+
builder.sql("aaa in (")
227+
.params(String.class, Arrays.asList("x", "y", "z")).sql(")");
228+
Sql<?> sql = builder.getSql();
229+
String rawSql = String.format(
230+
"select ccc from Emp%n" + "where%n" + "aaa in (?, ?, ?)");
231+
assertEquals(rawSql, sql.getRawSql());
232+
233+
List<? extends SqlParameter> params = sql.getParameters();
234+
assertEquals(3, params.size());
235+
assertEquals("x", params.get(0).getValue());
236+
assertEquals("y", params.get(1).getValue());
237+
assertEquals("z", params.get(2).getValue());
238+
}
239+
240+
public void testParams_empty() throws Exception {
241+
SelectBuilder builder = SelectBuilder.newInstance(new MockConfig());
242+
builder.sql("select ccc from Emp");
243+
builder.sql("where");
244+
builder.sql("aaa in (")
245+
.params(String.class, Collections.emptyList()).sql(")");
246+
Sql<?> sql = builder.getSql();
247+
String rawSql = String.format(
248+
"select ccc from Emp%n" + "where%n" + "aaa in (null)");
249+
assertEquals(rawSql, sql.getRawSql());
250+
251+
List<? extends SqlParameter> params = sql.getParameters();
252+
assertEquals(0, params.size());
253+
}
254+
255+
public void testLiterals() throws Exception {
256+
SelectBuilder builder = SelectBuilder.newInstance(new MockConfig());
257+
builder.sql("select ccc from Emp");
258+
builder.sql("where");
259+
builder.sql("aaa in (")
260+
.literals(String.class, Arrays.asList("x", "y", "z")).sql(")");
261+
Sql<?> sql = builder.getSql();
262+
String rawSql = String.format(
263+
"select ccc from Emp%n" + "where%n" + "aaa in ('x', 'y', 'z')");
264+
assertEquals(rawSql, sql.getRawSql());
265+
266+
List<? extends SqlParameter> params = sql.getParameters();
267+
assertEquals(0, params.size());
268+
}
269+
270+
public void testLiterals_empty() throws Exception {
271+
SelectBuilder builder = SelectBuilder.newInstance(new MockConfig());
272+
builder.sql("select ccc from Emp");
273+
builder.sql("where");
274+
builder.sql("aaa in (").params(String.class, Collections.emptyList())
275+
.sql(")");
276+
Sql<?> sql = builder.getSql();
277+
String rawSql = String
278+
.format("select ccc from Emp%n" + "where%n" + "aaa in (null)");
279+
assertEquals(rawSql, sql.getRawSql());
280+
281+
List<? extends SqlParameter> params = sql.getParameters();
282+
assertEquals(0, params.size());
283+
}
284+
219285
}

0 commit comments

Comments
 (0)