Android jetpack Room數據庫(一)基本使用

1.gradle添加引用


 def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

2.配置編譯器選項

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                    "room.schemaLocation":"$projectDir/schemas".toString(),  //配置並啓用架構導出到給定目錄中【"$projectDir/schemas".toString()】的json文件功能
                    "room.incremental":"true",  //啓用 Gradle 增量註釋處理器 
                    "room.expandProjection":"true"] //配置 Room 以重寫查詢 ,設置成false則不需要導出到指定目錄json文件
            }
        }
    }
}

不配置會報如下錯誤: 警告: Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide room.schemaLocation annotation processor argument OR set exportSchema to false.

3.添加權限

room數據庫需要存儲讀寫權限

 <!-- 讀寫 外部存儲 權限 -->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

4.創建實體類

需要在類上加上Entity註解

@Entity(tableName = "user",ignoredColumns = {"testField1"})  //實體類創建需要加上@Entity註解
public class User {
    @PrimaryKey(autoGenerate = true) //@PrimaryKey 聲明id這個字段爲主鍵。autoGenerate自增
    public int id;
    @ColumnInfo(name = "user_name")//@ColumnInfo將此列名重命名爲name屬性所賦值的名字
    public String userName;
    @ColumnInfo(name = "user_age")
    public int userAge;
    @ColumnInfo(name = "user_mobile")
    public String userMobile;
​
    public String testField1;
    @Ignore                       //@Ignore 此屬性不在數據庫生產列
    public String testField2;
​
    public User() {
    }
​
    @Ignore  //@Ignore 有參構造方法必須加上,否則將會報錯
    public User(String userName, int userAge) {
        this.userName = userName;
        this.userAge = userAge;
    }
    @Ignore  //@Ignore 有參構造方法必須加上,否則將會報錯
    public User(String userName, int userAge, String userMobile) {
        this.userName = userName;
        this.userAge = userAge;
        this.userMobile = userMobile;
    }
​
   
}


 

5.看看Entity註解的內容

@Target(ElementType.TYPE) //定義作用域,ElementType.TYPE表示此註解可以作用在類、接口、註解和枚舉上
@Retention(RetentionPolicy.CLASS)//保留級別 RetentionPolicy.CLASS 保留到編譯期間,反射可用
public @interface Entity {
    /**
     * The table name in the SQLite database. If not set, defaults to the class name.
     *  表名,不設置此屬性的話會默認將className作爲表名
     * @return The SQLite tableName of the Entity.
     */
    String tableName() default "";
​
    /**
     * List of indices on the table.
     * 表索引  默認爲空數組
     * @return The list of indices on the table.
     */
    Index[] indices() default {};
​
    /**
     * 是否從父類繼承索引,如果是true,將會從其父類繼承父類所聲明的所有索引,即使父類此屬性設置爲false,只要本類設置爲true,都會將父類中聲明的索引全部繼承過來。如果從父類繼承了索引,那麼從父類繼承的索引將會根據Sqlite命名規則重新命名,因爲Sqlite同一個數據庫中不允許有相同的索引
     *
     默認爲false
     */
    boolean inheritSuperIndices() default false;
​
    /**
     * The list of Primary Key column names.
     主鍵定義
     * <p>
     * If you would like to define an auto generated primary key, you can use {@link PrimaryKey}
     * annotation on the field with {@link PrimaryKey#autoGenerate()} set to {@code true}.
     *
     * @return The primary key of this Entity. Can be empty if the class has a field annotated
     * with {@link PrimaryKey}.
     */
    String[] primaryKeys() default {};
​
    /**
     * List of {@link ForeignKey} constraints on this entity.
     *外鍵
     * @return The list of {@link ForeignKey} constraints on this entity.
     */
    ForeignKey[] foreignKeys() default {};
​
    /**
     * The list of column names that should be ignored by Room.
     * <p> 忽略的屬性,即不在數據表中生成列的字段
     * Normally, you can use {@link Ignore}, but this is useful for ignoring fields inherited from
     * parents.
     * <p>
     * Columns that are part of an {@link Embedded} field can not be individually ignored. To ignore
     * columns from an inherited {@link Embedded} field, use the name of the field.
     *
     * @return The list of field names.
     */
    String[] ignoredColumns() default {};
}

6.創建接口Dao

@Dao //加上@Dao註解
public interface UserDao {
/**
*數據庫操作註解分別有: Query  Insert  Update  Delete
*
*/
    //Query的值即使要執行的sql語句
    @Query("SELECT * FROM user")
    List<User> getAll();
​
    @Query("SELECT * FROM user WHERE user_name in (:names)")
    List<User> getUsersByMames(List<String> names);
​
    //注意點: 在Room使用中,模糊匹配的格式爲" like '%' || :userName || '%' ",即在要匹配的參數值前後要加上 “||”,並且“%”要區分出來
    @Query("SELECT * FROM user WHERE user_name like '%'|| :userName ||'%' LIMIT 1")
    User getUserInfoByName(String userName);
​
    @Insert  //Insert 可以單獨插入,也可以批量插入
    void insertUser(User user);
​
    @Insert
    void insertUsers(List<User> users);
}

7.創建DataBase抽象類

//創建database類繼承自RoomDatabase類,必須聲明成abstract
//entities,指定需要創建的數據表的類,必須有Entity註解,version ,指定數據庫版本
@Database(entities = {User.class}, version = 1) 
public abstract class AppDataBase extends RoomDatabase {
    
    public abstract UserDao userDao();
​
    private final static String DATABASE_NAME = "test_db";
​
    private static AppDataBase instance;
​
    public static AppDataBase getInstance(Context context) {
        if (instance == null) {
            synchronized (AppDataBase.class) {
                if (instance == null) {
                    instance = Room.databaseBuilder(context.getApplicationContext(), AppDataBase.class, DATABASE_NAME).build();
                }
            }
        }
        return instance;
    }
​
}

8.使用

 private void createTestData() {
        new Thread() {
        //數據庫操作不能再主線程,否則會報錯
            @Override
            public void run() {
                super.run();
                User user = new User();
                user.userAge = 18;
                user.userName = "Databinding";
                user.userMobile = "15888888888";
​
            //通過query語句刪除單個數據                                               AppDataBase.getInstance(MainActivity.this).userDao().delete(user.userName);
                //插入單條數據
                AppDataBase.getInstance(MainActivity.this).userDao().insertUser(user);
​
                String names[] = new String[]{"Lifecycles", "LiveData", "Navigation", "Paging", "ViewModel"};
                int[] ages = new int[]{19, 19, 18, 20, 21};
                List<User> userList = new ArrayList<>();
                for (int i = 0; i < names.length; i++) {
                    User mUser = new User(names[i], ages[i % ages.length]);
                    userList.add(mUser);
                }
                //模擬刪除數據
                AppDataBase.getInstance(MainActivity.this).userDao().deletes(names);
            //模擬批量插入    AppDataBase.getInstance(MainActivity.this).userDao().insertUsers(userList);
​
            }
        }.start();
    }

9.下一篇預告

下一篇將會對room數據庫的升級以及複雜數據類型存儲進行記錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章