Jetpack 中Room 的使用

博客主要讲述SQLite使用Insert插入数据时,表中id设为主键但非自增会出现约束异常。给出两种解决方案,一是添加@Insert(onConflict = OnConflictStrategy.REPLACE),二是用@PrimaryKey(autoGenerate = true)让主键自增。还介绍了具体操作步骤及相关类库使用。
部署运行你感兴趣的模型镜像

1、在使用Insert 插入数据时,如果表中id只是设置为主键而没有使用自增的方式时,会出现 
     android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed:
    解决方案:在方法上面添加如下代码

 @Insert(onConflict = OnConflictStrategy.REPLACE),这样虽然可以避免程序崩溃,但这样我们插入数据库的数据可能就是一个更新之后的数据   ,而不是一条新产生的数据。如果想要插入的数据每次都是新的记录,可以利用
@PrimaryKey(autoGenerate = true)的注解方式,让主键id 每次自增

​2、具体操作使用:

      在build.gradle 文件中添加如下引用:

    implementation "androidx.room:room-runtime:2.1.0-alpha07"
    annotationProcessor "androidx.room:room-compiler:2.1.0-alpha07"

3、定义一个可操作的实体类:

@Entity(tableName = "products")
public class ProductEntity {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private int type;
    private float unitPrice;
    private float totalPrice;
    private String name;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public float getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(float unitPrice) {
        this.unitPrice = unitPrice;
    }

    public float getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(float totalPrice) {
        this.totalPrice = totalPrice;
    }


    public ProductEntity(){}

    public ProductEntity(int id, String name){
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4、定义操作数据的CURD方法:

@Dao
public interface ProductDao {
    @Insert
    void insert(ProductEntity product);

    @Update
    void update(ProductEntity product);

    @Delete
    void delete(ProductEntity product);

    @Query("SELECT * FROM products ORDER BY id DESC")
    LiveData<List<ProductEntity>> getAll();

}

5、创建数据库:

@Database(entities = {ProductEntity.class},version = 1)
public abstract  class ProductDB extends RoomDatabase {
    private static final String DB_NAME ="product_db";
    private static ProductDB mInstance;
    public abstract ProductDao productDao();
    
    public static ProductDB getInstance(Application context){
        if (mInstance == null){
            synchronized (ProductDB.class){
                if (mInstance == null){
                    mInstance = buildDatabase(context);
                }
            }
        }
        return mInstance;
    }

    private static ProductDB buildDatabase(final Application appContext) {
        return Room.databaseBuilder(appContext, ProductDB.class, DB_NAME)
                .addCallback(new Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        super.onCreate(db);
                        Log.d("markTest","db oncreate");
                    }

                    @Override
                    public void onOpen(@NonNull SupportSQLiteDatabase db) {
                        super.onOpen(db);
                        Log.d("markTest","db onOpen");
                    }
                })
               .allowMainThreadQueries().build();
    }



    public void insertData(final ProductEntity productEntity){
        runInTransaction(new Runnable() {
            @Override
            public void run() {
                productDao().insert(productEntity);
            }
        });
    }
}

6、对数据的操作:

public class HomeViewModel extends AndroidViewModel {
 
    private MediatorLiveData<List<ProductEntity>> mProductNameList = null;
    private long mInitialTime;
    private ProductDB mPoductDB;
 
    public HomeViewModel(@NonNull Application application) {
        super(application);
 
        mPoductDB = ProductDB.getInstance(application);
    }

    public void insertData(){

        ProductEntity entity = new ProductEntity();
        entity.setName("k"+ new Random().nextInt(100));
        mPoductDB.insertData(entity);
    }

    private void loadData(ProductDB db){
        mProductNameList.addSource(db.productDao().getAll(), new Observer<List<ProductEntity>>() {
            @Override
            public void onChanged(List<ProductEntity> productEntityList) {

                mProductNameList.postValue(productEntityList);
            }
        });
    }

    public LiveData<List<ProductEntity>> getProductNameList(){
        if (mProductNameList == null){
            mProductNameList = new MediatorLiveData<>();
            loadData(mPoductDB);
        }
        return mProductNameList;
    }

}

7、在Fragment中调用:

public class HomeFragment extends NavHostFragment {

    private HomeViewModel mViewModel;
    private HomeAdapter mHomeAdapter;
    private HomeFragmentBinding mBinding;
    public static HomeFragment newInstance() {
        return new HomeFragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        mBinding =  DataBindingUtil.inflate(inflater,R.layout.home_fragment,container,false);

        mBinding.btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewModel.insertData();
            }
        });
        mHomeAdapter = new HomeAdapter();
        mBinding.productsList.setAdapter(mHomeAdapter);
        return mBinding.getRoot();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mViewModel = ViewModelProviders.of(getActivity()).get(HomeViewModel.class);
        suscribeUI(mViewModel.getProductNameList());

    }
 

    private void suscribeUI(LiveData<List<ProductEntity>> liveData){
        liveData.observe(this, new Observer<List<ProductEntity>>() {
            @Override
            public void onChanged(List<ProductEntity> data) {

                mHomeAdapter.setProductList(data);
            }
        });

    }

}

注:代码中使用了lifecycle 和databinding两个类库,大家可以视情况使用

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值