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)