当前位置: 首页 > news >正文

怎么样模仿网站海口的网站建设公司

怎么样模仿网站,海口的网站建设公司,网页制作软件visual,网站建设怎么改栏目名称SQLiteOpenHelper SQLiteOpenHelper是Android开发中用于管理SQLite数据库的一个非常重要的工具类。以下是对SQLiteOpenHelper的详细介绍#xff1a; 一、基本概念 SQLiteOpenHelper是一个抽象类#xff0c;它主要用于管理数据库的创建和版本管理。通过继承这个类#xff…SQLiteOpenHelper SQLiteOpenHelper是Android开发中用于管理SQLite数据库的一个非常重要的工具类。以下是对SQLiteOpenHelper的详细介绍 一、基本概念 SQLiteOpenHelper是一个抽象类它主要用于管理数据库的创建和版本管理。通过继承这个类开发者可以重写一些方法以实现数据库的创建、升级和降级等功能。 二、主要方法 构造方法用于创建SQLiteOpenHelper对象需要传入数据库名称、版本号和一个可选的CursorFactory对象。 public SQLiteOpenHelper(Nullable Context context, Nullable String name, Nullable SQLiteDatabase.CursorFactory factory, int version) public SQLiteOpenHelper(Nullable Context context, Nullable String name, Nullable SQLiteDatabase.CursorFactory factory, int version, Nullable DatabaseErrorHandler errorHandler) public SQLiteOpenHelper(Nullable Context context, Nullable String name, int version, NonNull SQLiteDatabase.OpenParams openParams)onCreate(SQLiteDatabase db)在数据库第一次创建时调用用于执行创建表和初始化数据等操作。onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)在数据库版本升级时调用用于执行表结构的修改、数据迁移等操作。onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)在数据库版本降级时调用但这个方法不是必须的因为在实际开发中降级操作并不常见。getReadableDatabase()获取一个可读的数据库对象。如果数据库不存在则会先调用onCreate()方法创建数据库。getWritableDatabase()获取一个可写的数据库对象。如果数据库不存在也会先调用onCreate()方法创建数据库。 SQLiteOpenHelper的主要方法 方法名 作用 备注 SQLiteOpenHelper(构造方法三个创建SQLiteOpenHelper实例一般用 new SQLiteOpenHelper(Context context, String databaseName, CursorFactory factory, int version) 参数1可填MianActivity的实例,如this或MainActivity.this参数2是数据库名称,如果不存在就会调用onCreate()方法参数3指定CursorFactory , 可以为null(使用默认的CursorFactory)参数4是版本号,如果变动就会执行onUpgrade()方法 抽象方法onCreate() 创建数据库时做什么, 可以写入创建表结构的sql语句 没有对应的数据库时才调用(构造函数的参数中的数据库名对应的数据库不存在时才调用)构造获得实例,实例调用getReadableDatabase()或getWritableDatabase()时,发现构造时指定的数据库不存在,就会调用该方法 抽象方法onUpgrade() 升级数据库版本时做什么 构造方法参数的版本号上升时才调用 非抽象,可选onDowngrade()降级数据库版本时做什么构造方法参数的版本号下降时才调用非抽象,可选onOpen()打开数据库时做什么 close() 关闭所有打开的数据库对象 getWritableDatabase() 创建或打开可以读/写的数据库 通过返回的SQLiteDatabase对象对数据库进行操作 getReadableDatabase() 创建或打开可读的数据库 同上 SQLiteDatabase的主要方法 方法名 作用 备注 execSQL() 可进行增删改操作, 不能进行查询操作 query()、rawQuery() 查询数据库 insert() 插入数据 delete() 删除数据 SQLiteOpenHelper的构造方法 SQLiteOpenHelper 的构造方法通常看起来像这样基于 Android SDK 的源代码 public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {// 验证版本号是否有效if (version 1) {throw new IllegalArgumentException(Version must be 1, was version);}// 保存传入的参数mContext context;mName name;mFactory factory;mNewVersion version;mErrorHandler errorHandler; }// 还有一个更简单的构造方法它不接受 DatabaseErrorHandler public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {this(context, name, factory, version, null); }在上面的构造方法中 context 是一个 Context 对象它允许访问应用的资源和类以及调用应用级操作如启动活动、广播和接收意图等。name 是数据库文件的名称。如果不包括路径则数据库文件将被存储在应用的私有文件目录中。factory 是一个用于创建游标对象的 CursorFactory。如果传入 null则使用默认的游标工厂。version 是数据库的版本号。这是一个整数用于跟踪数据库的结构变化。当版本号增加时onUpgrade 方法将被调用。errorHandler 是一个 DatabaseErrorHandler 对象它允许在数据库遇到错误时执行自定义的错误处理逻辑。如果传入 null则使用默认的错误处理器。 在创建 SQLiteOpenHelper 的子类时我们需要调用其中一个构造方法来初始化父类。然后我们可以实现 onCreate、onUpgrade 等方法来定义数据库的结构和升级逻辑。 例如 public class MyDatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME mydatabase.db;private static final int DATABASE_VERSION 1;public MyDatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}Overridepublic void onCreate(SQLiteDatabase db) {// 创建表的 SQL 语句String CREATE_TABLE CREATE TABLE mytable ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT );;db.execSQL(CREATE_TABLE);}Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 版本升级时的逻辑db.execSQL(DROP TABLE IF EXISTS mytable);onCreate(db);} }在这个例子中我们创建了一个名为 MyDatabaseHelper 的类它继承自 SQLiteOpenHelper。我们在构造方法中调用了父类的构造方法并传入了数据库名称、版本号和上下文对象。然后我们实现了 onCreate 和 onUpgrade 方法来定义数据库的结构和升级逻辑。 三、 SQLiteOpenHelper源代码 以下是一个简化的 SQLiteOpenHelper 源代码示例并附有关键部分的解释 package android.database.sqlite;import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.util.Log;public abstract class SQLiteOpenHelper {// 调试标志用于确定是否严格只读private static final boolean DEBUG_STRICT_READONLY false;// 上下文对象用于访问应用的资源和类private final Context mContext;// 数据库文件名private final String mName;// 用于创建游标对象的工厂如果为 null则使用默认工厂private final CursorFactory mFactory;// 数据库版本号private final int mNewVersion;// 数据库错误处理器如果为 null则使用默认处理器private final DatabaseErrorHandler mErrorHandler;// 数据库对象可能为 nullprivate SQLiteDatabase mDatabase;// 标记数据库是否正在初始化private boolean mIsInitializing;// SQLiteOpenHelper 的构造函数public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {if (version 1) throw new IllegalArgumentException(Version must be 1, was version);mContext context;mName name;mFactory factory;mNewVersion version;mErrorHandler errorHandler;}// 简化构造函数不指定错误处理器public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {this(context, name, factory, version, null);}// 创建或打开一个数据库用于读写。如果数据库磁盘空间已满则尝试以只读方式打开public synchronized SQLiteDatabase getWritableDatabase() {// ...实现细节省略}// 创建或打开一个数据库用于读取。如果数据库磁盘空间已满则只能以只读方式打开public synchronized SQLiteDatabase getReadableDatabase() {// ...实现细节省略}// 当数据库第一次创建时调用此方法public abstract void onCreate(SQLiteDatabase db);// 当数据库版本升级时调用此方法public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);// 当数据库版本降级时调用此方法可选实现public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {throw new SQLiteException(Cant downgrade database from version oldVersion to newVersion);}// 当数据库打开时调用此方法可选实现public void onOpen(SQLiteDatabase db) {}// ...其他方法和内部类省略 }关键部分解释 构造函数SQLiteOpenHelper 提供了两个构造函数允许开发者指定数据库名称、版本号、游标工厂和错误处理器。版本号必须大于等于 1。getWritableDatabase()此方法用于创建或打开一个数据库用于读写操作。如果数据库磁盘空间已满则尝试以只读方式打开但会抛出异常。getReadableDatabase()此方法用于创建或打开一个数据库用于读取操作。如果数据库磁盘空间已满则只能以只读方式打开。onCreate(SQLiteDatabase db)这是一个抽象方法当数据库第一次创建时调用。开发者应在此方法中编写创建表和初始化数据的 SQL 语句。onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)这也是一个抽象方法当数据库版本升级时调用。开发者应在此方法中编写升级数据库的 SQL 语句如添加新列、修改表结构等。onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)这是一个可选实现的方法当数据库版本降级时调用。默认情况下此方法会抛出异常因为降级操作通常不被推荐。onOpen(SQLiteDatabase db)这是一个可选实现的方法当数据库打开时调用。开发者可以在此方法中执行一些初始化操作。 请注意上述代码是一个简化的示例并省略了部分实现细节和内部类。在实际开发中SQLiteOpenHelper 的实现可能会更加复杂具体取决于应用的需求和数据库的结构。 用法实例 一个用 匿名内部类实例化SQLiteOpenHelper的Activity package com.example.emptyviewsactivity2410261826;import android.annotation.SuppressLint; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.util.Log; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView;import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatEditText; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat;public class MainActivity extends AppCompatActivity {final String DbName note1, TbName tableA1 , Col0id , Col1content;final int RowQuantity 666;LinearLayout linearLayout null;TableLayout tableLayout null;final TableRow[] TableRows new TableRow[RowQuantity];final TextView[] TvAr new TextView[RowQuantity];final EditText[] EtAr new EditText[RowQuantity]; // final AppCompatEditText EtAr[] new AppCompatEditText[RowQuantity];final Button[] CopyBtnAr new Button[RowQuantity];final Button[] PasteBtnAr new Button[RowQuantity];final Button[] CutBtnAr new Button[RowQuantity];final Button[] DelBtnAr new Button[RowQuantity];SQLiteOpenHelper sqliteOpenHelper;SQLiteDatabase sqliteDatabase;SuppressLint(MissingInflatedId)Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); Log.i(onCreate(),onCreate());EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) - {Insets systemBars insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});/// 上面部分是新建项目自动生成的linearLayout findViewById(R.id.LinearLayoutA1);tableLayout findViewById(R.id.tableLayoutA1);// EditText editText new EditText(this); linearLayout.addView(editText); // // AppCompatEditText appCompatEditText new AppCompatEditText(MainActivity.this); linearLayout.addView(appCompatEditText); // // AutoCompleteTextView autoCompleteTextView new AutoCompleteTextView(this); linearLayout.addView(autoCompleteTextView); // // MultiAutoCompleteTextView multiAutoCompleteTextView new MultiAutoCompleteTextView(MainActivity.this); linearLayout.addView(multiAutoCompleteTextView);/*删除数据库deleteDatabase(DbName)删除数据库, Activity,AppCompatActivity都自带删除Sqlite数据库的方法, 这是实现自最顶层 public abstract class Context 的抽象方法 public abstract boolean deleteDatabase(String name);AppCompatActivity extends FragmentActivity extends ComponentActivity extends androidx.core.app.ComponentActivity extends Activity extends ContextThemeWrapper extends ContextWrapper extends Context*/ // deleteDatabase(DbName);/*通过匿名内部类实现SQLiteOpenHelper, 也可用继承类实现.实例化SQLiteOpenHelper时虽然指定了数据库名称和版本,但还不会创建或打开数据库,直到实例执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时,才会打开 或 创建再打开 数据库*/sqliteOpenHelper new SQLiteOpenHelper(MainActivity.this, DbName, null, 1) {//必须//onCreate(SQLiteDatabase sqLiteDatabase数据库实例)///在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库名称对应的数据库不存在,就会调用该方法,该方法为abstract抽象方法,必须实现.Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {System.out.println(SQLiteOpenHelper 的 onCreate(SQLiteDatabase sqLiteDatabase)被调用 //在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库名称对应的数据库不存在,就会调用该方法,该方法为abstract抽象方法,必须实现);final String CreateTableSql CREATE TABLE TbName ( id INTEGER PRIMARY KEY , content TEXT );sqLiteDatabase.execSQL(CreateTableSql);for(int r0; rRowQuantity; r){ContentValues cvs new ContentValues(2);cvs.put(Col0, r);cvs.put(Col1, );sqLiteDatabase.insert(TbName, null, cvs);}}//必须//onUpgrade(SQLiteDatabase sqLiteDatabase数据库实例, int oldVersion旧版本号, int newVersion新版本号)///在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库版本号升高,就会调用该方法,该方法为abstract抽象方法,必须实现. 在创建数据库时不会调用该方法Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {System.out.println(SQLiteOpenHelper 的 onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion)被调用 //在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库版本号升高,就会调用该方法,该方法为abstract抽象方法,必须实现. 在创建数据库时不会调用该方法);}//非抽象,可选//onDowngrade(SQLiteDatabase sqLiteDatabase数据库实例, int oldVersion旧版本号, int newVersion新版本号)///在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库版本号发生变动,就会调用该方法,该方法非抽象,可选. 在创建数据库时不会调用该方法Overridepublic void onDowngrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {System.out.println(SQLiteOpenHelper 的 onDowngrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion)被调用 //在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 如果数据库版本号降低,就会调用该方法,该方法非抽象,可选. 在创建数据库时不会调用该方法);}//非抽象,可选//onOpen(SQLiteDatabase sqLiteDatabase数据库实例)//在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 被调用Overridepublic void onOpen(SQLiteDatabase sqLiteDatabase) {Log.i(onOpen(SQLiteDatabase sqLiteDatabase),SQLiteOpenHelper 的 onOpen(SQLiteDatabase sqLiteDatabase)被调用 //在执行 getReadableDatabase() 或 getWritableDatabase() 获取数据库时时, 会调用onOpen(SQLiteDatabase db)方法);SuppressLint(Recycle) Cursor cursor sqLiteDatabase.rawQuery(SELECT COUNT(*) FROM TbName, null);cursor.moveToFirst(); if(cursor.getInt(0) ! RowQuantity){ Log.i(库表均已存在,但行数不对应,库表均已存在,但行数不对应, 将 DELETE TABLE FROM table-name 然后重新 INSERT INTO);sqLiteDatabase.delete(TbName,null,null);for(int r0; rRowQuantity; r){sqLiteDatabase.execSQL(INSERT INTO TbName VALUES (?,?) , new Object[]{r,});}}}};sqliteDatabase sqliteOpenHelper.getWritableDatabase();SuppressLint(Recycle) Cursor cursor sqliteDatabase.rawQuery(SELECT * FROM TbName, null);for(int r0; cursor.moveToNext(); r){TableRow row TableRows[r] new TableRow(this); tableLayout.addView(row);TextView tv TvAr[r] new TextView(this); row.addView(tv); tv.setText(cursor.getString(0));EditText et EtAr[r] new EditText(this); row.addView(et); et.setText(cursor.getString(1));Button copyBtn CopyBtnAr[r] new Button(this); row.addView(copyBtn, 100, 100); copyBtn.setText(复);copyBtn.setOnClickListener((view)-{ClipboardManager clipboardManager (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);ClipData clipData ClipData.newPlainText(text, et.getEditableText().toString());clipboardManager.setPrimaryClip(clipData);});Button pBtn PasteBtnAr[r] new Button(this); row.addView(pBtn, 100, 100); pBtn.setText(粘); pBtn.setOnClickListener((view)-{ et.setText(((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)).getPrimaryClip().getItemAt(0).getText()); });Button cutBtn CutBtnAr[r] new Button(this); row.addView(cutBtn, 100, 100); cutBtn.setText(剪); cutBtn.setOnClickListener((view)-{copyBtn.callOnClick(); et.setText();});Button dBtn DelBtnAr[r] new Button(this); row.addView(dBtn, 100, 100); dBtn.setText(删); dBtn.setOnClickListener((view)-{ et.setText(); });}// for(int r0; rRowQuantity; r){ // TableRow row tableRows[r] new TableRow(this); tableLayout.addView(row); // EditText et etAr[r] new EditText(this); row.addView(et); // // }/*测试多次调用 getReadableDatabase() 和 getWritableDatabase() 获取SQLiteDatabase数据库实例多次调用 getReadableDatabase() 和 getWritableDatabase() 返回同一个SQLiteDatabase实例*/SQLiteDatabase dbw , dbr;dbr sqliteOpenHelper.getReadableDatabase();Log.i(dbw.isReadOnly(),dbr.isReadOnly());dbw sqliteOpenHelper.getWritableDatabase();Log.i(dbw.isReadOnly(),dbw.isReadOnly()); // dbr sqliteOpenHelper.getReadableDatabase();System.out.println(dbwdbr 结果 (dbwdbr));Log.i(dbw.isReadOnly(),dbw.isReadOnly());/*删除数据库deleteDatabase(DbName)删除数据库, Activity,AppCompatActivity都自带删除Sqlite数据库的方法, 这是实现自最顶层 public abstract class Context 的抽象方法 public abstract boolean deleteDatabase(String name);AppCompatActivity extends FragmentActivity extends ComponentActivity extends androidx.core.app.ComponentActivity extends Activity extends ContextThemeWrapper extends ContextWrapper extends Context*/ // deleteDatabase(DbName);}void save(){for(int r0; rRowQuantity; r){ContentValues cvs new ContentValues();cvs.put(Col1, EtAr[r].getText().toString());sqliteDatabase.update(TbName, cvs, id?, new String[]{r});}}Overrideprotected void onStart() {super.onStart(); Log.i(onStart(),onStart());}Overrideprotected void onPause() {super.onPause(); Log.i( onPause(), onPause());save();}Overrideprotected void onStop() {super.onStop(); Log.i(onStop(),onStop());save();}Overrideprotected void onRestart() {super.onRestart(); Log.i(onRestart(),onRestart());}Overrideprotected void onPostResume() {super.onPostResume(); Log.i(onPostResume(),onPostResume());}Overrideprotected void onDestroy() {super.onDestroy(); Log.i(onDestroy(),onDestroy());save();}}一些用法收集参考 public class SQLiteHelper extends SQLiteOpenHelper {private SQLiteDatabase sqLiteDatabase;//调用父类 SQLiteOpenHelper 的构造函数public SQLiteHelper(Context context) {//context上下文环境例如一个 Activity数据库名字一个可选的游标工厂通常是 Null一个代表你正在使用的数据库模型版本的整数。super(context, DBUtils.DATABASE_NAME, null, DBUtils.DATABASE_VERSION);sqLiteDatabase this.getWritableDatabase();}//创建数据库 只在没有数据库时执行Overridepublic void onCreate(SQLiteDatabase db) {//execSQL() 方法适用于所有不返回结果的 SQL 语句db.execSQL(CREATE TABLE DBUtils.DATABASE_TABLE ( DBUtils.NOTE_ID INTEGER PRIMARY KEY AUTOINCREMENT, DBUtils.NOTE_CONTENT TEXT, DBUtils.NOTE_TIME TEXT));}//把一个数据库从旧的模型转变到新的模型。//它需要三个参数一个 SQLiteDatabase 对象一个旧的版本号和一个新的版本号Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}//添加数据public boolean insertData(String userContent, String userTime) {//ContentValues 储存数据只能存储基本类型的数据不能存储对象ContentValues values new ContentValues();values.put(DBUtils.NOTE_CONTENT, userContent);values.put(DBUtils.NOTE_TIME, userTime);//插入数据//第一个参数是表的名称//第二个参数为空值字段就是如果第三个参数为空null)的时候就会用到第二个参数的值。用第二个参数代替第三个参数组拼成SQL语句//比如insert into person(name) values(null) 这里的person字段使用了第二个参数的name//第三个参数不为空就不会用到第二个参数return sqLiteDatabase.insert(DBUtils.DATABASE_TABLE, null, values) 0;}//删除数据public boolean deleteData(String id) {String sql DBUtils.NOTE_ID ?;String[] contentValuesArrary new String[]{String.valueOf(id)};//1表名、2字段名、3占位符的数据return sqLiteDatabase.delete(DBUtils.DATABASE_TABLE, sql, contentValuesArrary) 0;}//修改数据public boolean updateData(String id, String content, String userYear) {ContentValues contentValues new ContentValues();contentValues.put(DBUtils.NOTE_CONTENT, content);contentValues.put(DBUtils.NOTE_TIME, userYear);String sql DBUtils.NOTE_ID ?;String[] strings new String[]{id};//1表名、2需要更新值、3以什么条件字段更新、4条件字段的数据值(占位符的值)return sqLiteDatabase.update(DBUtils.DATABASE_TABLE, contentValues, sql, strings) 0;}//查询数据public ListNotepadBean qurry() {ListNotepadBean list new ArrayListNotepadBean();//1 表名、 2 需要查询的字段列表,用字符串数组形式传入null为所有的字段、 3 以什么条件字段查询、 4 条件字段的数据值(占位符的值)、// 5 groupBy相当于select语句的groupby后面的部分、 6 having相当于select语句的having后面的部分、 7 order是我们想要的排序方式。Cursor cursor sqLiteDatabase.query(DBUtils.DATABASE_TABLE, null, null, null,null, null, DBUtils.NOTE_ID desc);if (cursor ! null) {while (cursor.moveToNext()) {NotepadBean noteInfo new NotepadBean();String id String.valueOf(cursor.getInt(cursor.getColumnIndex(DBUtils.NOTE_ID)));String content cursor.getString(cursor.getColumnIndex(DBUtils.NOTE_CONTENT));String time cursor.getString(cursor.getColumnIndex(DBUtils.NOTE_TIME));noteInfo.setId(id);noteInfo.setNotepadContent(content);noteInfo.setNotepadTime(time);list.add(noteInfo);}cursor.close();}return list;} } package com.example.dbproject; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast; public class DbContect extends SQLiteOpenHelper {private static final int VERSION1;private static final String DBNAMEUsers.db; // 创建数据库名叫 Usersprivate Context mContext;public DbContect(Context context){super(context,DBNAME,null,VERSION);mContext context;}//创建数据库 只在没有数据库时执行public void onCreate(SQLiteDatabase db){//创建密码表 pwd_tbdb.execSQL(create table pwd_tb (pwd varchar(20) primary key));//创建收入表 user_tbdb.execSQL(create table user_tb(_id integer primary key autoincrement, money decimal, time varchar(10),type varchar(10),handler varchar(100),mark varchar(200)));}//数据库版本更新时执行public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){db.execSQL(drop table if exists pwd_tb);db.execSQL(drop table if exists user_tb);onCreate(db);}} SQLiteOpenHelper是Android开发中用于管理SQLite数据库的一个非常重要的工具类。以下是对SQLiteOpenHelper的详细介绍 一、基本概念 SQLiteOpenHelper是一个抽象类它主要用于管理数据库的创建和版本管理。通过继承这个类开发者可以重写一些方法以实现数据库的创建、升级和降级等功能。 二、主要方法 构造方法用于创建SQLiteOpenHelper对象需要传入数据库名称、版本号和一个可选的CursorFactory对象。onCreate(SQLiteDatabase db)在数据库第一次创建时调用用于执行创建表和初始化数据等操作。onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)在数据库版本升级时调用用于执行表结构的修改、数据迁移等操作。onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)在数据库版本降级时调用但这个方法不是必须的因为在实际开发中降级操作并不常见。getReadableDatabase()获取一个可读的数据库对象。如果数据库不存在则会先调用onCreate()方法创建数据库。getWritableDatabase()获取一个可写的数据库对象。如果数据库不存在也会先调用onCreate()方法创建数据库。 三、使用示例 以下是一个使用SQLiteOpenHelper创建数据库、表以及进行增删改查操作的简单示例 创建数据库帮助类 public class MyDatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME mydatabase.db;private static final int DATABASE_VERSION 1;public MyDatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}Overridepublic void onCreate(SQLiteDatabase db) {String createTable CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);db.execSQL(createTable);}Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL(DROP TABLE IF EXISTS users);onCreate(db);} }使用数据库帮助类进行增删改查操作 MyDatabaseHelper dbHelper new MyDatabaseHelper(context); SQLiteDatabase db dbHelper.getWritableDatabase();// 插入数据 ContentValues values new ContentValues(); values.put(name, John Doe); long id db.insert(users, null, values);// 查询数据 Cursor cursor db.query(users, null, null, null, null, null, null); while (cursor.moveToNext()) {int userId cursor.getInt(cursor.getColumnIndex(id));String userName cursor.getString(cursor.getColumnIndex(name));// 处理查询到的数据 } cursor.close();// 更新数据 ContentValues updateValues new ContentValues(); updateValues.put(name, Jane Smith); db.update(users, updateValues, id?, new String[]{String.valueOf(id)});// 删除数据 db.delete(users, id?, new String[]{String.valueOf(id)});// 关闭数据库 db.close();四、注意事项 数据库版本管理在开发过程中随着应用程序的更新数据库结构可能会发生变化。因此合理使用onUpgrade()方法来进行数据库结构的升级是非常重要的。异常处理在进行数据库操作时可能会遇到各种异常情况如SQL语法错误、数据库文件损坏等。因此在实际开发中应该添加适当的异常处理代码来确保程序的健壮性。性能优化对于大规模的数据库操作如批量插入、更新或删除数据应该考虑使用事务Transaction来提高性能并减少数据库锁定的时间。 综上所述SQLiteOpenHelper是Android开发中管理SQLite数据库的重要工具类。通过合理使用该类开发者可以实现高效的数据管理从而提升应用程序的性能和用户体验。 如何使用SQLiteOpenHelper SQLiteOpenHelper 是 Android 平台上用于管理 SQLite 数据库的一个辅助类。它简化了数据库的创建和版本管理。以下是使用 SQLiteOpenHelper 的基本步骤 1. 创建一个继承自 SQLiteOpenHelper 的类 首先你需要创建一个类这个类继承自 SQLiteOpenHelper 并实现其两个抽象方法onCreate(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)。 import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;public class MyDatabaseHelper extends SQLiteOpenHelper {// 数据库名称private static final String DATABASE_NAME my_database.db;// 数据库版本private static final int DATABASE_VERSION 1;// 创建一个表private static final String TABLE_CREATE CREATE TABLE my_table ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL);;public MyDatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(TABLE_CREATE);}Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 如果表已经存在删除表db.execSQL(DROP TABLE IF EXISTS my_table);// 重新创建表onCreate(db);} }2. 在你的 Activity 或其他组件中使用 SQLiteOpenHelper 在你的 Activity 或其他组件中你可以通过实例化 MyDatabaseHelper 类来获取 SQLiteDatabase 对象然后执行 CRUD创建、读取、更新、删除操作。 import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.widget.Toast;public class MainActivity extends AppCompatActivity {private MyDatabaseHelper dbHelper;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dbHelper new MyDatabaseHelper(this);// 插入数据insertData();// 查询数据queryData();}private void insertData() {SQLiteDatabase db dbHelper.getWritableDatabase();ContentValues values new ContentValues();values.put(name, Alice);values.put(age, 30);long newRowId db.insert(my_table, null, values);Toast.makeText(this, Inserted Row ID: newRowId, Toast.LENGTH_SHORT).show();}private void queryData() {SQLiteDatabase db dbHelper.getReadableDatabase();String[] projection {id,name,age};Cursor cursor db.query(my_table, // 表名projection, // 要返回的列null, // WHERE 子句的选择条件null, // WHERE 子句的选择参数null, // GROUP BY 子句null, // HAVING 子句null // ORDER BY 子句);while (cursor.moveToNext()) {int id cursor.getInt(cursor.getColumnIndexOrThrow(id));String name cursor.getString(cursor.getColumnIndexOrThrow(name));int age cursor.getInt(cursor.getColumnIndexOrThrow(age));// 处理查询结果Toast.makeText(this, ID: id , Name: name , Age: age, Toast.LENGTH_SHORT).show();}cursor.close();} }3. 注意事项 线程安全SQLite 数据库不是线程安全的因此你应该确保所有的数据库操作都在一个单独的线程中执行或者使用 AsyncTask 或其他异步方法。关闭游标每次使用完 Cursor 后都应该调用 cursor.close() 方法来释放资源。错误处理在实际应用中你应该添加适当的错误处理逻辑比如捕获 SQLException。 通过以上步骤你就可以在 Android 应用中使用 SQLiteOpenHelper 来管理 SQLite 数据库了。 Android API34 的 SQLiteOpenHelper 的源码 /** Copyright (C) 2007 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package android.database.sqlite;import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.os.FileUtils; import android.util.Log;import java.io.File; import java.util.Objects;/*** A helper class to manage database creation and version management.** pYou create a subclass implementing {link #onCreate}, {link #onUpgrade} and* optionally {link #onOpen}, and this class takes care of opening the database* if it exists, creating it if it does not, and upgrading it as necessary.* Transactions are used to make sure the database is always in a sensible state.** pThis class makes it easy for {link android.content.ContentProvider}* implementations to defer opening and upgrading the database until first use,* to avoid blocking application startup with long-running database upgrades.** pFor an example, see the NotePadProvider class in the NotePad sample application,* in the emsamples//em directory of the SDK./p** p classnotestrongNote:/strong this class assumes* monotonically increasing version numbers for upgrades./p** p classnotestrongNote:/strong the {link AutoCloseable} interface was* first added in the {link android.os.Build.VERSION_CODES#Q} release./p*/ public abstract class SQLiteOpenHelper implements AutoCloseable {private static final String TAG SQLiteOpenHelper.class.getSimpleName();private final Context mContext;UnsupportedAppUsageprivate final String mName;private final int mNewVersion;private final int mMinimumSupportedVersion;private SQLiteDatabase mDatabase;private boolean mIsInitializing;private SQLiteDatabase.OpenParams.Builder mOpenParamsBuilder;/*** Create a helper object to create, open, and/or manage a database.* This method always returns very quickly. The database is not actually* created or opened until one of {link #getWritableDatabase} or* {link #getReadableDatabase} is called.** param context to use for locating paths to the the database* param name of the database file, or null for an in-memory database* param factory to use for creating cursor objects, or null for the default* param version number of the database (starting at 1); if the database is older,* {link #onUpgrade} will be used to upgrade the database; if the database is* newer, {link #onDowngrade} will be used to downgrade the database*/public SQLiteOpenHelper(Nullable Context context, Nullable String name,Nullable CursorFactory factory, int version) {this(context, name, factory, version, null);}/*** Create a helper object to create, open, and/or manage a database.* The database is not actually created or opened until one of* {link #getWritableDatabase} or {link #getReadableDatabase} is called.** pAccepts input param: a concrete instance of {link DatabaseErrorHandler} to be* used to handle corruption when sqlite reports database corruption./p** param context to use for locating paths to the the database* param name of the database file, or null for an in-memory database* param factory to use for creating cursor objects, or null for the default* param version number of the database (starting at 1); if the database is older,* {link #onUpgrade} will be used to upgrade the database; if the database is* newer, {link #onDowngrade} will be used to downgrade the database* param errorHandler the {link DatabaseErrorHandler} to be used when sqlite reports database* corruption, or null to use the default error handler.*/public SQLiteOpenHelper(Nullable Context context, Nullable String name,Nullable CursorFactory factory, int version,Nullable DatabaseErrorHandler errorHandler) {this(context, name, factory, version, 0, errorHandler);}/*** Create a helper object to create, open, and/or manage a database.* This method always returns very quickly. The database is not actually* created or opened until one of {link #getWritableDatabase} or* {link #getReadableDatabase} is called.** param context to use for locating paths to the the database* param name of the database file, or null for an in-memory database* param version number of the database (starting at 1); if the database is older,* {link #onUpgrade} will be used to upgrade the database; if the database is* newer, {link #onDowngrade} will be used to downgrade the database* param openParams configuration parameters that are used for opening {link SQLiteDatabase}.* Please note that {link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be* set when the helper opens the database*/public SQLiteOpenHelper(Nullable Context context, Nullable String name, int version,NonNull SQLiteDatabase.OpenParams openParams) {this(context, name, version, 0, openParams.toBuilder());}/*** Same as {link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)}* but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old* versions of this database that are no longer supported. If a database with older version that* minimumSupportedVersion is found, it is simply deleted and a new database is created with the* given name and version** param context to use for locating paths to the the database* param name the name of the database file, null for a temporary in-memory database* param factory to use for creating cursor objects, null for default* param version the required version of the database* param minimumSupportedVersion the minimum version that is supported to be upgraded to* {code version} via {link #onUpgrade}. If the current database version is lower* than this, database is simply deleted and recreated with the version passed in* {code version}. {link #onBeforeDelete} is called before deleting the database* when this happens. This is 0 by default.* param errorHandler the {link DatabaseErrorHandler} to be used when sqlite reports database* corruption, or null to use the default error handler.* see #onBeforeDelete(SQLiteDatabase)* see #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)* see #onUpgrade(SQLiteDatabase, int, int)* hide*/public SQLiteOpenHelper(Nullable Context context, Nullable String name,Nullable CursorFactory factory, int version,int minimumSupportedVersion, Nullable DatabaseErrorHandler errorHandler) {this(context, name, version, minimumSupportedVersion,new SQLiteDatabase.OpenParams.Builder());mOpenParamsBuilder.setCursorFactory(factory);mOpenParamsBuilder.setErrorHandler(errorHandler);}private SQLiteOpenHelper(Nullable Context context, Nullable String name, int version,int minimumSupportedVersion,NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {Objects.requireNonNull(openParamsBuilder);if (version 1) throw new IllegalArgumentException(Version must be 1, was version);mContext context;mName name;mNewVersion version;mMinimumSupportedVersion Math.max(0, minimumSupportedVersion);setOpenParamsBuilder(openParamsBuilder);}/*** Return the name of the SQLite database being opened, as given to* the constructor.*/public String getDatabaseName() {return mName;}/*** Enables or disables the use of write-ahead logging for the database.** Write-ahead logging cannot be used with read-only databases so the value of* this flag is ignored if the database is opened read-only.** param enabled True if write-ahead logging should be enabled, false if it* should be disabled.** see SQLiteDatabase#enableWriteAheadLogging()*/public void setWriteAheadLoggingEnabled(boolean enabled) {synchronized (this) {if (mOpenParamsBuilder.isWriteAheadLoggingEnabled() ! enabled) {if (mDatabase ! null mDatabase.isOpen() !mDatabase.isReadOnly()) {if (enabled) {mDatabase.enableWriteAheadLogging();} else {mDatabase.disableWriteAheadLogging();}}mOpenParamsBuilder.setWriteAheadLoggingEnabled(enabled);}// Compatibility WAL is disabled if an app disables or enables WALmOpenParamsBuilder.removeOpenFlags(SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL);}}/*** Configures a hrefhttps://sqlite.org/malloc.html#lookasidelookaside memory allocator/a** pThis method should be called from the constructor of the subclass,* before opening the database, since lookaside memory configuration can only be changed* when no connection is using it** pSQLite default settings will be used, if this method isnt called.* Use {code setLookasideConfig(0,0)} to disable lookaside** pstrongNote:/strong Provided slotSize/slotCount configuration is just a recommendation.* The system may choose different values depending on a device, e.g. lookaside allocations* can be disabled on low-RAM devices** param slotSize The size in bytes of each lookaside slot.* param slotCount The total number of lookaside memory slots per database connection.*/public void setLookasideConfig(IntRange(from 0) final int slotSize,IntRange(from 0) final int slotCount) {synchronized (this) {if (mDatabase ! null mDatabase.isOpen()) {throw new IllegalStateException(Lookaside memory config cannot be changed after opening the database);}mOpenParamsBuilder.setLookasideConfig(slotSize, slotCount);}}/*** Sets configuration parameters that are used for opening {link SQLiteDatabase}.* pPlease note that {link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be set when* opening the database** param openParams configuration parameters that are used for opening {link SQLiteDatabase}.* throws IllegalStateException if the database is already open*/public void setOpenParams(NonNull SQLiteDatabase.OpenParams openParams) {Objects.requireNonNull(openParams);synchronized (this) {if (mDatabase ! null mDatabase.isOpen()) {throw new IllegalStateException(OpenParams cannot be set after opening the database);}setOpenParamsBuilder(new SQLiteDatabase.OpenParams.Builder(openParams));}}private void setOpenParamsBuilder(SQLiteDatabase.OpenParams.Builder openParamsBuilder) {mOpenParamsBuilder openParamsBuilder;mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY);}/*** Sets the maximum number of milliseconds that SQLite connection is allowed to be idle* before it is closed and removed from the pool.** pThis method should be called from the constructor of the subclass,* before opening the database** pbDO NOT USE/b this method.* This feature has negative side effects that are very hard to foresee.* See the javadoc of* {link SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)}* for the details.** param idleConnectionTimeoutMs timeout in milliseconds. Use {link Long#MAX_VALUE} value* to allow unlimited idle connections.** see SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)** deprecated DO NOT USE this method. See the javadoc of* {link SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)}* for the details.*/Deprecatedpublic void setIdleConnectionTimeout(IntRange(from 0) final long idleConnectionTimeoutMs) {synchronized (this) {if (mDatabase ! null mDatabase.isOpen()) {throw new IllegalStateException(Connection timeout setting cannot be changed after opening the database);}mOpenParamsBuilder.setIdleConnectionTimeout(idleConnectionTimeoutMs);}}/*** Create and/or open a database that will be used for reading and writing.* The first time this is called, the database will be opened and* {link #onCreate}, {link #onUpgrade} and/or {link #onOpen} will be* called.** pOnce opened successfully, the database is cached, so you can* call this method every time you need to write to the database.* (Make sure to call {link #close} when you no longer need the database.)* Errors such as bad permissions or a full disk may cause this method* to fail, but future attempts may succeed if the problem is fixed./p** p classcautionDatabase upgrade may take a long time, you* should not call this method from the application main thread, including* from {link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.** throws SQLiteException if the database cannot be opened for writing* return a read/write database object valid until {link #close} is called*/public SQLiteDatabase getWritableDatabase() {synchronized (this) {return getDatabaseLocked(true);}}/*** Create and/or open a database. This will be the same object returned by* {link #getWritableDatabase} unless some problem, such as a full disk,* requires the database to be opened read-only. In that case, a read-only* database object will be returned. If the problem is fixed, a future call* to {link #getWritableDatabase} may succeed, in which case the read-only* database object will be closed and the read/write object will be returned* in the future.** p classcautionLike {link #getWritableDatabase}, this method may* take a long time to return, so you should not call it from the* application main thread, including from* {link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.** throws SQLiteException if the database cannot be opened* return a database object valid until {link #getWritableDatabase}* or {link #close} is called.*/public SQLiteDatabase getReadableDatabase() {synchronized (this) {return getDatabaseLocked(false);}}private SQLiteDatabase getDatabaseLocked(boolean writable) {if (mDatabase ! null) {if (!mDatabase.isOpen()) {// Darn! The user closed the database by calling mDatabase.close().mDatabase null;} else if (!writable || !mDatabase.isReadOnly()) {// The database is already open for business.return mDatabase;}}if (mIsInitializing) {throw new IllegalStateException(getDatabase called recursively);}SQLiteDatabase db mDatabase;try {mIsInitializing true;if (db ! null) {if (writable db.isReadOnly()) {db.reopenReadWrite();}} else if (mName null) {db SQLiteDatabase.createInMemory(mOpenParamsBuilder.build());} else {final File filePath mContext.getDatabasePath(mName);SQLiteDatabase.OpenParams params mOpenParamsBuilder.build();try {db SQLiteDatabase.openDatabase(filePath, params);// Keep pre-O-MR1 behavior by resetting file permissions to 660setFilePermissionsForDb(filePath.getPath());} catch (SQLException ex) {if (writable) {throw ex;}Log.e(TAG, Couldnt open mName for writing (will try read-only):, ex);params params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();db SQLiteDatabase.openDatabase(filePath, params);}}onConfigure(db);final int version db.getVersion();if (version ! mNewVersion) {if (db.isReadOnly()) {throw new SQLiteException(Cant upgrade read-only database from version db.getVersion() to mNewVersion : mName);}if (version 0 version mMinimumSupportedVersion) {File databaseFile new File(db.getPath());onBeforeDelete(db);db.close();if (SQLiteDatabase.deleteDatabase(databaseFile)) {mIsInitializing false;return getDatabaseLocked(writable);} else {throw new IllegalStateException(Unable to delete obsolete database mName with version version);}} else {db.beginTransaction();try {if (version 0) {onCreate(db);} else {if (version mNewVersion) {onDowngrade(db, version, mNewVersion);} else {onUpgrade(db, version, mNewVersion);}}db.setVersion(mNewVersion);db.setTransactionSuccessful();} finally {db.endTransaction();}}}onOpen(db);if (db.isReadOnly()) {Log.w(TAG, Opened mName in read-only mode);}mDatabase db;return db;} finally {mIsInitializing false;if (db ! null db ! mDatabase) {db.close();}}}private static void setFilePermissionsForDb(String dbPath) {int perms FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP;FileUtils.setPermissions(dbPath, perms, -1, -1);}/*** Close any open database object.*/public synchronized void close() {if (mIsInitializing) throw new IllegalStateException(Closed during initialization);if (mDatabase ! null mDatabase.isOpen()) {mDatabase.close();mDatabase null;}}/*** Called when the database connection is being configured, to enable features such as* write-ahead logging or foreign key support.* p* This method is called before {link #onCreate}, {link #onUpgrade}, {link #onDowngrade}, or* {link #onOpen} are called. It should not modify the database except to configure the* database connection as required.* /p* p* This method should only call methods that configure the parameters of the database* connection, such as {link SQLiteDatabase#enableWriteAheadLogging}* {link SQLiteDatabase#setForeignKeyConstraintsEnabled}, {link SQLiteDatabase#setLocale},* {link SQLiteDatabase#setMaximumSize}, or executing PRAGMA statements.* /p** param db The database.*/public void onConfigure(SQLiteDatabase db) {}/*** Called before the database is deleted when the version returned by* {link SQLiteDatabase#getVersion()} is lower than the minimum supported version passed (if at* all) while creating this helper. After the database is deleted, a fresh database with the* given version is created. This will be followed by {link #onConfigure(SQLiteDatabase)} and* {link #onCreate(SQLiteDatabase)} being called with a new SQLiteDatabase object** param db the database opened with this helper* see #SQLiteOpenHelper(Context, String, CursorFactory, int, int, DatabaseErrorHandler)* hide*/public void onBeforeDelete(SQLiteDatabase db) {}/*** Called when the database is created for the first time. This is where the* creation of tables and the initial population of the tables should happen.** param db The database.*/public abstract void onCreate(SQLiteDatabase db);/*** Called when the database needs to be upgraded. The implementation* should use this method to drop tables, add tables, or do anything else it* needs to upgrade to the new schema version.** p* The SQLite ALTER TABLE documentation can be found* a hrefhttp://sqlite.org/lang_altertable.htmlhere/a. If you add new columns* you can use ALTER TABLE to insert them into a live table. If you rename or remove columns* you can use ALTER TABLE to rename the old table, then create the new table and then* populate the new table with the contents of the old table.* /pp* This method executes within a transaction. If an exception is thrown, all changes* will automatically be rolled back.* /p* p* emImportant:/em You should NOT modify an existing migration step from version X to X1* once a build has been released containing that migration step. If a migration step has an* error and it runs on a device, the step will NOT re-run itself in the future if a fix is made* to the migration step./p* pFor example, suppose a migration step renames a database column from {code foo} to* {code bar} when the name should have been {code baz}. If that migration step is released* in a build and runs on a users device, the column will be renamed to {code bar}. If the* developer subsequently edits this same migration step to change the name to {code baz} as* intended, the user devices which have already run this step will still have the name* {code bar}. Instead, a NEW migration step should be created to correct the error and rename* {code bar} to {code baz}, ensuring the error is corrected on devices which have already run* the migration step with the error./p** param db The database.* param oldVersion The old database version.* param newVersion The new database version.*/public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);/*** Called when the database needs to be downgraded. This is strictly similar to* {link #onUpgrade} method, but is called whenever current version is newer than requested one.* However, this method is not abstract, so it is not mandatory for a customer to* implement it. If not overridden, default implementation will reject downgrade and* throws SQLiteException** p* This method executes within a transaction. If an exception is thrown, all changes* will automatically be rolled back.* /p** param db The database.* param oldVersion The old database version.* param newVersion The new database version.*/public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {throw new SQLiteException(Cant downgrade database from version oldVersion to newVersion);}/*** Called when the database has been opened. The implementation* should check {link SQLiteDatabase#isReadOnly} before updating the* database.* p* This method is called after the database connection has been configured* and after the database schema has been created, upgraded or downgraded as necessary.* If the database connection must be configured in some way before the schema* is created, upgraded, or downgraded, do it in {link #onConfigure} instead.* /p** param db The database.*/public void onOpen(SQLiteDatabase db) {} }
http://www.tj-hxxt.cn/news/132290.html

相关文章:

  • 重庆网站建设子沃科技熊掌号牟平网站建设
  • 织梦 xml网站地图自己网站开发
  • 国外手机网站设计成都旅游公司排名前十
  • 上海网站建设网络推广wordpress 描文本优化
  • 宁波网站推广宣传公司排名林西网站建设优化
  • 哪个网站是自己销售网站seo设置
  • 公司形象墙设计方案黄骅做网站|黄骅网站|黄骅百度优化|黄骅百度推广|黄骅微信|黄骅
  • 珲春市建设局网站是多少怎么做表格
  • 网站建设背景怎么设置成私人网官网
  • wordpress建站上海金昌百度seo
  • dede网站后台模板网站搭建与生成技术教材
  • 凡科快速建站wordpress 图片加水印
  • 长沙网站制作哪家强网站怎么做的精致一点
  • 做一个二手网站怎么做怎样建立自己网站视频网站
  • 高安建站公司互联网电商
  • 做婚姻介绍网站赚钱吗手机本地建WordPress
  • 免费做字体的网站好广州市医院网站建设
  • 济南公司注册网站设计师网络接单
  • 南昌网站建设公司网站建设公司app线上推广方式
  • 网上做网站网站潍坊 网站推广
  • 做印刷的有什么网站如何在百度网站收录提交入口
  • 学做网站视频论坛娱乐城网站开发
  • 赣州市铁路建设办公室网站网站备案麻烦么
  • 网站开发需求分析与功能设计网站备案密码格式
  • 网站做gzip压缩seo技术培训唐山
  • 网站建设买服务器还是数据库商务网站开发的基本原则
  • 做进出口外贸网站黄金行情软件下载
  • 网站服务器端口设置重庆建筑工程特种作业信息网
  • 解析网站接口怎么做专门教ps的网站
  • 做sns网站需要什么做游戏视频网站有哪些