今回は、検索条件を動的に変更できるDAOの作り方を、研修中に配布したSuperDaoクラスも使いながら詳しく解説します。
「AND条件」だけでなく「OR条件」にも対応できる柔軟な実装方法を紹介します!
たとえばこんな検索、やりたくなったことはありませんか?
- 「年齢が30歳以上かつ性別が女性」
 - 「名前が『田中』または『佐藤』」
 - 「部署が『営業部』か『企画部』かつ年齢が40歳以下」
 
こうした複雑な条件を自由に組み立てる方法を、例えを交えながら丁寧に説明します。
AND/OR条件に対応した検索DAOの設計
ここでは社員情報を検索するEmployeeDaoクラスの例で、AND・OR両方に対応する方法を解説します。
どう実現する?
検索条件を格納するために、以下のような構造を使います。
public class SearchCondition {
    public enum Operator { AND, OR }
    private String field;
    private String operator;  // 例: =, >=, LIKEなど
    private Object value;
    private Operator logic;   // ANDかOR
    // コンストラクタやgetter/setterは省略
}
これを使えば、複数の条件をANDやORでつなぐことができます。
実装コード例(EmployeeDao)
public class EmployeeDao extends SuperDao {
    public List<Employee> searchEmployees(List<SearchCondition> conditions) {
        List<Employee> resultList = new ArrayList<>();
        connect();
        StringBuilder sql = new StringBuilder("SELECT * FROM employee WHERE ");
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < conditions.size(); i++) {
            SearchCondition cond = conditions.get(i);
            if (i > 0) {
                sql.append(" ").append(cond.getLogic().name()).append(" ");
            }
            sql.append(cond.getField()).append(" ").append(cond.getOperator()).append(" ?");
            // 値の加工(LIKE用の%追加など)
            if ("LIKE".equalsIgnoreCase(cond.getOperator())) {
                params.add("%" + cond.getValue() + "%");
            } else {
                params.add(cond.getValue());
            }
        }
        try (PreparedStatement stmt = con.prepareStatement(sql.toString())) {
            for (int i = 0; i < params.size(); i++) {
                stmt.setObject(i + 1, params.get(i));
            }
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                Employee emp = new Employee();
                emp.setId(rs.getInt("id"));
                emp.setName(rs.getString("name"));
                emp.setAge(rs.getInt("age"));
                emp.setGender(rs.getString("gender"));
                resultList.add(emp);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }
        return resultList;
    }
}
利用例 – ANDとORを組み合わせる
List<SearchCondition> conditions = new ArrayList<>();
conditions.add(new SearchCondition("name", "LIKE", "田中", SearchCondition.Operator.OR));
conditions.add(new SearchCondition("name", "LIKE", "佐藤", SearchCondition.Operator.OR));
conditions.add(new SearchCondition("age", ">=", 30, SearchCondition.Operator.AND));
EmployeeDao dao = new EmployeeDao();
List<Employee> employees = dao.searchEmployees(conditions);
この例では次のようなSQLが実行されます:
SELECT * FROM employee WHERE name LIKE ? OR name LIKE ? AND age >= ?
ちなみにこれは次のように解釈されます:
(名前が「田中」に類似 または 名前が「佐藤」に類似) かつ 年齢が30歳以上
H2: AND/OR条件の整理(表で理解)
| 条件 | SQLの書き方 | 説明 | 
|---|---|---|
| AND | 条件1 AND 条件2 | すべての条件を満たす | 
| OR | 条件1 OR 条件2 | いずれかの条件を満たす | 
| グループ化 | (条件1 OR 条件2) AND 条件3 | 複数条件をまとめてAND/ORで比較 | 
まとめ
SuperDaoをベースに、動的にAND/OR条件を組み合わせて検索できるDAOを作ることで、非常に高機能で汎用的な検索処理が実現できます。
「たくさんの検索項目を自由に組み合わせて探したい!」
というニーズにこたえる柔軟なシステムが作れるようになりますよ。
次のステップは、グルーピングされた条件(括弧処理)の自動化です。
それも学べば、もっと本格的な検索機能を手に入れられます!
ぜひトライしてみてください!