我尝试在数据库中插入一些示例数据。
最初在我的Logcat上出现错误,说“ movie_rating”列不为空。
我注释掉了一段看起来似乎很复杂的代码,没有再次在logcat上看到该消息,但是当我用调试器检查它时仍然得到-1。
这是github仓库:https://github.com/Mf4z/Movie-bookmark/tree/debug-sample-insertion
1-这是样本插入的代码:
public class DatabaseDataWorker {
private SQLiteDatabase mDb;
public DatabaseDataWorker(SQLiteDatabase db){
this.mDb = db;
}
public void insertSampleMovies(){
insertMovies("Big Bang Theory","Series","2","22","Hey Penny","15:12","5");
insertMovies("Mr Robot","Series","1","2","Ones-and-zer0es","10:11","5");
}
/*
private void insertMovies(String name,String type,String timestamp,String rating) {
ContentValues values = new ContentValues();
values.put(MovieInfoEntry.COLUMN_MOVIE_NAME,name);
values.put(MovieInfoEntry.COLUMN_MOVIE_TYPE,type);
values.put(MovieInfoEntry.COLUMN_MOVIE_TIMESTAMP,timestamp);
values.put(MovieInfoEntry.COLUMN_MOVIE_NAME,rating);
String[] nullColumns = {MovieInfoEntry.COLUMN_MOVIE_SEASON,
MovieInfoEntry.COLUMN_MOVIE_EPISODE,
MovieInfoEntry.COLUMN_MOVIE_EPISODE_NAME };
long newRowId = mDb.insertOrThrow(MovieInfoEntry.TABLE_NAME, String.valueOf(nullColumns), values);
}
*/
private void insertMovies(String name,String type,String season,String episode,String epName,String timestamp,String rating) {
ContentValues values = new ContentValues();
values.put(MovieInfoEntry.COLUMN_MOVIE_NAME,name);
values.put(MovieInfoEntry.COLUMN_MOVIE_TYPE,type);
values.put(MovieInfoEntry.COLUMN_MOVIE_SEASON,season);
values.put(MovieInfoEntry.COLUMN_MOVIE_EPISODE,episode);
values.put(MovieInfoEntry.COLUMN_MOVIE_EPISODE_NAME,epName);
values.put(MovieInfoEntry.COLUMN_MOVIE_TIMESTAMP,timestamp);
values.put(MovieInfoEntry.COLUMN_MOVIE_NAME,rating);
long newRowId = mDb.insert(MovieInfoEntry.TABLE_NAME, null, values);
}
}
2-这是数据库架构的代码:
public class MovieBookmarkDatabaseContract {
private MovieBookmarkDatabaseContract(){}
public static final class MovieInfoEntry implements BaseColumns {
public static final String TABLE_NAME = "movie_info";
public static final String COLUMN_MOVIE_NAME = "movie_name";
public static final String COLUMN_MOVIE_TYPE = "movie_type";
public static final String COLUMN_MOVIE_SEASON = "movie_season";
public static final String COLUMN_MOVIE_EPISODE = "movie_episode";
public static final String COLUMN_MOVIE_EPISODE_NAME = "movie_episode_name";
public static final String COLUMN_MOVIE_TIMESTAMP = "movie_timestamp";
public static final String COLUMN_MOVIE_RATING = "movie_rating";
//CREATE INDEX movie_info_index ON movie_info(movie_name)
public static final String INDEX1 = TABLE_NAME+"_index1";
public static final String SQL_CREATE_INDEX1 =
"CREATE INDEX " + INDEX1 + " ON " + TABLE_NAME + "(" + COLUMN_MOVIE_NAME + ")";
/* CREATE TABLE movie_info (_id INTEGER PRIMARY KEY,movie_name TEXT NOT NULL,movie_type TEXT NOT NULL,
movie_season TEXT NOT NULL,movie_episode TEXT NOT NULL,movie_episode_name TEXT,
movie_timestamp TEXT NOT NULL,movie_rating TEXT NOT NULL)
*/
public static final String SQL_CREATE_TABLE = "CREATE TABLE "+TABLE_NAME+" ("+
_ID+" INTEGER PRIMARY KEY, " +
COLUMN_MOVIE_NAME+" TEXT NOT NULL, "+
COLUMN_MOVIE_TYPE+" TEXT NOT NULL, "+
COLUMN_MOVIE_SEASON +" TEXT, "+
COLUMN_MOVIE_EPISODE +" TEXT, "+
COLUMN_MOVIE_EPISODE_NAME +" TEXT, "+
COLUMN_MOVIE_TIMESTAMP + " TEXT NOT NULL, "+
COLUMN_MOVIE_RATING +" TEXT NOT NULL)";
}
}
3-数据库帮助程序类:
import com.emef4z.moviebookmark.MovieBookmarkDatabaseContract.MovieInfoEntry;
public class MovieBookmarkOpenHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Moviebookmark.db";
public static final int DATABASE_VERSION = 1;
public MovieBookmarkOpenHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(MovieInfoEntry.SQL_CREATE_TABLE);
db.execSQL(MovieInfoEntry.SQL_CREATE_INDEX1);
DatabaseDataWorker worker = new DatabaseDataWorker(db);
worker.insertSampleMovies();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
4-结合在一起的类:
public class WatchingFragment extends Fragment {
private MovieBookmarkOpenHelper mOpenHelper;
private RecyclerView mRecyclerItems;
private MovieRecyclerAdapter mAdapter;
private LinearLayoutManager mLinearLayoutManager;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.display_list, container, false);
mOpenHelper = new MovieBookmarkOpenHelper(getContext());
initializeDisplayContent(rootView);
return rootView;
}
@Override
public void onDestroyView() {
mOpenHelper.close();
super.onDestroyView();
}
private void initializeDisplayContent(View rootView){
mRecyclerItems = (RecyclerView)rootView.findViewById(R.id.recyclerView_list);
mLinearLayoutManager = new LinearLayoutManager(getContext());
mAdapter = new MovieRecyclerAdapter(getContext(),null);
displayMovies();
}
private void displayMovies() {
mRecyclerItems.setLayoutManager(mLinearLayoutManager);
mRecyclerItems.setAdapter(mAdapter);
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
}
}
答案 0 :(得分:0)
在 insertMovies 方法(两个签名)中,您为 rating 使用了错误的列名,即
values.put(MovieInfoEntry.COLUMN_MOVIE_NAME,rating);
似乎应该拥有
values.put(MovieInfoEntry.COLUMN_MOVIE_RATING,rating);
因此,评分将被放置在电影名称列中,并且尝试 什么 (即空)插入到 rating 列中,从而非空冲突
从日志中的消息中可以清楚地看到:-
2019-11-19 10:45:05.586 22025-22025/com.emef4z.moviebookmark E/SQLiteDatabase: Error inserting movie_name=5 movie_type=Series movie_season=1 movie_timestamp=15:12 movie_episode=2 movie_episode_name=1_ones-and-zer0es
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: movie_info.movie_rating (code 1299 SQLITE_CONSTRAINT_NOTNULL)
消息本身不是致命异常,并且被SQLiteDatabase 插入便捷方法(如设计那样)捕获,因此该方法返回-1,指示未插入行。
P.S。
较短的 insertMovies 方法可能只是:-
private void insertMovies(String name,String type,String timestamp,String rating) {
insertMovies(name,type,null,null,null,timestamp,rating);
}