国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

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

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

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

文章目錄

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

一、Room簡介

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

Room包含三個主要組件:

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

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

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

項目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)建一個數(shù)據(jù)表Student。先創(chuàng)建包名,在com.bignerdranch.roomdemo下創(chuàng)建一個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會使用這個構(gòu)造器來存儲數(shù)據(jù),也就是當(dāng)你從表中得到Student對象時候,Room會使用這個構(gòu)造器*/constructor(id: Int, name: String, age: String) {this.id = idthis.name = namethis.age = age}/*** 由于Room只能識別和使用一個構(gòu)造器,如果希望定義多個構(gòu)造器,你可以使用Ignore標(biāo)簽,讓Room忽略這個構(gòu)造器* 同樣,@Ignore標(biāo)簽還可用于字段,使用@Ignore標(biāo)簽標(biāo)記過的字段,Room不會持久化該字段的數(shù)據(jù)*/@Ignoreconstructor(name: String, age: String) {this.name = namethis.age = age}
}

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

下面在db包下新建一個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是一個接口,主要是定義了一些方法,通過注解在編譯的時候會生成實現(xiàn)類。
然后,新建main/assets/databases,并在其中放置student.db文件,其位置如下:

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

然后,在MyDatabase.kt中,用createFromAsset()方法從assets/database/students.db創(chuàng)建Room數(shù)據(jù)庫,下面是數(shù)據(jù)庫的創(chuàng)建,在db包下新建一個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注解表示這個類是用來操作數(shù)據(jù)庫的,entities = [Student::class]表示當(dāng)前數(shù)據(jù)庫中的表,只有一個Student表,多的表用應(yīng)用逗號隔開。version = 1表示數(shù)據(jù)庫的版本,可以做數(shù)據(jù)庫的升級操作。createFromAsset()Room庫中提供的。

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

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

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

ViewModel內(nèi):通過 Room.Database查到LiveData數(shù)據(jù),在外部監(jiān)聽LiveData
當(dāng) Room變化時,通過ViewModel內(nèi)的LiveData通知頁面數(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()}}

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

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

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

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

1. 修改布局
Sync一下,下面修改一下頁面的布局文件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>

在這里插入圖片描述

這里就是一個按鈕和一個列表,下面創(chuàng)建列表的item布局
layout下新建一個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下新建一個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,實例化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}
}

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

三、下載源碼

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

http://aloenet.com.cn/news/43765.html

相關(guān)文章:

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