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两个类库,大家可以视情况使用
博客主要讲述SQLite使用Insert插入数据时,表中id设为主键但非自增会出现约束异常。给出两种解决方案,一是添加@Insert(onConflict = OnConflictStrategy.REPLACE),二是用@PrimaryKey(autoGenerate = true)让主键自增。还介绍了具体操作步骤及相关类库使用。
701

被折叠的 条评论
为什么被折叠?



