Room数据库简单使用

Room 数据库简单使用

一、说明

Room是一个SQLite抽象层,使用更加简单,通过注解的方式标记相关功能,编译时自动生成响应的 impl 实现类,具有丰富的编译时校验,错误提示。

类注解:

  • @Entity:映射为数据库中的一张表。
  • @Dao:即 Data Access Objects,数据访问对象。
  • @Database:数据库,标注的类必须是抽象类,在注解中添加与数据库关联的表,包含使用 @Dao 注解标记的类的抽象方法。

类内注解:

  • @PrimaryKey():标识主键。
  • @NonNull:字段非空标识。
  • @ColumnInfo(“XXX”):字段名。
  • @Insert():插入方法。
  • @Query():查询方法。
  • @Delete:删除方法。
  • @Ignore:忽视该方法或字段。

测试过程中错误点:
1、主键需要使用 @NonNull 标注。
2、tablename 必须和实体类名称相同,大小写也要一模一样。
3、@Database 中加入 exportSchema = false。
4、@Insert 注解方法的返回值是 Long,插入多个则是 List。
5、@Query() 可以用于执行 SQL 语句,参数引用方法为“:参数名 ”,“:”不能去。
6、Entity 实体类定义中,构造函数只能显式一个,其余不显式的使用 @Ignore 标注。
7、如果定义了列值唯一,主键自带唯一。当插入的数据该列在数据库中已经存在,则会报异常SQLiteConstraintException,try/catch 打个数据已存在的 Log 即可。
8、数据操作开子线程去拿,不然也会报错。

二、使用

  1. 添加依赖
    在官网找合适版本的依赖。(Room 依赖极易出错,请小心)加在 build 的 dependencies 下。
    测试使用依赖为:
implementation "androidx.room:room-common:2.4.3"
annotationProcessor "androidx.room:room-compiler:2.4.3"
implementation "androidx.room:room-runtime:2.4.3"
  1. 使用注解自定义实体类
@Entity(tableName = "Fruit")
public class Fruit {

    @PrimaryKey
    @NonNull
    public Integer id;
    @ColumnInfo(name = "fruit_name")
    public String fruitName;
    @ColumnInfo(name = "fruit_type")
    public String fruitType;
    @ColumnInfo(name = "fruit_price")
    public Integer fruitPrice;
    @ColumnInfo(name = "fruit_num")
    public Integer fruitNum;

    @Ignore
    public Fruit(Integer id, String fruitName, String fruitType, Integer fruitPrice, Integer fruitNum) {
        this.id = id;
        this.fruitName = fruitName;
        this.fruitType = fruitType;
        this.fruitPrice = fruitPrice;
        this.fruitNum = fruitNum;
    }
    public Fruit() {
    }

    @NonNull
    public Integer getId() {
        return id;
    }

    public void setId(@NonNull Integer id) {
        this.id = id;
    }

    public String getFruitName() {
        return fruitName;
    }

    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }

    public String getFruitType() {
        return fruitType;
    }

    public void setFruitType(String fruitType) {
        this.fruitType = fruitType;
    }

    public Integer getFruitPrice() {
        return fruitPrice;
    }

    public void setFruitPrice(Integer fruitPrice) {
        this.fruitPrice = fruitPrice;
    }

    public Integer getFruitNum() {
        return fruitNum;
    }

    public void setFruitNum(Integer fruitNum) {
        this.fruitNum = fruitNum;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "id=" + id +
                ", fruitName='" + fruitName + '\'' +
                ", fruitType='" + fruitType + '\'' +
                ", fruitPrice=" + fruitPrice +
                ", fruitNum=" + fruitNum +
                '}';
    }
}
  1. 自定义 Dao 接口
@Dao
public interface MyDAO {
    /**参数可为List**/
    //返回插入的 rowId 值,long 型
    @Insert
    Long insertFruit(Fruit fruit);

    //插入列表
    @Insert
    List<Long> insertList(List<Fruit> list);

    //返回受影响的行数
    @Delete
    int deleteFruit(Fruit fruit);

    //返回受影响的行数
    @Update(entity = Fruit.class)
    int updateFruit(Fruit fruit);

    //返回查询的数据
    @Query("select * from fruit;")
    List<Fruit> selectAllFruit();
}
  1. 自定义 Database 抽象类
@Database(version = 1,entities = {Fruit.class},exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {
    public abstract MyDAO myDAO();
}
  1. 测试,需要 context
new Thread(() -> {
    MyDatabase database = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, "Fruit").build();
    MyDAO dao = database.myDAO();
    try {
        //插入单个
        dansertFruit(new Fruit(1, "橘子", "橘子", 10, 120));

        //插入 List
         List<Fruit> entityList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Fruit entity = new Fruit(i, "" + i, "" + i, i, i);
            entityList.add(entity);
        }
        dao.insertList(entityList);
    } catch (SQLiteConstraintException e) {
        //id 为 1 那一项会导致异常,因为数据库已经存在该主键数据
        Log.e(TAG, "There are same data in local!!!");
    }
        Log.d(TAG, "insert success,size:");

    //查找 Fruit
    List<Fruit> fruits = dao.selectAllFruit();

    Fruit fruit = new Fruit();
    if (fruits.size() > 0) {
         fruit = fruits.get(0);
    }
    Log.d(TAG, "初始数据库中Fruit为:" + fruit);

    //修改 Fruit
    fruit.setFruitName("苹果");
    fuit.setFruitType("苹果");
    dao.updateFruit(fruit);

    //查找 Fruit
    List<Fruit> fruitList = dao.selectAllFruit();

    Fruit f = new Fruit();
    if (fruits.size() > 0) {
        fruit = fruits.get(0);
    }
    Log.i(TAG, "修改后的数据 Fruit 为:" + f);

    //删除 Fruit
    dao.deleteFruit(f);

    //查找 Fruit
    List<Fruit> list = dao.selectAllFruit();

    Fruit fi = new Fruit();
    if (fruits.size() > 0) {
        fruit = fruits.get(0);
    }
    Log.d(TAG, "删除后数据库中Fruit为:" + fi);
}).start();

你可能感兴趣的:(数据库,java,sqlite)