<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 1. 前言 當然,我們所使用的就是之前使用過的`SQLite`數據庫。可以簡單回顧一下在`java`中是如何操作數據庫的: - 繼承自`SQLiteOpenHelper`類,復寫對應的方法,可以得到一個`Helper`實例; - 通過`SQLiteOpenHelper`的實例的`getWritableDatabase()`來得到一個數據庫實例; - 然后就可以通過這個數據庫實例進行`CRUD`操作; 簡單回顧一下在`Java`中的流程: ``` // 構建一個子類Helper public class MySQLiteOpenHelper extends SQLiteOpenHelper { private Context context; private String name; private String bookSql = "create table Book (id integer primary key autoincrement, " + "name text, pages integer)"; private String userSql = "create table User (name text, age integer)"; public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); this.context = context; this.name = name; } @Override public void onCreate(SQLiteDatabase db) { // 創建數據庫表 db.execSQL(bookSql); db.execSQL(userSql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists User"); onCreate(db); // 重新執行一下onCreate方法 } } // 獲取db對象 mySQLiteOpenHelper = new MySQLiteOpenHelper(getApplicationContext(), "BookDatabase.db", null, 3); SQLiteDatabase db= mySQLiteOpenHelper.getWritableDatabase(); // CRUD db.insert("Book", null, values); ``` # 2. Kotlin中的數據庫操作 雖然在`Kotlin`中也可以像上面的那種方式一樣來進行數據庫的操作,但是`Google`推出了一款數據庫框架,即:`Room`。下面就使用這個框架進行完成操作。 ## 2.1 依賴 首先需要添加依賴: ~~~ // Room def room_version = "2.2.6" implementation "androidx.room:room-runtime:$room_version" // For Kotlin use kapt instead of annotationProcessor (注意這個注釋) kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-ktx:$room_version" testImplementation "androidx.room:room-testing:$room_version" ~~~ 當然,這里在`kotlin`中使用`kapt`,我們需要導入這個插件: ~~~ plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-kapt' } ~~~ 注釋:如果項目是使用`Kotlin`語言來開發的,在添加`room-compiler`的時候使用`kapt`關鍵字,`java`語言開發的就使用`annotationProcessor`關鍵字。 ## 2.2 基礎概念 要想使用`Room`,必須要了解最基礎的三個概念: * `Entity`:實體類,對應的是數據庫的一張表結構。需要使用注解 `@Entity` 標記。默認實體類的類名為表名,字段名為數據庫中的字段。 * `Dao`:包含訪問一系列訪問數據庫的方法。需要使用注解 `@Dao` 標記。 * `Database`:數據庫持有者,作為與應用持久化相關數據的底層連接的主要接入點。需要使用注解 `@Database` 標記。 使用`@Database`注解需滿足以下條件: * 定義的類必須是一個繼承于`RoomDatabase`的抽象類。 * 在注解中需要定義與數據庫相關聯的實體類列表。 * 包含一個沒有參數的抽象方法并且返回一個帶有注解的 `@Dao`。 注釋:以上基礎概念摘自:[Jetpack架構組件 — Room入坑詳解](https://blog.csdn.net/singwhatiwanna/article/details/104890202/) ### 2.2 1 @Entity 從前面我們知道,`@Entity`作用在類上,該類對應數據庫中的一個數據表。屬性對應數據庫中的字段,那么類似的我們可以指定主鍵和注釋。同樣也是使用注解: * `@PrimaryKey`注解用來標注表的主鍵,可以使用`autoGenerate = true `來指定了主鍵自增長; * `@ColumnInfo`注解用來標注表對應的列的信息比如表名、默認值等等。 * `@Ignore` 注解顧名思義就是忽略這個字段,使用了這個注解的字段將不會在數據庫中生成對應的列信息。 ## 2.2.2 @Dao `Dao`類是一個接口,其中定義了一系列的操作數據庫的方法。`Room`也為我們的提供了相關的注解,有`@Insert`、`@Delete`、`@Update` 和 `@Query`。 比如: ``` @Query("select * from user where userId = :id") fun getUserById(id: Long): User ``` ### 2.2.3 @Database 首先需要定義一個類,繼承自`RoomDatabase`,并添加注解 `@Database` 來標識。 ## 2.3 實戰 這里我們需要一個數據庫來存儲用戶記事本的數據,大致包括如下內容: | 字段 | 說明 | | --- | --- | | `title` | 標題 | | `content` | 數據內容 | | `firstSubmit` | 首次提交時間 | | `lastModifiy` | 最后一次修改時間 | | `type` | 類型,普通記事或者待辦 | | `label` | 標簽,支持多個,使用`#`號分割 | | `category` | 分類,工作/學習/生活/... | | `groupId` | 組號,默認為1,表示單個記錄;如果為多個,表示前端顯示為重疊 | 那么首先我們需要使用`@Entity`注解來生成邏輯的表(`MFNote`): ~~~ @Entity class MFNote { @PrimaryKey(autoGenerate = true) var noteId: Int = 0 @ColumnInfo(defaultValue = "無標題") lateinit var title: String @ColumnInfo(defaultValue = "") lateinit var content: String @ColumnInfo(name = "first_submit") var submit: String? = null @ColumnInfo(name = "last_modify") var modify: String? = null var type: Int = 0 @ColumnInfo(defaultValue = "默認") lateinit var label: String @ColumnInfo(defaultValue = "默認") lateinit var category: String @ColumnInfo(name = "group_id") var groupId: Int = 1 } ~~~ 然后構建一個訪問`MFNote`表的`DAO`接口(`MFDao`): ~~~ @Dao interface MFDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(mfNote: MFNote?) @Delete fun delete(mfNote: MFNote): Int @Query("select * from MFNote") fun getAllNotes(): List<MFNote> @Query("select * from MFNote where type = :type") fun getNotesByType(type: Int): MFNote @Update fun updateNoteByNote(mfNote: MFNote) } ~~~ 參數`onConflict`,表示的是當插入的數據已經存在時候的處理邏輯,有三種操作邏輯:`REPLACE`、`ABORT`和`IGNORE`。如果不指定則默認為`ABORT`終止插入數據。這里我們將其指定為`REPLACE`替換原有數據。 最后需要構建`Room`使用的入口`RoomDatabase`。 ~~~ @Database(entities = [MFNote::class], version = 1) abstract class MFNoteDataBase : RoomDatabase() { abstract fun mfDao(): MFDao companion object { @Volatile private var mInstance: MFNoteDataBase? = null private const val DATABASE_NAME = "MFNote.db" @JvmStatic fun getInstance(context: Context): MFNoteDataBase? { if (mInstance == null) { synchronized(MFNoteDataBase::class.java) { if (mInstance == null) { mInstance = createInstance(context) } } } return mInstance } private fun createInstance(context: Context): MFNoteDataBase { mInstance = Room.databaseBuilder( context.applicationContext, MFNoteDataBase::class.java, DATABASE_NAME ).build() return mInstance as MFNoteDataBase } } } ~~~ 在這里我們只需要對一個數據庫表進行操作,所以就定義了一個抽象接口。如果需要定義多個,比如下面的寫法: ~~~ @Database(entities = [User::class, Course::class, Teacher::class, UserJoinCourse::class, IDCard::class], version = 1) abstract class AppDataBase : RoomDatabase() { abstract fun userDao(): UserDao abstract fun teacherDao(): TeacherDao abstract fun courseDao(): CourseDao abstract fun userJoinCourseDao(): UserJoinCourseDao abstract fun idCardDao(): IDCardDao } ~~~ * `@Database` 表示繼承自`RoomDatabase`的抽象類,`entities`指定表的實現類列表,`version`指定了`DB`版本 * 必須提供獲取`DAO`接口的抽象方法,比如上面定義的`movieDao()`,`Room`將通過這個方法實例化`DAO`接口 接下來就是調用了: ~~~ class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) // 調用Room數據庫 val mfDao = MFNoteDataBase.getInstance(this)?.mfDao() mfDao?.insert(MFNote()) mfDao?.getAllNotes()?.forEach { Log.e("TAG", "onCreate: ${it.title}, ${it.category}" ) } } } ~~~ 結果: ![](https://img.kancloud.cn/b0/9f/b09f59550432f50a63b44b94e8bb3668_1833x271.png) 最終我在`Dao`層添加了如下方法: ~~~ @Dao interface MFDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(mfNote: MFNote?) @Delete fun delete(mfNote: MFNote): Int @Query("select * from MFNote") fun getAllNotes(): List<MFNote> @Query("select * from MFNote where noteId = :id") fun getNoteByNoteId(id: Int): MFNote @Query("select * from MFNote where type = :type") fun getNotesByType(type: Int): List<MFNote> @Query("select * from MFNote where label like '%' || :label || '%'") fun getNotesByLabel(label: String): List<MFNote> @Query("select * from MFNote where category like '%' || :category || '%'") fun getNotesByCategory(category: String): List<MFNote> @Query("select * from MFNote where group_id = :groupId") fun getNotesByGroupId(groupId: Int): List<MFNote> @Query("select * from MFNote where first_submit >= :beginTime and first_submit <= :endTime") fun getNotesBySubmitTime(beginTime: String, endTime: String): List<MFNote> @Query("select * from MFNote where first_submit >= :beginTime") fun getNotesByStartSubmitTime(beginTime: String): List<MFNote> @Query("select * from MFNote where first_submit <= :endTime") fun getNotesByEndSubmitTime(endTime: String): List<MFNote> @Query("select * from MFNote where last_modify >= :beginTime and last_modify <= :endTime") fun getNotesByModifyTime(beginTime: String, endTime: String): List<MFNote> @Query("select * from MFNote where last_modify >= :beginTime") fun getNotesByStartModifyTime(beginTime: String): List<MFNote> @Query("select * from MFNote where last_modify <= :endTime") fun getNotesByEndModifyTime(endTime: String): List<MFNote> @Query("select * from MFNote where (title like '%' || :words || '%') or (content like '%' || :words || '%') or (first_submit like '%' || :words || '%') or (last_modify like '%' || :words || '%') or (label like '%' || :words || '%') or (category like '%' || :words || '%')") fun getNodesByKeyWords(words: String): List<MFNote> @Update fun updateNoteByNote(mfNote: MFNote) } ~~~ 測試代碼: ~~~ class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) // 調用Room數據庫 val mfDao = MFNoteDataBase.getInstance(this)?.mfDao() val mfNote = MFNote() mfNote.title = "測試" mfNote.content = "第一條測試" mfDao?.insert(mfNote) mfDao?.getAllNotes()?.forEach { Log.e("TAG", "onCreate: ${it.title}, ${it.category}" ) } val notesByType = mfDao?.getNotesByType(0) notesByType?.forEach { Log.e("TAG", "onCreate: ${it.title}, ${it.category}" ) } val entity = mfDao?.getNoteByNoteId(2) Log.e("TAG", "onCreate: ${entity?.title}, ${entity?.firstSubmit}" ) entity?.title = "厲害" mfDao?.updateNoteByNote(entity!!) } } ~~~ 以上代碼均測試通過。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看