带有空参数的 Room (SQLite) WHERE 子句不起作用

Egi*_*gis 6 android android-sqlite android-room

我有实体类Person,我想从数据库中查询feature可能为也可能不为空的人员。当我将特征设置为非空时,查询有效,但当特征为空时,查询返回空列表。我做错了什么?

测试

Context context = InstrumentationRegistry.getContext();
AppDb db = Room.inMemoryDatabaseBuilder(context, AppDb.class).allowMainThreadQueries().build();
PersonDao dao = db.personDao();

dao.insert(new Person("El Risitas", "Funny"));
dao.insert(new Person("Elon Musk", "Alien"));
dao.insert(new Person("Donald Trump", null));

assertEquals(3, dao.getAll().size());

assertEquals("Funny", dao.getByFeature("Funny").get(0).getFeature());

// fails because dao.getByFeature(null) = EMPTY LIST
assertEquals(null, dao.getByFeature(null).get(0).getFeature());

Run Code Online (Sandbox Code Playgroud)

人.java

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = "person")
public class Person {

    @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) private int id;
    @ColumnInfo(name = "name") private String name;
    @ColumnInfo(name = "feature") private String feature;

    public Person(String name, String feature) {
        this.name = name;
        this.feature = feature;
    }
    public void setId(int id) { this.id = id; }
    public int getId() { return id; }
    public String getName() { return name; }
    public String getFeature() { return feature; }
}
Run Code Online (Sandbox Code Playgroud)

人道

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;

@Dao
public interface PersonDao {

    @Insert
    void insert(Person person);

    @Query("SELECT * FROM person")
    List<Person> getAll();

    @Query("SELECT * FROM person WHERE feature = :feature")
    List<Person> getByFeature(String feature);

}
Run Code Online (Sandbox Code Playgroud)

应用程序数据库

import androidx.room.Database;
import androidx.room.RoomDatabase;

@Database(
        version = 1,
        exportSchema = false,
        entities = {Person.class}
)
public abstract class AppDb extends RoomDatabase {

    public abstract PersonDao personDao();
}
Run Code Online (Sandbox Code Playgroud)

No *_*o U 14

在 SQL 中,没有任何东西等于 null。(也没有任何东西等于 null。)您必须使用is null. 所以您的查询可能类似于(未经测试)

SELECT * FROM person WHERE feature = :feature or (feature is null and :feature is null)
Run Code Online (Sandbox Code Playgroud)


Php*_*pXp 9

您还可以使用IS运算符代替=

SELECT * FROM person WHERE feature IS :feature
Run Code Online (Sandbox Code Playgroud)

来自SQLite 文档

IS 和 IS NOT 运算符的工作方式类似于 = 和 !=,除非其中一个或两个操作数均为 NULL。在这种情况下,如果两个操作数均为 NULL,则 IS 运算符的计算结果为 1(真),而 IS NOT 运算符的计算结果为 0(假)。如果一个操作数为 NULL 而另一个操作数不是 NULL,则 IS 运算符的计算结果为 0(假),而 IS NOT 运算符的计算结果为 1(真)。IS 或 IS NOT 表达式的计算结果不可能为 NULL。