正确处理SQL Null参数

时间:2015-07-02 11:25:37

标签: java android sql sqlite

我通过检查提交给查询的每个列字段是否为空(== null)来生成SQL语句。看来我的方法非常幼稚,所以我想知道如何优雅地处理null参数。如果没有指定某些内容,则应该只匹配任何内容。

以下是代码:

public List<Flight> findMatchingFlights(Flight flight)
{
    List<Flight> foundFlights = new ArrayList<>();
    StringBuilder sqlQueryBuilder = new StringBuilder();
    sqlQueryBuilder.append("SELECT * FROM Flights");
    boolean emptyQuery = true;

    if(flight.getDeparture() != null)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
            emptyQuery = false;
        }

        sqlQueryBuilder.append("Departure = '" + flight.getDeparture() + "'");
    }

    if(flight.getArrival() != null)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
            emptyQuery = false;
        }
        else
        {
            sqlQueryBuilder.append(" AND ");
        }

        sqlQueryBuilder.append("Arrival = '" + flight.getArrival() + "'");
    }

    if(flight.getFlightNumber() != null)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
            emptyQuery = false;
        }
        else
        {
            sqlQueryBuilder.append(" AND ");
        }

        sqlQueryBuilder.append("Number = '" + flight.getFlightNumber() + "'");
    }

    if(flight.getFlightMinutes() != 0)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
            emptyQuery = false;
        }
        else
        {
            sqlQueryBuilder.append(" AND ");
        }

        sqlQueryBuilder.append("Duration = " + flight.getFlightMinutes());
    }

    /*
    ...
    A bunch more fields
    */

    if(flight.getAirplane() != null)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
        }
        else
        {
            sqlQueryBuilder.append(" AND ");
        }

        sqlQueryBuilder.append("Airplane = '" + flight.getAirplane() + "'");
    }

    sqlQueryBuilder.append(";");

    // Execute sql and fill list with rows that match
}

3 个答案:

答案 0 :(得分:2)

您可以为下面的块创建公共方法,并通过传递参数来调用方法。

if(flight.getArrival() != null)
    {
        if(emptyQuery)
        {
            sqlQueryBuilder.append(" WHERE ");
            emptyQuery = false;
        }
        else
        {
            sqlQueryBuilder.append(" AND ");
        }

        sqlQueryBuilder.append("Arrival = '" + flight.getArrival() + "'");
    }

答案 1 :(得分:1)

最好的方法是在SQL中执行技巧,而不是在Java中检查null。这就是你如何做到的。

sqlQueryBuilder.append("(Number = '" + flight.getFlightNumber() + "' OR " + flight.getFlightNumber() + " IS NULL)");

这样你就不必在java中检查null,如果flight.getFlightNumber()为null,那么这个where子句将总是返回true,这就是你想要的。

此方法的唯一缺点是该子句将包含在查询中,但由于您打算使用这些列来查询表,因此它们不是null,我会假设该表将被同样编入索引。 / p>

答案 2 :(得分:0)

sqlQueryBuilder.append("SELECT * FROM Flights WHERE 1 = 1");

然后你不需要emptyQuery标志和检查以及许多if else约束。

List<Flight> foundFlights = new ArrayList<>();
    StringBuilder sqlQueryBuilder = new StringBuilder();
    sqlQueryBuilder.append("SELECT * FROM Flights WHERE 1 = 1");

    if(flight.getDeparture() != null) {
        sqlQueryBuilder.append("AND Departure = '" + flight.getDeparture() + "'");
    }