中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

電子商務(wù)網(wǎng)站建設(shè)與實(shí)踐上機(jī)指導(dǎo)教程網(wǎng)絡(luò)營(yíng)銷最火的案例

電子商務(wù)網(wǎng)站建設(shè)與實(shí)踐上機(jī)指導(dǎo)教程,網(wǎng)絡(luò)營(yíng)銷最火的案例,國(guó)內(nèi)代理ip地址,暴走漫畫網(wǎng)站建設(shè)目的文章目錄 一、Room簡(jiǎn)介二、用RoomViewModelLiveData增刪改查數(shù)據(jù)三、下載源碼 一、Room簡(jiǎn)介 Room是Google推出的數(shù)據(jù)庫(kù)框架,是一個(gè) ORM (Object Relational Mapping)對(duì)象關(guān)系映射數(shù)據(jù)庫(kù)、其底層還是對(duì)SQLite的封裝。 Room包含三個(gè)主要組件: 數(shù)據(jù)庫(kù)類&…

文章目錄

  • 一、Room簡(jiǎn)介
  • 二、用Room+ViewModel+LiveData增刪改查數(shù)據(jù)
  • 三、下載源碼

一、Room簡(jiǎn)介

RoomGoogle推出的數(shù)據(jù)庫(kù)框架,是一個(gè) ORM (Object Relational Mapping)對(duì)象關(guān)系映射數(shù)據(jù)庫(kù)、其底層還是對(duì)SQLite的封裝。

Room包含三個(gè)主要組件:

  • 數(shù)據(jù)庫(kù)類(DataBase),用于保存數(shù)據(jù)庫(kù)并作為應(yīng)用持久性數(shù)據(jù)底層連接的主要訪問(wèn)點(diǎn)。
  • 數(shù)據(jù)實(shí)體(Entity),用于表示應(yīng)用的數(shù)據(jù)庫(kù)中的表。
  • 數(shù)據(jù)訪問(wèn)對(duì)象 (DAO),提供您的應(yīng)用可用于查詢、更新、插入和刪除數(shù)據(jù)庫(kù)中的數(shù)據(jù)的方法。
  • @Entity 表結(jié)構(gòu)實(shí)體
  • @PrimaryKey 主鍵
  • @ColumnInfo 列/字段信息

二、用Room+ViewModel+LiveData增刪改查數(shù)據(jù)

Entity、DaoDatabase 操作數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)的每個(gè)表,都對(duì)應(yīng)一個(gè)Entity,一個(gè)DaoDao負(fù)責(zé)增刪改查操作)

項(xiàng)目RoomDemo,如下圖:

build.gradle添加如下依賴:

plugins {id 'com.android.application'id 'kotlin-android'id 'kotlin-android-extensions'id 'kotlin-kapt'
}dependencies {def room_version = "2.3.0"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version"kapt "androidx.room:room-compiler:$room_version"
}

首先,創(chuàng)建一個(gè)數(shù)據(jù)表Student。先創(chuàng)建包名,在com.bignerdranch.roomdemo下創(chuàng)建一個(gè)db包,db下創(chuàng)建bean包,bean包下創(chuàng)建Student類。

package com.bignerdranch.roomdemo.db.beanimport androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import org.jetbrains.annotations.NotNull@Entity(tableName = "student")
class Student {@NotNull@PrimaryKey(autoGenerate = true)@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)var id = 0@NotNull@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)var name: String@NotNull@ColumnInfo(name = "age", typeAffinity = ColumnInfo.TEXT)var age: String/*** Room會(huì)使用這個(gè)構(gòu)造器來(lái)存儲(chǔ)數(shù)據(jù),也就是當(dāng)你從表中得到Student對(duì)象時(shí)候,Room會(huì)使用這個(gè)構(gòu)造器*/constructor(id: Int, name: String, age: String) {this.id = idthis.name = namethis.age = age}/*** 由于Room只能識(shí)別和使用一個(gè)構(gòu)造器,如果希望定義多個(gè)構(gòu)造器,你可以使用Ignore標(biāo)簽,讓Room忽略這個(gè)構(gòu)造器* 同樣,@Ignore標(biāo)簽還可用于字段,使用@Ignore標(biāo)簽標(biāo)記過(guò)的字段,Room不會(huì)持久化該字段的數(shù)據(jù)*/@Ignoreconstructor(name: String, age: String) {this.name = namethis.age = age}
}

這個(gè)@Entity就是表示數(shù)據(jù)庫(kù)中的表,Student類對(duì)應(yīng)就是Student表,@PrimaryKey表示主鍵,這里是idautoGenerate = true 是自增,@NonNull表示不為空。 @ColumnInfo表示表中的列名,name = "name"表示列名的值。

下面在db包下新建一個(gè)dao包,創(chuàng)建StudentDao,里面的代碼如下:

package com.bignerdranch.roomdemo.db.daoimport androidx.lifecycle.LiveData
import androidx.room.*
import com.bignerdranch.roomdemo.db.bean.Student@Dao
interface StudentDao {@Insertfun insertStudent(student: Student?)@Deletefun deleteStudent(student: Student?)@Updatefun updateStudent(student: Student?)@Query("SELECT * FROM student")fun getStudentList(): LiveData<List<Student?>?>? //希望監(jiān)聽學(xué)生表的變化,為其加上LiveData@Query("SELECT * FROM student WHERE id = :id")fun getStudentById(id: Int): Student?
}

StudentDao是一個(gè)接口,主要是定義了一些方法,通過(guò)注解在編譯的時(shí)候會(huì)生成實(shí)現(xiàn)類。
然后,新建main/assets/databases,并在其中放置student.db文件,其位置如下:

SQLite軟件導(dǎo)入students.db文件,如下圖:

然后,在MyDatabase.kt中,用createFromAsset()方法從assets/database/students.db創(chuàng)建Room數(shù)據(jù)庫(kù),下面是數(shù)據(jù)庫(kù)的創(chuàng)建,在db包下新建一個(gè)MyDatabase類,繼承RoomDatabase,代碼如下:

package com.bignerdranch.roomdemo.dbimport android.content.Context
import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.bignerdranch.roomdemo.db.bean.Student
import com.bignerdranch.roomdemo.db.dao.StudentDao@Database(entities = [Student::class], exportSchema = false, version = 1)
abstract class MyDatabase() : RoomDatabase() {abstract fun studentDao(): StudentDao?companion object {private val DATABASE_NAME = "my_db"private var databaseInstance: MyDatabase? = null@Synchronized //已同步fun getInstance(context: Context): MyDatabase? {if (databaseInstance == null) {databaseInstance = Room.databaseBuilder(context.applicationContext,MyDatabase::class.java,DATABASE_NAME).createFromAsset("databases/student.db").fallbackToDestructiveMigration()
//                    .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_1_3, MIGRATION_3_4).build()}return databaseInstance}val MIGRATION_1_2: Migration = object : Migration(1, 2) {override fun migrate(database: SupportSQLiteDatabase) {//do somethingLog.d("MyDatabase", "MIGRATION_1_2")}}private val MIGRATION_2_3: Migration = object : Migration(2, 3) {override fun migrate(database: SupportSQLiteDatabase) {//do somethingLog.d("MyDatabase", "MIGRATION_2_3")}}private val MIGRATION_1_3: Migration = object : Migration(1, 3) {override fun migrate(database: SupportSQLiteDatabase) {//do somethingLog.d("MyDatabase", "MIGRATION_1_3")}}val MIGRATION_3_4: Migration = object : Migration(3, 4) {override fun migrate(database: SupportSQLiteDatabase) {Log.d("MyDatabase", "MIGRATION_3_4")database.execSQL("CREATE TABLE temp_Student (" +"id INTEGER PRIMARY KEY NOT NULL," +"name TEXT," +"age TEXT)")database.execSQL("INSERT INTO temp_Student (id, name, age) " +"SELECT id, name, age FROM Student")database.execSQL("DROP TABLE Student")database.execSQL("ALTER TABLE temp_Student RENAME TO Student")}}}
}

這里的@Database注解表示這個(gè)類是用來(lái)操作數(shù)據(jù)庫(kù)的,entities = [Student::class]表示當(dāng)前數(shù)據(jù)庫(kù)中的表,只有一個(gè)Student表,多的表用應(yīng)用逗號(hào)隔開。version = 1表示數(shù)據(jù)庫(kù)的版本,可以做數(shù)據(jù)庫(kù)的升級(jí)操作。createFromAsset()Room庫(kù)中提供的。

注意這是一個(gè)抽象類,在編譯時(shí)Room會(huì)幫助構(gòu)建實(shí)現(xiàn)類。

現(xiàn)在運(yùn)行一下,手機(jī)或者模擬器都可以。然后什么都不用去做。

可以查看到,MyDatabaseStudentDao的實(shí)現(xiàn)類都自動(dòng)生成了。

ViewModel內(nèi):通過(guò) Room.Database查到LiveData數(shù)據(jù),在外部監(jiān)聽LiveData
當(dāng) Room變化時(shí),通過(guò)ViewModel內(nèi)的LiveData通知頁(yè)面數(shù)據(jù)的變化,架構(gòu)如下:

新建StudentViewModel類,該類繼承自AndroidViewModel,其中有DatabaseLiveData,代碼如下:

package com.bignerdranch.roomdemo.jetpackroomwithlivedataandviewmodeltestimport android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import com.bignerdranch.roomdemo.db.MyDatabase
import com.bignerdranch.roomdemo.db.bean.Studentclass StudentViewModel(application: Application) : AndroidViewModel(application) {private val myDatabase: MyDatabase?val liveDataStudent: LiveData<List<Student?>?>?init {myDatabase = MyDatabase.getInstance(application)liveDataStudent = myDatabase!!.studentDao()!!.getStudentList()}}

表操作無(wú)非就是那么幾個(gè),增刪改查,但是為了更直觀的顯示結(jié)果,需要對(duì)UI做一些改動(dòng)。

在工程的build.gradle中增加repositories閉包中增加jitpack庫(kù)。

然后在appbuild.gradle中的dependencies{}比包中增加

implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'

1. 修改布局
Sync一下,下面修改一下頁(yè)面的布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btnInsertStudent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_margin="12dp"android:text="Add a Student"android:textAllCaps="false" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content" />
</LinearLayout>

在這里插入圖片描述

這里就是一個(gè)按鈕和一個(gè)列表,下面創(chuàng)建列表的item布局
layout下新建一個(gè)list_item_student.xml布局,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingTop="12dp"android:paddingBottom="12dp"><TextViewandroid:id="@+id/tvId"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center" /><TextViewandroid:id="@+id/tvName"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center" /><TextViewandroid:id="@+id/tvAge"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center" /></LinearLayout>

在這里插入圖片描述

新建dialog_layout_student.xml,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><EditTextandroid:id="@+id/etName"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:autofillHints=""android:hint="Name" /><EditTextandroid:id="@+id/etAge"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:autofillHints=""android:hint="Age" /></LinearLayout>

在這里插入圖片描述

com.bignerdranch.roomdemo下新建一個(gè)adapter包,包下新建StudentAdapter類,作為列表數(shù)據(jù)的適配器。代碼如下:
2. 列表適配器

package com.bignerdranch.roomdemo.adapterimport com.bignerdranch.roomdemo.R
import com.bignerdranch.roomdemo.db.bean.Student
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import kotlinx.android.synthetic.main.list_item_student.view.*class StudentAdapter(layoutResId: Int = R.layout.list_item_student) :BaseQuickAdapter<Student, BaseViewHolder>(layoutResId) {override fun convert(holder: BaseViewHolder, item: Student) {holder.itemView.run {tvId.text = item.id.toString()tvName.text = item.nametvAge.text = item.age}}
}

然后,在MainActivity中初始化List,實(shí)例化StudentViewModel并監(jiān)聽其LiveData的變化,代碼如下:

package com.bignerdranch.roomdemoimport android.content.DialogInterface
import android.os.AsyncTask
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.bignerdranch.roomdemo.adapter.StudentAdapter
import com.bignerdranch.roomdemo.db.MyDatabase
import com.bignerdranch.roomdemo.db.bean.Student
import com.bignerdranch.roomdemo.jetpackroomwithlivedataandviewmodeltest.StudentViewModel
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemLongClickListener
import kotlinx.android.synthetic.main.activity_main.recyclerView/**** @date*/
class MainActivity : AppCompatActivity(), OnItemLongClickListener {private val mStudentAdapter by lazy {StudentAdapter().apply {setOnItemLongClickListener(this@MainActivity)}}private var myDatabase: MyDatabase? = nullprivate var studentList: MutableList<Student>? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)findViewById<View>(R.id.btnInsertStudent).setOnClickListener {openAddStudentDialog()}studentList = ArrayList()val layoutManager = LinearLayoutManager(this@MainActivity)layoutManager.orientation = LinearLayoutManager.VERTICALrecyclerView.layoutManager = layoutManagerrecyclerView.adapter = mStudentAdapter
//        mStudentAdapter.setList(studentList)myDatabase = MyDatabase.getInstance(this)val studentViewModel: StudentViewModel =ViewModelProvider(this)[StudentViewModel::class.java]studentViewModel.liveDataStudent!!.observe(this) { students ->(studentList as ArrayList<Student?>).clear()(studentList as ArrayList<Student?>).addAll(students!!)
//            studentAdapter2!!.notifyDataSetChanged()mStudentAdapter.setList(studentList)mStudentAdapter.notifyDataSetChanged()}}private fun updateOrDeleteDialog(student: Student?) {val options = arrayOf("更新", "刪除")AlertDialog.Builder(this@MainActivity).setTitle("").setItems(options) { _, which ->if (which == 0) {openUpdateStudentDialog(student)} else if (which == 1) {if (student != null) {DeleteStudentTask(student).execute()}}}.show()}private fun openAddStudentDialog() {val customView: View = this.layoutInflater.inflate(R.layout.dialog_layout_student, null)val etName = customView.findViewById<EditText>(R.id.etName)val etAge = customView.findViewById<EditText>(R.id.etAge)val builder = AlertDialog.Builder(this@MainActivity)val dialog = builder.create()dialog.setTitle("Add Student")dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK") { dialog, which ->if (TextUtils.isEmpty(etName.text.toString()) || TextUtils.isEmpty(etAge.text.toString())) {Toast.makeText(this@MainActivity, "輸入不能為空", Toast.LENGTH_SHORT).show()} else {InsertStudentTask(etName.text.toString(), etAge.text.toString()).execute()}}dialog.setButton(DialogInterface.BUTTON_NEGATIVE,"CANCEL") { dialog, which -> dialog.dismiss() }dialog.setView(customView)dialog.show()}private fun openUpdateStudentDialog(student: Student?) {if (student == null) {return}val customView: View = this.layoutInflater.inflate(R.layout.dialog_layout_student, null)val etName = customView.findViewById<EditText>(R.id.etName)val etAge = customView.findViewById<EditText>(R.id.etAge)etName.setText(student.name)etAge.setText(student.age)val builder = AlertDialog.Builder(this@MainActivity)val dialog = builder.create()dialog.setTitle("Update Student")dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK") { dialog, which ->if (TextUtils.isEmpty(etName.text.toString()) || TextUtils.isEmpty(etAge.text.toString())) {Toast.makeText(this@MainActivity, "輸入不能為空", Toast.LENGTH_SHORT).show()} else {UpdateStudentTask(student.id,etName.text.toString(),etAge.text.toString()).execute()}}dialog.setButton(DialogInterface.BUTTON_NEGATIVE,"CANCEL") { dialog, which -> dialog.dismiss() }dialog.setView(customView)dialog.show()}private inner class InsertStudentTask(var name: String, var age: String) :AsyncTask<Void?, Void?, Void?>() {override fun doInBackground(vararg params: Void?): Void? {myDatabase!!.studentDao()!!.insertStudent(Student(name, age))return null}}private inner class UpdateStudentTask(var id: Int, var name: String, var age: String) :AsyncTask<Void?, Void?, Void?>() {override fun doInBackground(vararg params: Void?): Void? {myDatabase!!.studentDao()!!.updateStudent(Student(id, name, age))return null}}private inner class DeleteStudentTask(var student: Student) : AsyncTask<Void?, Void?, Void?>() {override fun doInBackground(vararg params: Void?): Void? {myDatabase!!.studentDao()!!.deleteStudent(student)return null}}override fun onItemLongClick(adapter: BaseQuickAdapter<*, *>,view: View,position: Int): Boolean {updateOrDeleteDialog((studentList as ArrayList<Student?>)[position])return true}
}

運(yùn)行后,當(dāng)LiveData數(shù)據(jù)變化時(shí),更新UI即可,而不需要每次增刪改后都必須用QueryStudentTask() 來(lái)手動(dòng)查詢一次數(shù)據(jù)庫(kù),簡(jiǎn)化了系統(tǒng),效果如下:

三、下載源碼

下載源碼github地址:https://github.com/caobin10/RoomDemo

http://www.risenshineclean.com/news/43765.html

相關(guān)文章:

  • 網(wǎng)站建站發(fā)布平臺(tái)企業(yè)網(wǎng)站建設(shè)推廣
  • 網(wǎng)站建設(shè)和維護(hù)公司百度怎么收錄自己的網(wǎng)站
  • window2003iis建好的網(wǎng)站上海網(wǎng)站排名優(yōu)化怎么做
  • 鎮(zhèn)海官方網(wǎng)站建設(shè)網(wǎng)絡(luò)銷售怎么做才能有業(yè)務(wù)
  • 做網(wǎng)站北京培訓(xùn)網(wǎng)絡(luò)營(yíng)銷的機(jī)構(gòu)
  • 裝修廣告做哪個(gè)網(wǎng)站最好看百度站長(zhǎng)平臺(tái)網(wǎng)頁(yè)版
  • 鹽城企業(yè)做網(wǎng)站多少錢網(wǎng)絡(luò)營(yíng)銷研究背景及意義
  • 國(guó)內(nèi)知名互聯(lián)網(wǎng)公司泉州seo按天計(jì)費(fèi)
  • 專業(yè)做展會(huì)網(wǎng)站網(wǎng)絡(luò)營(yíng)銷成功的品牌
  • 新鄉(xiāng)網(wǎng)站制作手機(jī)怎么做網(wǎng)站免費(fèi)的
  • WordPress短碼生成器廣州seo顧問(wèn)seocnm
  • 網(wǎng)站音樂(lè)播放器插件衡水網(wǎng)站優(yōu)化推廣
  • 可以看所有網(wǎng)站的瀏覽器線在成都網(wǎng)站推廣公司
  • 石家莊做家教網(wǎng)站win10優(yōu)化大師有用嗎
  • 網(wǎng)頁(yè)兼容性站點(diǎn)app注冊(cè)推廣拉人
  • 做網(wǎng)站的工資無(wú)限制訪問(wèn)國(guó)外的瀏覽器
  • 武昌專業(yè)的網(wǎng)絡(luò)推廣團(tuán)隊(duì)seo的特點(diǎn)是什么
  • 要做網(wǎng)站找誰(shuí)幫忙做百度快照客服電話
  • 網(wǎng)站建設(shè)項(xiàng)目計(jì)劃書如何寫西地那非片能延時(shí)多久
  • 番禺區(qū)網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷師官網(wǎng)
  • 邢臺(tái)做網(wǎng)站的價(jià)格究竟多少錢?網(wǎng)站建設(shè)需求模板
  • JAVA做的小型網(wǎng)站有哪些今天新聞?lì)^條最新消息
  • 企業(yè)免費(fèi)郵箱注冊(cè)申請(qǐng)家庭優(yōu)化大師
  • 白城網(wǎng)站開發(fā)為企業(yè)策劃一次網(wǎng)絡(luò)營(yíng)銷活動(dòng)
  • 美食網(wǎng)站建設(shè)畢業(yè)設(shè)計(jì)產(chǎn)品推廣計(jì)劃書怎么寫
  • 外貿(mào)網(wǎng)站建站公司專業(yè)推廣圖片
  • 網(wǎng)站制作公司 番禺網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷
  • 營(yíng)口網(wǎng)站建設(shè)做網(wǎng)站seo推廣公司
  • 海珠區(qū)做網(wǎng)站的公司如何讓百度收錄自己的網(wǎng)站信息
  • 創(chuàng)建全國(guó)文明城市我們?cè)谛袆?dòng)繪畫優(yōu)化seo教程技術(shù)