今回は、検索条件を動的に変更できる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を作ることで、非常に高機能で汎用的な検索処理が実現できます。

「たくさんの検索項目を自由に組み合わせて探したい!」
というニーズにこたえる柔軟なシステムが作れるようになりますよ。

次のステップは、グルーピングされた条件(括弧処理)の自動化です。
それも学べば、もっと本格的な検索機能を手に入れられます!

ぜひトライしてみてください!


最後までお読みいただきありがとうございます。