Sqlite
Google 官方建议建议将 Room 持久性库用作抽象层以访问应用的 SQLite 数据库中的信息。Android为了让我们能够更加方便地管理数据库,专门提供了一个SQLiteOpenHelper帮助
类,借助这个类可以非常简单地对数据库进行创建和升级。既然有好东西可以直接使用,那我们自然要尝试一下了,下面我就对SQLiteOpenHelper的基本用法进行介绍。
首先,你要知道SQLiteOpenHelper是一个抽象类,这意味着如果我们想要使用它,就需要创建一个自己的帮助类去继承它。SQLiteOpenHelper中有两个抽象方法:onCreate()和
onUpgrade()。我们必须在自己的帮助类里重写这两个方法,然后分别在这两个方法中实现创建和升级数据库的逻辑。SQLiteOpenHelper中还有两个非常重要的实例方法:getReadableDatabase()和
getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则要创建一个新的数据库),并返回一个可对数据库进行读写操作的对
象。不同的是,当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase()方法返回的对象将以只读的方式打开数据库,而getWritableDatabase()方法则将出现异常。
一个例子:
public class MySqliteHelper extends SQLiteOpenHelper {
public static String db_name = "my_sqlite";
public static int version = 2;
public MySqliteHelper(@Nullable Context context, @Nullable String name, int version) {
super(context, name, null, version);
this.db_name = name;
this.version = version;
}
//只会在安装应用后 数据库未建立的时候执行一次
@Override
public void onCreate(SQLiteDatabase db) {
ILog.LogDebug("create database");
createTables(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
ILog.LogDebug("Database upgrade");
if(oldVersion <= 2){
createStudentTable(db);
}
}
private void createTables(SQLiteDatabase database){
String sql = "create table book (" +
"id integer primary key autoincrement," +
"author text," +
"price real," +
"pages integer," +
"name text)";
database.execSQL(sql);
}
private void createStudentTable(SQLiteDatabase database){
String sql = "create table student (" +
"id integer primary key autoincrement," +
"age integer," +
"name text)";
database.execSQL(sql);
}
@SuppressLint("Range")
public String query(SQLiteDatabase database){
StringBuilder stringBuilder = new StringBuilder("book:");
Cursor cursor = database.query("book",null,null,null,null,null,null);
if(cursor.moveToFirst()){
do{
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
stringBuilder.append(name).append(",").append(author).append(",").append(price).append(",").append(pages);
}while (cursor.moveToNext());
}
cursor.close();
return stringBuilder.toString();
}
public void insert(SQLiteDatabase database){
ContentValues contentValues = new ContentValues();
contentValues.put("author","liuhanze");
contentValues.put("price",88.88);
contentValues.put("pages",80);
contentValues.put("name","Java");
database.insert("book",null,contentValues);
}
public void update(SQLiteDatabase database){
ContentValues contentValues = new ContentValues();
contentValues.put("price",100);
database.update("book",contentValues,"name=?", new String[]{"Java"});
}
public void delete(SQLiteDatabase database){
ContentValues contentValues = new ContentValues();
contentValues.put("price",100);
database.delete("book","name=?",new String[]{"Java"});
}
//事务处理
public void beginTransaction(SQLiteDatabase database){
database.beginTransaction();
try {
delete(database);
//这里可能出现异常
insert(database);
database.setTransactionSuccessful();
}catch (Exception e){
e.printStackTrace();
}finally {
database.endTransaction();
}
}
}
public class TestSqliteActivity extends AppCompatActivity {
private ActivitySqliteBinding binding;
private MySqliteHelper sqliteHelper;
private SQLiteDatabase database;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySqliteBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
initView();
}
private void initView(){
//由于可能会长时间运行,因此请务必在后台线程中调用 getWritableDatabase() 或 getReadableDatabase()
//getReadableDatabase()和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已
//存在则直接打开,否则要创建一个新的数据库),并返回一个可对数据库进行读写操作的对
//象。不同的是,当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase()方
//法返回的对象将以只读的方式打开数据库,而getWritableDatabase()方法则将出现异常。
new Thread(() -> {
sqliteHelper = new MySqliteHelper(this,MySqliteHelper.db_name,MySqliteHelper.version);
database = sqliteHelper.getReadableDatabase();
}).start();
binding.btnAdd.setOnClickListener(v -> {
sqliteHelper.insert(database);
String info = sqliteHelper.query(database);
binding.tvInformation.setText(info);
});
binding.btnDelete.setOnClickListener(v -> {
sqliteHelper.delete(database);
String info = sqliteHelper.query(database);
binding.tvInformation.setText(info);
});
binding.btnModify.setOnClickListener(v -> {
sqliteHelper.update(database);
String info = sqliteHelper.query(database);
binding.tvInformation.setText(info);
});
binding.btnQuery.setOnClickListener(v -> {
String info = sqliteHelper.query(database);
binding.tvInformation.setText(info);
});
}
@Override
protected void onDestroy() {
if(database.isOpen()){
database.close();
}
super.onDestroy();
}
}
使用SQL语句直接操作CRUD
插入数据
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
arrayOf("The Da Vinci Code", "Dan Brown", "454", "16.96")
)
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
arrayOf("The Lost Symbol", "Dan Brown", "510", "19.95")
)
更新数据:
db.execSQL("update Book set price = ? where name = ?", arrayOf("10.99", "The Da Vinci Code"))
删除数据:
db.execSQL("delete from Book where pages > ?", arrayOf("500"))
查询数据:
val cursor = db.rawQuery("select * from Book", null)