IN句を作りまくる
EntityManagerを用いたselect.java
package sql;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public class Sql {
private EntityManager em;
public <T> T select(Class<? extends Object> clazz, Map<String, List<Object>> conditions) {
String tableName = camelToSnake(clazz.getSimpleName());
String select = "SELECT entity FROM " + tableName + " entity ";
String state = select + conditions.entrySet().stream()
.map(Entry::getKey)
.map(column -> "WHERE " + camelToSnake(column) + " IN :" + column)
.collect(Collectors.joining(" "));
TypedQuery query = em.createNativeQuery(state, clazz);
conditions.entrySet().forEach(map -> query.setParameter(map.getKey(), map.getValue()));
return query.getResultList;
}
public String camelToSnake(final String camel) {
final StringBuilder sb = new StringBuilder(camel.length() + camel.length());
for (int i = 0; i < camel.length(); i++) {
final char c = camel.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(sb.length() != 0 ? '_' : "").append(Character.toLowerCase(c));
} else {
sb.append(Character.toLowerCase(c));
}
}
return sb.toString();
}
}
"userName", List("A子", "B太郎")
といったMapを入れて、user_nameというカラムにIN句でリストをバインドするようにしています
NOT INを使いたい場合は、NOT IN用の引数を増やす必要があったり、完全にどんな状況でも使えるわけではありませんが
IN句である以上=よりは便利ですし、IN句も複数指定できるため
かなり汎用的といえるのではないでしょうか