Android第一行代码 Day06笔记

tips:

  • EditText: setSelection()方法:将输入光标移到到文本的末尾
  • TextUtils.isEmpty()方法:对字符串进行非空判断,可以一次性进行两种空值的判断

6. 数据存储

文件存储:不对存储的数据进行任何格式化
所有的文件默认存储在:/data/data/packagename/files目录下

Context类提供openFileOutput()方法: 返回一个FileOutputStream对象,有两个参数

  • 第一个参数为文件名不能包含路径
  • 第二个参数为文件的操作模式
  • MODE_PRIVATE: 默认的操作模式,表示当指定同文件名时,所写入的内容会覆盖原文件的内容
  • MODE_APPEND: 如果该文件存在,则向其中追加内容,不存在则创建新文件

代码示例:


    private void save(String inputText) {

        FileOutputStream os = null;
        BufferedWriter bw = null;
        try {

            os = openFileOutput("data", Context.MODE_PRIVATE);

            bw = new BufferedWriter(new OutputStreamWriter(os));

            bw.write(inputText);
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {

            try {
                if(bw!=null){
                    bw.close();
                }

                if(os!=null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

  • openFileInput(): 返回一个FileInputStream对象
  • 一个参数:文件名

代码示例:


    private String read(){
        FileInputStream fis = null;
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        try {

            fis = openFileInput("data");

            br = new BufferedReader(new InputStreamReader(fis));
            String str = "";
            while((str = br.readLine())!=null){
                sb.append(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(br != null){
                    br.close();
                }
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

使用键值对的方式存储 支持多种不同的数据类型存储,该类主要用于基本类型。
存储目录:/data/data/

获取SharedPreferences对象方法:

  • Context类中 getSharedPreferences()方法: 如果需要多个使用名称来区分的SharedPreferences文件,则可以使用该方法。
    两个参数:
  • name:指定文件名
  • mode:指定访问权限,目前只有MODE_PRIVATE(默认的操作模式,和直接传入0的效果是相同的)这一种模式可选,
  • Activity类中 getPreferences()方法:只接收一个操作模式参数,使用时会自动将当前活动的类名作为SharedPreferences的文件名
  • PreferencesManager类中 getDefaultSharedPreferences()静态方法:接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件

获取到SharedPreferences对象后,存储数据的具体步骤:

使用put方法存储数据,接收两个参数,第一个参数是键,第二个参数是对应的值

代码示例:


 SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
 editor.putString("键","值");
 editor.putInt("键",值);
 editor.putBoolean("键",值);
 editor.apply();

使用get方法获取数据,一般接收两个参数,第一个参数是键,第二个参数是默认值,表示当传入的键找不到对应的值时返回传入的默认值

代码示例:


 SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);
 preferences.getString("键","default_value");
 preferences.getInt("键",default_value);
 preferences.getBoolean("键",default_value);

使用SQLiteOpenHelper:需要自定义一个帮助类继承,然后重写两个方法以及构造方法

  • onCreate():创建数据库
  • onUpgrade():升级数据库

两个实例方法: 都可以创建或打开一个现有的数据库(已存在直接打开,不存在则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象,数据库文件会存放在 /data/data/

  • getReadableDatabase():当数据库不可写入时,将以只读的方式去打开数据库
  • getWriteableDatabase():当数据库不可写入时,将出现异常

重写的构造方法中的4个参数:

  • context:上下文对象
  • name:数据库名称
  • factory:允许在查询的时候返回一个自定义的Cursor
  • version:版本号,用于升级数据库使用

数据库建表语句中数据类型:

  • integer:整形
  • real:浮点型
  • text:文本类型
  • blob:二进制类型

使用db.execSQL()方法:执行sql语句

adb调试工具:

  • adb shell进入控制台
  • 使用cd 命令进入到项目的databases目录下,使用ls可以查看文件
  • sqlite3 数据库名.db 打开对应的数据库
  • .table 查看数据库中的表 .schema 查看表的建表语句
  • .exit.quit 退出数据库的编辑

自定义帮助类代码示例:

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String CREATE_BOOK = "create table Book(\n" +
            "\tid integer primary key autoincrement,\n" +
            "\tauthor text,\n" +
            "\tprice real,\n" +
            "\tpages integer,\n" +
            "\tname text\n" +
            ")";

    private Context mContext;

    public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
    }

}

在主活动中:


  private MyDatabaseHelper dbHelper;

  dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);

  dbHelper.getWritableDatabase();

流程:

代码示例:

  • 在MyDatabaseHelper类中:

    private static final String CREATE_CATEGORY = "create table Category(\n" +
            "\tid integer primary key autoincrement,\n" +
            "\tcategory_name text,\n" +
            "\tcategory_code integer\n" +
            ")";

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }
  • 在主活动中:

  dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);

  dbHelper.getWritableDatabase();

tips:借助dbHelper.getWritableDatabase()返回的SQLiteDatabase对象进行CRUD操作
inset() 方法:三个参数

  • table:表名
  • nullColumnHack:用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般用不到
  • ContentValues:提供一系列的put()方法重载,用于向 ContentValues中添加数据

代码示例:

  • 使用insert()方法进行添加数据:
SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();

                values.put("name","The Da Vinci Code");
                values.put("author","Dan Brown");
                values.put("pages",454);
                values.put("price",16.96);

                db.insert("Book",null,values);
                values.clear();

                values.put("name","The Lost Symbol");
                values.put("author","Dan Brown");
                values.put("pages",510);
                values.put("price",19.95);

                db.insert("Book",null,values);
  • 使用原生sql语句进行数据添加:
 db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)",new String[]{"The Da Vinci Code","Dan Brown","123","12.65"});

update() 方法:四个参数

  • table:表名
  • ContentValues对象:把更新的数据组装进去
  • whereClause: 某一个条件或多个,用于约束更新某一行或某几行的数据,不指定默认更新所有行
  • whereArgs:数组,对应的条件值

代码示例:

  • 使用update()方法进行更新数据:
 SQLiteDatabase db = dbHelper.getWritableDatabase();
 ContentValues values = new ContentValues();
 values.put("price",10.99);
 db.update("Book",values,"name=?",new String[]{"The Da Vinci Code"});
  • 使用原生sql语句进行数据更新:
db.execSQL("update Book set price=?where name=?",new String[]{"12.36","The Da Vinci Code"});

delete() 方法:三个参数

  • table:表名
  • whereClause: 某一个条件或多个,用于约束更新某一行或某几行的数据,不指定默认删除所有行
  • whereArgs:数组,对应的条件值

代码示例:

  • 使用delete()方法进行更新数据:
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book","pages > ?",new String[]{"500"});
  • 使用原生sql语句进行数据删除:
db.execSQL(" delete from Book where pages > ?",new String[]{"100"});

tips:

  • cursor.getColumnIndex()方法: 获取某一列在表中对应的位置索引

query() 方法:7个参数,返回一个Cursor对象

  • table:表名
  • columns:指定查询哪几列,不指定查询所有
  • selection:指定where的约束条件,用于约束查询某一行或某几行的数据,不指定默认查询所有行
  • selectionArgs:为占位符提供具体的值
  • groupBy:指定需要去group by的列
  • having:用于对group by之后的数据进一步过滤
  • orderBy:指定查询结果的排列方式

代码示例:

  • 使用query()方法进行更新数据:
                SQLiteDatabase db = dbHelper.getWritableDatabase();

                Cursor cursor = db.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"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));

                        Log.d("MainActivity","book name is "+name);
                        Log.d("MainActivity","book author is "+author);
                        Log.d("MainActivity","book pages is "+pages);
                        Log.d("MainActivity","book price is "+price);
                    }while (cursor.moveToNext());
                }
                cursor.close();
  • 使用原生sql语句进行数据查询:

                Cursor rawQuery = db.rawQuery("select * from Book", null);
                if(rawQuery.moveToFirst()){
                    do {
                        String name = rawQuery.getString(rawQuery.getColumnIndex("name"));
                        String author = rawQuery.getString(rawQuery.getColumnIndex("author"));
                        int pages = rawQuery.getInt(rawQuery.getColumnIndex("pages"));
                        double price = rawQuery.getDouble(rawQuery.getColumnIndex("price"));

                        Log.d("MainActivity","book name is "+name);
                        Log.d("MainActivity","book author is "+author);
                        Log.d("MainActivity","book pages is "+pages);
                        Log.d("MainActivity","book price is "+price);
                    }while (rawQuery.moveToNext());
                }

                rawQuery.close();
  • 引入依赖包: 在build.gradle文件中dependencies引入 implementation ‘org.litepal.android:core:1.6.1’
  • 创建数据库表所对应的模型类,同时继承于DataSupport类
  • 在src/main目录下右键目录assets,然后新建litepal.xml文件,并编辑

<litepal>

    <dbname value="BookStore">dbname>
    <version value="1">version>

    <list>

        <mapping class="com.example.litepaltest.Book">mapping>
        <mapping class="com.example.litepaltest.Category">mapping>
    list>
litepal>
  • 配置LitePalApplication

 android:name="org.litepal.LitePalApplication"
  • 创建数据库:
 LitePal.getDatabase();
  • 升级数据库:
  • 情况1:如果是向某一个表中添加一个列,直接修改对应模型类,添加一个字段即可
  • 情况2:如果是添加一张表,则只需要新建一个对应模型类即可
  • 如果是情况1则最后在litepal.xml文件中将version版本号加1,如果是情况2则最后在litepal.xml文件中list标签中,配置映射模型类,并将版本号加1
  • 最后重新运行程序,数据库已经成功升级,同时LitePal自动保留之前表中的数据

流程:为要添加的表的模型类设置好数据,在通过实例调用 save() 方法进行数据添加

代码示例:

 Book book = new Book();

 book.save();

对已存储的对象重新设值,是否为已存储的对象通过model.isSaved()方法判断

isSave()方法返回true的两种情况:

  • 一种情况是已经调用过model.save()方法
  • 一种情况是通过LitePal提供的API查询出来的对象

代码示例:

  • 只对已存储对象进行操作:

                Book book = new Book();
                book.setName("The Lost Symbol");
                book.setAuthor("Dan Brown");
                book.setPages(510);
                book.setPrice(19.95);
                book.setPress("Unknow");
                book.save();
                book.setPrice(10.99);
                book.save();
  • 使用updateAll()方法更新:

                Book book = new Book();
                book.setPrice(14.95);
                book.setPress("Anchor");
                book.updateAll("name=? and author=?","The Lost Symbol","Dan Brown");
  • 将某一列数据设置为默认值
                Book book = new Book();
                book.setToDefault("列名");
                book.updateAll();
  • 方式1:通过调用save()方法的对象或通过LitePal查询出来的对象,可以直接调用delete()方法删除
  • 方式2:DataSupport.deleteAll() 两个参数
  • modelClass:指定表名.class,意味删除哪张表的数据
  • …conditions:指定约束条件,如果不指定则删除表中所有数据

代码示例:

DataSupport.deleteAll(Book.class,"price,"15");

查询API:以下方法都返回一个Book类型的List集合
参数均为模型类名.class

  • DataSupport.findAll():查询表中所有数据
  • DataSupport.findFirst():返回表中的第一条数据
  • DataSupport.findLast():返回表中的最后一条数据

可组合使用的连缀方法进行复杂的查询操作:

  • DataSupport.select().find(表名.class):用于指定查询哪几列的数据,参数为列名,之间用逗号隔开
  • DataSupport.where().find(表名.class):用于指定查询的条件,参数1为约束条件,包含占位符,参数2为对应条件值
  • DataSupport.order().find(表名.class):用于指定结果的排序方式,desc降序 asc或者不写表示升序,参数为列名中间空格后跟排序方式
  • DataSupport.limit().find(表名.class):用于指定查询结果的数量,参数为int类型的数字
  • DataSupport.limit().offset().find(表名.class):用于指定查询结果的偏移量,参数为int类型的数字

代码示例:

  • 使用方法进行查询操作:

                List<Book> books = DataSupport.select("name", "author", "pages")
                        .where("pages>?", "400")
                        .order("pages desc")
                        .limit(3)
                        .offset(3)
                        .find(Book.class);

  • 使用原生的SQL语句进行查询:
    DataSupport.findBySQL():返回一个Cursor对象,参数1用于指定SQL语句(内含占位符),参数2为可变参数列表,用于指定占位符的值
Cursor cursor = DataSupport.findBySQL("select * from Book where pages>? and price, "400", "10");

Original: https://blog.csdn.net/weixin_46078890/article/details/123375584
Author: na小子叫坚强
Title: Android第一行代码 Day06笔记

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815610/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球