SQLite只是一个轻量级数据库,不像mysql、oracle等数据库只是一个嵌入式数据引擎。
用于资源有限的移动设备。
不需要启动服务器进程,不要安装
使用语法:SQL92语法
有点像Access数据库打开它就像打开一个文件进行读写操作(但比Access强大的多)
Q:当遇到高并发、大量数据读写怎么办?
A:不办!!!sqlite压根就使该用于移动便捷设备,而这种设备的计算能力储存能力,都导致它不应该被作为服务器使用!!
SQLiteDatabase
android提供SQLiteDatabase代表数据库
SQLiteDatabase等同于JDBC中Connection和Statement的结合体。SQLiteDatabase既代表与数据库的连接,又只能用于执行sql语句操作
SQLiteDatabase语句
以下只是一部分常用方法
创建、打开数据库
openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags)
打开file文件所代表的数据库openOrCreateDatabase(File file, CursorFactory factory)
打开或创建,file文件所代表的数据库openOrCreateDatabase(String path, CursorFactory factory)
打开或创建,path文件所代表的数据库
调用方法
在程序中获取SQLiteDatabase之后调用以下方法
- execSQL(String sql);
执行sql语句 - execSQL(String sql, Object[] bindArgs)
执行带占位符的SQL语句
flags代表的是创建表时的一些权限设置,多个权限之间用|分隔:
OPEN_READONLY :代表的是以只读方式打开数据库(常量值为:1)
OPEN_READWRITE:代表以读写方式打开数据库(常量值为:0)
CREATE_IF_NECESSARY:当数据库不存在时创建数据库
NO_LOCALIZED_COLLATORS:打开数据库时,不根据本地化语言对数据库进行排序(常量值为:16)
path代表着数据库的路径(如果是在默认路径/data/data/<package_name>/databases/下,则这里只需要提供数据库名称);
factory代表着在创建Cursor对象时,使用的工厂类,如果为null的话,则使用默认的工厂(这里我们可以实现自己的工厂进行某些数据处理);
以下不常用方法可以跳过
用来提供给对sql语句不熟悉得开发者使用这里就不做果多解释了(都可以用sql语句实现)
insert
updata
delete
query
移动查询结果的记录指针
以上方法的返回值都是Cursor类型的,试用下图中的方法还可以移动记录指针
创建数据库和表
SQLiteDatabase.openDatabase("XXX/XXX/hrk.db",null);
打开或创建(如果没有)XXX/XXX/目录下的hrk.db数据库用默认工厂
String sql = "CREATE TABLE user(" +
"user_id integer primary key," +
"user_name varchar(255)" +
")";
db.execSQL(sql);
创建数据表使用execSQL方法执行
SQLiteOpenHelper
其实在实际项目中很少使用openOrCreateDatabase去打开数据库,通畅情况下使用继承了SQLiteOpenHelper的子类,并通过该子类的getReadableDatabase和getWritableDatabase两个方法来打开数据库
我们先写一个子类
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version, @Nullable DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
我们发现我们必须重写他的onCreate和onUpgrade方法,还要给出他的构造函数
- onCreate
第一次创建时回调该方法 - onUpgrade
当数据库坂本更新时调用该方法 - MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler)
context:用来打开或创建数据库
name:数据库文件名,对一个在内存中的数据库而言是null
factory:用来创建对象工厂,一般给null
version:数据库的版本号(从1开始);如果数据库是旧的,onUpgrade(SQLiteDataBase,int,int)会被调用去升级数据库;如果数据库是新的,onDowngrade(SQLiteDatabase,int,int)会被调用去降级数据库。 - close
关闭数据库
那么现在我们写个示例(单词本)
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private MySQLiteOpenHelper mySQLiteOpenHelper;
private TextView tv1;
private EditText et1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn1).setOnClickListener(this);
findViewById(R.id.btn2).setOnClickListener(this);
tv1 = findViewById(R.id.tv1);
et1 = findViewById(R.id.et1);
mySQLiteOpenHelper = new MySQLiteOpenHelper(this, this.getFilesDir().toString() + "myword.db3", 1);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
btn1_onClick();
break;
case R.id.btn2:
btn2_onClick();
break;
}
}
private void btn1_onClick() {
String english = et1.getText().toString();
Cursor cursor = mySQLiteOpenHelper.getReadableDatabase().rawQuery("SELECT Chinese FROM myword WHERE English=?;", new String[]{english});
if(cursor.moveToFirst()) {
tv1.setText(cursor.getString(0));
}else{
tv1.setText("没有!");
}
}
private void btn2_onClick() {
startActivity(new Intent(this,AddActivity.class));
}
@Override
protected void onDestroy() {
mySQLiteOpenHelper.close();
super.onDestroy();
}
}
MySQLiteOpenHelper
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
private static final String TAG = "mysql";
public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version) {
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE myword(" +
"id integer primary key AUTOINCREMENT," +
"English NOT NULL," +
"Chinese NOT NULL" +
")";
db.execSQL(sql);
Log.i(TAG, "onCreate 启动了");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "onUpgrade 启动了"+oldVersion+"-->"+newVersion);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="单词本"
android:textSize="99dp"/>
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入查询的单词"/>
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""/>
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询"/>
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加新单词"/>
</LinearLayout>
AddActivity
public class AddActivity extends AppCompatActivity {
private EditText et1;
private EditText et2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
}
public void onClick(View view) {
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, this.getFilesDir().toString() + "myword.db3", 1);
mySQLiteOpenHelper.getReadableDatabase().execSQL("INSERT INTO myword VALUES(NULL,?,?)",new String[]{String.valueOf(et1.getText()),String.valueOf(et2.getText())});
finish();
}
}
activity_add.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="English"/>
<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Chinese"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加"
android:onClick="onClick"/>
</LinearLayout>
通过以上代码的运行,我们可以看到整个程序无论退出还是打开别的Activity,或是再次访问数据库,我们在logcat上面也只看到了一次『onCreate 启动了』
Log.i(TAG, "onCreate 启动了");
而onUpgrade却迟迟没有运行那他是干什么的呢?
我们卸载重新安装程序依旧没有发现他的身影,
不卸载重装也没有。
答案揭晓
当我们想数据库中保存数据后我们改变
mySQLiteOpenHelper = new MySQLiteOpenHelper(this, this.getFilesDir().toString() + "myword.db3", 1);
末位的1版本号改为2,不卸载原有程序的情况下,覆盖重新安装我可以看到onUpgrade方法调用了而且之前安装时我们的保存进数据库的内容也保存了下来!