首页 > 解决方案 > 使用房间数据库查询在产品之间进行搜索

问题描述

在解决我的问题之前,让我告诉你我的应用程序是如何工作的。

我有一个小杂货应用程序,并通过改造从 api 获取数据,然后将其保存到 Roomdatabase。

为了更好的 Ui 实验,我需要在我的主屏幕上使用 edittext 实现 searchview。

因此,我决定在我的 dao 中编写一个查询代码,并通过标题过滤器获取所有数据。

但问题是,当我填写编辑文本并单击按钮以获取我过滤的产品时,什么也没发生,也没有任何搜索。

好吧,我想我的问题可能出在我在存储库和 viewmodel 中实现以将数据插入到 roomdatabase 的代码上。如果不是,我的代码有什么问题?

如果您查看我的代码,我将不胜感激。

这是我的代码:

这是房间表:


@Entity(tableName = "newTable")
data class RoomEntity(
    
    @PrimaryKey
        (autoGenerate = true)
    val id : Int? ,
    @ColumnInfo val title: String,
    @ColumnInfo val image: String

)

道:

@Dao
interface RoomDaoQuery {



    @Query("SELECT * FROM newTable")
    fun getAllProduct () : LiveData<List<RoomEntity>>


    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertDataToDatabase(model : List<RoomEntity>)


    @Query("SELECT * FROM newTable WHERE title LIKE '%' || :search || '%'")
    fun searchByName(search: String): List<RoomEntity>

}

存储库:

class Repository(private val database: DatabaseRoom) {


    fun getAllProduct() = database.GetDao.getAllProduct()


    private fun retrofit(): ApiRetrofit {

        return Retrofit.Builder()
            .baseUrl("http://192.168.43.106/")
            .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
            .build()
            .create(ApiRetrofit::class.java)

    }


    suspend fun fettchAllDat(): List<RoomEntity> {
        return retrofit().getProduct()

    }

    suspend fun insertToDatabase(model : List<RoomEntity>) {

        database.GetDao.insertDataToDatabase(fettchAllDat())


    }

    // this is for local search

     fun searchWithName (title : String) : List<RoomEntity> {


        return database.GetDao.searchByName(title)


    }


}

视图模型:

class ViewmodelRoom(application: Application) : AndroidViewModel(application) {

    val product = MutableLiveData<List<RoomEntity>>()
    private val repository = Repository(DatabaseRoom.getInstance(application))
    private var viewModelJob = SupervisorJob()
    private val viewModelScope = CoroutineScope(viewModelJob + Dispatchers.Default)



 fun getAllProduct() = repository.getAllProduct()



    fun setup() {

        viewModelScope.launch{
            product.postValue(repository.fettchAllDat())
            insertall()


        }

    }

    fun insertall() {


        viewModelScope.launch {

            repository.insertToDatabase(repository.fettchAllDat())

        }
    }

    fun searchByTitle(title : String) = CoroutineScope(Dispatchers.Default).launch{


        repository.searchWithName(title)


    }

}

和 MainActivity :


class MainActivity : AppCompatActivity() {


    val viewModel: ViewmodelRoom by lazy {

        ViewModelProvider(this).get(ViewmodelRoom::class.java)
    }

    @RequiresApi(Build.VERSION_CODES.M)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val editText: EditText = findViewById(R.id.edittext)
        val search: ImageView = findViewById(R.id.searchview)
        val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)


        search.setOnClickListener {


         viewModel.searchByTitle(editText.text.toString())
            editText.text.clear()


        }



        editText.addTextChangedListener(object : TextWatcher {

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

                viewModel.searchByTitle(editText.text.toString())

            }

            override fun afterTextChanged(p0: Editable?) {

            }

            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }
        })



        if (isNetworkAvaliable(applicationContext)) {

            viewModel.setup()
            viewModel.product.observe(this, Observer {

                recyclerView.apply {

                    layoutManager = GridLayoutManager(this@MainActivity, 2)
                    adapter = RecyclerAdapterMain(it, this@MainActivity)

                }

            })

        } else {


            viewModel.getAllProduct().observe(this, Observer { list ->
                recyclerView.apply {
                    layoutManager = GridLayoutManager(this@MainActivity, 2)
                    adapter = RecyclerAdapterMain(list, this@MainActivity)

                }
            })
        }


    }

标签: androidkotlinretrofit2android-room

解决方案


最后我得到了正确的结果。我把我的代码放在这里,我希望对某人有用。

道:

  @Query("SELECT * FROM newTable WHERE title LIKE :name")
    fun search (name : String) :LiveData<List<RoomEntity>>

存储库:


    fun search(name : String): LiveData<List<RoomEntity>>{

        return database.GetDao.search(name)
    }

fun search(name : String) : LiveData<List<RoomEntity>> {

    return repository.search(name)

}
MainActivity : 
    val editText: EditText = findViewById(R.id.edittext)
    val search: ImageView = findViewById(R.id.searchview)
    recyclerView = findViewById(R.id.recyclerview)


    search.setOnClickListener {

// this is an extention function that observe data
        searchProduct(editText.text.toString())


    }

   editText.addTextChangedListener(object : TextWatcher {

        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            searchProduct(editText.text.toString())
        }

        override fun afterTextChanged(p0: Editable?) {


        }

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }
    })

private fun searchProduct(title : String) {


    var searchText = title
    searchText = "%$title%"

        viewModel.search(searchText).observe(this@MainActivity , Observer {

        d("main" , "$it")

            recyclerView.apply {
                layoutManager = GridLayoutManager(this@MainActivity, 2)
                adapter = RecyclerAdapterMain(it, this@MainActivity)


                }
        })

    }







推荐阅读