首页 > 其他分享 >Android中数据存储

Android中数据存储

时间:2024-09-13 18:54:08浏览次数:14  
标签:存储 return String SharedPreferences key Android 数据 public

数据存储

Android中提供了五种主要的数据存储方式,分别为文件存储,SharedPreferences存储,SQLite数据库存储,ContentProvider存储,网络存储。主要整理文件存储,SharedPreferences存储,SQLite数据库存储,Litepal,序列化知识点及应用

文件存储

  • Android的文件存储主要分为内部存储和外部存储两部分
  • 在Android中,文件存储的读写主要通过Java的IO流体系来实现。Android还提供了Context类中的openFileInput()openFileOutput()方法来简化文件的读写操作。
  • 故可以分为四个板块解析文件存储,分别是:将数据写入内部存储文件中,读取内部存储文件中的数据。将数据写入外部存储文件中,读取外部存储文件中的数据

内部存储

  1. 存储路径:内部存储是是将应用中的数据以文件存储的方式存储在应用中,内部存储的路径通常是/data/data/<包名>/files
  2. 私有化:每个应用都有自己的私有内部存储空间,其他应用无法直接访问,如有需要访问需申请权限
  3. 自动清理:当应用被卸载时,内部存储中的文件也会被一并删除。
  4. 适用范围:适用于存储应用的私有数据,如配置文件、数据库、缓存等。这些数据通常不需要与其他应用共享,且当应用被卸载时,这些数据也需要被一并删除。
将数据写入内部存储文件中
  1. 使用了ContextopenFileOutput()方法来创建或打开文件,并返回一个FileOutputStream对象。
  • 通过Context提供的openFileOutput(String name, int mode))方法。

  • openFileOutput()方法用于打开应用对应的输出流,将数据存储在指定的文件中。

  • 参数name表示文件名,mode表示文件操作的方式。

注意:第二个参数是文件的操作模式,主要有两种模式可选,MODE_PRIVATE和 MODE_APPEND。

  • MODE_PRIVATE是默认的操作模式,表示该文件只能被当前程序读写
  • 而MODE_APPEND,则表示如果该文件已存在,就往文件里面追加内容,不存在就创建新文件。
  • 另外两种:MODE_WORLD_READABLE和 MODE_WORLD_WRITEABLE,这两种模式表示允许其他的应用程序对我们程序中的文件进行读写操作,不过由于这两种模式过于危险,很容易引起应用的安全性漏洞,已在 Android 4.2版本中被废弃。

2.使用write()方法将字符串转换为字节并写入文件。注意,这里使用了try-with-resources语句来自动关闭FileOutputStream

String fileName = "myfile.txt";  
String fileContents = "Hello";  
  
try {
FileOutputStream fos = openFileOutput(fileName, Context.MODE_PRIVATE);
    fos.write(fileContents.getBytes());  
} finally{
try{
	if(fos!=null){
		fos.close();//关闭输入流
}catch (IOException e) {  
    e.printStackTrace();  
	}
}

读取内部存储文件中的数据
  1. 这里使用了ContextopenFileInput()方法来获取文件的FileInputStream
  • openFileInput()方法用于打开应用对应的输入流,读取指定文件中的数据
  1. 然后通过InputStreamReaderBufferedReader来逐行读取文件内容。
StringBuilder stringBuilder = new StringBuilder();  
  
try (FileInputStream fis = openFileInput(fileName)) {  
    InputStreamReader inputStreamReader = new InputStreamReader(fis);  
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    String line;  
    while ((line = bufferedReader.readLine()) != null) {  
        stringBuilder.append(line);  
    }  
    Log.d("InternalStorage", "File content: " + stringBuilder.toString());  
} catch (IOException e) {  
    e.printStackTrace();  
}

外部存储

  1. 存储路径:将数据以文件的形式存储到一些外部设备(例如SD卡或者设备内嵌的存储卡)上,属于永久性存储方式。(外部存储的文件通常位于storage/emulated/O目录下)
  2. 共享性:外部存储的文件可以被其他应用程序共享,当将外部存储设备连接到计算机时,这些文件可以被浏览、修改和删除,因此这种方式不安全。
  3. 适用范围:适用于存储需要与其他应用共享或长期保存的数据,如图片、视频、音乐等。这些数据在应用卸载时不会被删除,且可以被其他应用访问。
  4. 申请权限:AndroidManifest.xml文件中已经声明了相应的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
<!-- 对于Android 10及以上,建议使用分区存储(Scoped Storage),则不需要这个权限 -->
将数据写入外部存储文件中(这里以机身存储为例,SD卡类似)
String externalFilesDir = getExternalFilesDir(null).getAbsolutePath();  
File file = new File(externalFilesDir, "myfile_external.txt");  
String fileContents = "Hello, External Storage!";  
  
try (FileOutputStream fos = new FileOutputStream(file)) {  
    fos.write(fileContents.getBytes());  
    Log.d("ExternalStorage", "File written to external storage");  
} catch (IOException e) {  
    e.printStackTrace();  
}
读取外部存储文件中的数据
StringBuilder stringBuilder = new StringBuilder();  
  //这里假设file是一个指向外部存储中文件的File对象
try (FileInputStream fis = new FileInputStream(file)) {  
    InputStreamReader inputStreamReader = new InputStreamReader(fis);  
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    String line;  
    while ((line = bufferedReader.readLine()) != null) {  
        stringBuilder.append(line);  
    }  
    Log.d("ExternalStorage", "File content: " + stringBuilder.toString());  
} catch (IOException e) {  
    e.printStackTrace();  
}

SharedPreferences

  • SharedPreferences 是 Android 平台上一个轻量级的存储类,它允许你保存和读取应用程序的私有原始数据类型。
  • 主要用于存储少量的数据,如用户的设置、偏好等。
  • 以 XML 文件的形式保存在设备的内部存储中,文件名和路径由 Android 系统自动管理。

将数据存储在SharedPreferences

使用Context类中的getSharedPreferences()方法。

  • 其中getSharedPreferences()方法接收两个参数,第一个参数是文件名,第二个参数是操作模式,现主要是MODE_PRIVATE。

具体实现步骤:

  1. 调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象。

  2. 向 SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用putBoolean()方法,添加一个字符串则使用putstring()方法,以此类推。

  3. 调用 apply()方法将添加的数据提交,从而完成数据存储操作。

 /**
     * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
     *
     * @param context 上下文
     * @param key     key值
     * @param object  value值
     */
    public static void put(Context context, String key, Object object) {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        if (object instanceof String) {
            editor.putString(key, (String) object);
        } else if (object instanceof Integer) {
            editor.putInt(key, (Integer) object);
        } else if (object instanceof Boolean) {
            editor.putBoolean(key, (Boolean) object);
        } else if (object instanceof Float) {
            editor.putFloat(key, (Float) object);
        } else if (object instanceof Long) {
            editor.putLong(key, (Long) object);
        } else {
            editor.putString(key, object.toString());
        }

        SharedPreferencesCompat.apply(editor);
    }

读取SharedPreferences中数据

SharedPreferences 文件中读取数据会更加地简单。SharedPreferences对象中提供了一系列的get方法,用于对存储的数据进行读取,每种get方法都对应了SharedPreferences.Editor中的一种 put方法。

  /**
     * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     *
     * @param context       上下文
     * @param key           key值
     * @param defaultObject 默认value值,当数据不存在或者类型不匹配时,尝试返回默认值或对应类型的值,都不是则返回null
     * @return value值
     */
    public static Object get(Context context, String key, Object defaultObject) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);

        if (defaultObject instanceof String) {
            return sp.getString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float) {
            return sp.getFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long) {
            return sp.getLong(key, (Long) defaultObject);
        }

        return null;
    }

删除SharedPreferences中数据

  1. 删除某个特定的键值对,而不是清除整个SharedPreferences文件中的所有数据可以使用SharedPreferences.Editorremove(String key)方法。
  /**
     * 移除某个key值已经对应的值
     *
     * @param context 上下文
     * @param key     key值
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        SharedPreferencesCompat.apply(editor);
    }
  1. 删除或清除某个SharedPreferences文件中的所有数据,你不能直接删除文件本身(因为Android系统负责文件的管理),但你可以通过SharedPreferences.Editorclear()方法来清除所有存储的数据。
   /**
     * 清除所有数据
     *
     * @param context 上下文
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);
    }

关于apply()commit() 方法

  • apply() 方法是异步的,它不会返回任何值,但会尽快将更改写入磁盘。
  • commit() 方法是同步的,它会返回一个布尔值来表示更改是否成功写入磁盘。然而,由于 apply() 方法提供了更好的性能,并且对于大多数用例来说,立即知道更改是否成功写入磁盘并不是必需的,因此 apply() 是更推荐的方法。

项目中使用 SharedPreferences例子

finnal
  1. 定义final关键字用于声明一个变量、方法或类不能被修改(对于变量)或不能被重写(对于方法和类)。

  2. 作用:

  • 对于变量:一旦给final变量赋了初值,这个值就不能被改变。这通常用于定义常量。

  • 对于方法final方法不能被子类重写。这通常用于防止方法被意外地修改其行为。

  • 对于类final类不能被继承。这通常用于设计那些你不希望被扩展的类,可能是出于安全考虑或设计上的决定。

  • 示例:在你的代码片段中,IF_FIRSTIS_ADMINACCOUNT都是使用final声明的字符串常量,这意味着这些字符串的值在编译时就已经确定,并且在整个程序中不能被改变。

static
  1. 定义static关键字用于声明属于类的变量和方法,而不是属于类的某个特定对象的实例变量和实例方法。

  2. 作用

  • 静态变量:属于类本身,在内存中只有一份拷贝,无论创建多少个对象,静态变量都只有一份拷贝被所有对象共享。
  • 静态方法:属于类的方法,可以在没有创建对象的情况下通过类名直接调用。静态方法内部只能访问类的静态变量和静态方法,不能直接访问类的实例变量和实例方法。
final和static结合使用
  • finalstatic一起使用时,它们通常用于定义类常量,这些常量在编译时就被确定,并且在整个类(甚至整个应用程序)中保持不变。
  • 示例中的IF_FIRSTIS_ADMINACCOUNTFILE_NAME都是类常量,它们在整个应用程序的生命周期内都是不变的。
创建一个存放SharedPreferences的工具类

主要包含了SharedPreferences的文件名,存储,读取,删除SharedPreferences数据等方法。具体代码:


/**
 * 数据持久化工具类
 */
public class SPUtils {
    public static final String IF_FIRST = "is_first";//是否第一次进来
    public static final String IS_ADMIN = "is_admin";//是否是管理员
    public static final String ACCOUNT = "account";//账号
    /**
     * 保存在手机里面的文件名
     */
    private static final String FILE_NAME = "share_data";
    /**
     * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
     *
     * @param context 上下文
     * @param key     key值
     * @param object  value值
     */
    public static void put(Context context, String key, Object object) {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        if (object instanceof String) {
            editor.putString(key, (String) object);
        } else if (object instanceof Integer) {
            editor.putInt(key, (Integer) object);
        } else if (object instanceof Boolean) {
            editor.putBoolean(key, (Boolean) object);
        } else if (object instanceof Float) {
            editor.putFloat(key, (Float) object);
        } else if (object instanceof Long) {
            editor.putLong(key, (Long) object);
        } else {
            editor.putString(key, object.toString());
        }

        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     *
     * @param context       上下文
     * @param key           key值
     * @param defaultObject 默认value值,当数据不存在或者类型不匹配时,尝试返回默认值或对应类型的值,都不是则返回null
     * @return value值
     */
    public static Object get(Context context, String key, Object defaultObject) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);

        if (defaultObject instanceof String) {
            return sp.getString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float) {
            return sp.getFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long) {
            return sp.getLong(key, (Long) defaultObject);
        }

        return null;
    }

    /**
     * 移除某个key值已经对应的值
     *
     * @param context 上下文
     * @param key     key值
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 清除所有数据
     *
     * @param context 上下文
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 查询某个key是否已经存在
     *
     * @param context 上下文
     * @param key     key值
     * @return 是否存在
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.contains(key);
    }

    /**
     * 返回所有的键值对
     *
     * @param context 上下文
     * @return 所有的键值对
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.getAll();
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     *
     * @author zhy
     */
    private static class SharedPreferencesCompat {
        private static final Method sApplyMethod = findApplyMethod();

        /**
         * 反射查找apply的方法
         *
         * @return Method
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static Method findApplyMethod() {
            try {
                Class clz = SharedPreferences.Editor.class;
                return clz.getMethod("apply");
            } catch (NoSuchMethodException e) {
            }

            return null;
        }

        /**
         * 如果找到则使用apply执行,否则使用commit
         *
         * @param editor SharedPreferences.Edito
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                if (sApplyMethod != null) {
                    sApplyMethod.invoke(editor);
                    return;
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            editor.commit();
        }
    }

}
如何调用

在其余Activity或Fragment中调用get()方法获取当前账号及是否是管理员账号。

  private Boolean mIsAdmin;//是否管理员
  private String mAccount;//账号
 //在onCreate()方法中
 mIsAdmin = (Boolean) SPUtils.get(myActivity,SPUtils.IS_ADMIN,false);
 mAccount = (String) SPUtils.get(myActivity,SPUtils.ACCOUNT,"");

可通过三目运算符判断是否是管理员admin,设置视图的可见性。例如:

  • 三目运算符基本语法是条件 ? 表达式1 : 表达式2。如果条件为真(true),则整个表达式的结果是表达式1的结果;如果条件为假(false),则结果是表达式2的结果。
  • setVisibility(int visibility)方法用于设置视图的可见性。
  • View.VISIBLE作为参数时,视图可见。
  • View.GONE作为参数时,视图不可见且不占用布局空间。
 rbUserManage.setVisibility(mIsAdmin? View.VISIBLE: View.GONE);

SQLite数据库

在Android开发中,SQLite是一种常用的轻量级数据库,用于存储和管理应用程序的本地数据。

SQLite数据库的创建

需要创建一个继承自SQLiteOpenHelper的类,这个类将负责数据库的创建和版本管理。

  • 重写onCreate(SQLiteDatabase db)方法创建数据库。
  • 重写onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法数据库版本更新时调用
  • 其中 super(context, DATABASE_NAME, null, DATABASE_VERSION); 参数分别是上下文,数据库文件名称,结果集,版本号。
    class MyHelper extends SQLiteOpenHelper{
        //构造器,参数:上下文,数据库文件名称,结果集,版本号。定义数据库
        public MyHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
        //数据库初始化,创建表或视图文件
        @Override
        public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table user(user_id interger primary key ,userName varchar(10),password varchar(10))");
        }

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

        }
    }

SQLite数据库的增

使用MyHelper实例获取SQLiteDatabase对象,然后使用insert方法添加数据。

  1. getWritableDatabase()方法得到SOLiteDatabase 对象
  2. 获得ContentValues对象并将数据
    添加到ContentValues对象中
  3. 调用insert()方法将数据插入information表中。
  • insert()方法可以接收3个参数,第1个参数是数据表的名称;第2个参数表示,如果发现将要插人的行空行,会将这个列名的值设为null;第三个参数为ContentValues 对象。
  • ContentValues类类似于 Map类,通过键值对的形式存入数据,这里的 key 表示插入数据的列名,value表示要插入的数据
  • SQLiteDatabase 对象后一定要调用close()方法关闭数据库连接,否则数据库连接会一直存在,不断消耗内存
    //创建数据库和表
    public MyDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        db=this.getWritableDatabase();
    }
   //添加用户信息
    public boolean insertUser(String username,String password1,String password2){
        ContentValues contentValues=new ContentValues();
        contentValues.put("username",username);
        contentValues.put("password1",password1);
        contentValues.put("password2",password2);
        long i=db.insert("userInfo",null,contentValues);
        return i>0?true:false;
    }

SQLite数据库的删

使用SOLiteDatabase类中delete方法根据条件删除数据

  //删除数据,根据记录的用户名删除
    public boolean delatedUser(String deletedname){
        long i=db.delete("userInfo","username=?",new String[]{deletedname});
        return i>0?true:false;
    }

SQLite数据库的改

SQLiteDatabase 类中存在一个update()方法,用于修改数据库表中的数据。

  1. getWritableDatabase()方法得到SOLiteDatabase 对象db
  2. 获得ContentValues对象并将数据
    添加到ContentValues对象中
  3. 通过调用put()方法将需要修改的字段名称和字段值放人对象values中
  4. 通过对象db调用update()方法来修改数据库表中对应的数据。
  • update()方法传递了4个参数,其中,第1个参数表示数据库表的名称,第2个参数表示最新的数据,第3个参数表示要修改的数据的查找条件,第4个参数表示查找条件的参数
 //修改用户数据的更新
    public boolean updateUser(String username,String password1,String password2){
        ContentValues contentValues=new ContentValues();
        contentValues.put("username",username);
        contentValues.put("password1",password1);
        contentValues.put("password2",password2);
        long i=db.update("userInfo",contentValues,"username=?",new String[]{username});
        return i>0?true:false;
    }

SQLite数据库的查

在进行数据查询时使用的是query()方法,该方法返回的是一个行数集合Cursor。通过getCount()方法获取到查询结果的总数,然后通过moveToNext()方法移动游标指向下一行数据,接着通过为geiString()方法传入列名获取对应的数据。

  • Cursor是个游标接口,提供了遍历查询结果的方法。需要注意的是,在使用完Cursor后、一定要及时关闭,否则会造成内存泄露。
  • query()方法包含7个参数,第1个参数表示表名称,第2个参数表示查询的列,第3个参数表示的是接收查询条件的子句,第4个参数接收查询子句对应的条件值,第5个参数表示分组6个参数用于接收having条件(定义组的过滤器),第7个参数表示排序方式。
  //查询用户数据
    public userbean queryUser(String username){
        Cursor cursor=db.query("userInfo",null,"username=?",new String[]{username},null,null,null,null);
        if (cursor.getCount()==1){
            cursor.moveToFirst();
            String Id=cursor.getString(0);
            String Username=cursor.getString(1);
            String Password=cursor.getString(2);
            userbean ub=new userbean();
            ub.setId(Id);
            ub.setUsername(Username);
            ub.setPassword1(Password);
            cursor.close();
            return ub;
        }else {
            return null;
        }
    }

创建一个继承自SQLiteOpenHelper的类

将上方的几个方法汇总写入

public class MyDbHelper extends SQLiteOpenHelper {
    SQLiteDatabase db;
    //创建数据库和表
    public MyDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        db=this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table userInfo(id integer primary key autoincrement,username varchar(50),password1 varchar(10),password2 varchar(10))");}
     //添加用户信息
    public boolean insertUser(String username,String password1,String password2){
        ContentValues contentValues=new ContentValues();
        contentValues.put("username",username);
        contentValues.put("password1",password1);
        contentValues.put("password2",password2);
        long i=db.insert("userInfo",null,contentValues);
        return i>0?true:false;
    }
    //修改用户数据的更新
    public boolean updateUser(String username,String password1,String password2){
        ContentValues contentValues=new ContentValues();
        contentValues.put("username",username);
        contentValues.put("password1",password1);
        contentValues.put("password2",password2);
        long i=db.update("userInfo",contentValues,"username=?",new String[]{username});
        return i>0?true:false;
    }
    //删除数据,根据记录的用户名删除
    public boolean delatedUser(String deletedname){
        long i=db.delete("userInfo","username=?",new String[]{deletedname});
        return i>0?true:false;
    }
    //查询用户数据
    public userbean queryUser(String username){
        Cursor cursor=db.query("userInfo",null,"username=?",new String[]{username},null,null,null,null);
        if (cursor.getCount()==1){
            cursor.moveToFirst();
            String Id=cursor.getString(0);
            String Username=cursor.getString(1);
            String Password=cursor.getString(2);
            userbean ub=new userbean();
            ub.setId(Id);
            ub.setUsername(Username);
            ub.setPassword1(Password);
            cursor.close();
            return ub;
        }else {
            return null;
        }
    }
    //查询用户密码

    public userbean queryPassword(String username,String password1){
        Cursor cursor = db.query("userInfo", new String[]{"username", "password1"}, "password=1?", new String[]{username}, null, null, null, null);
        if (cursor.getCount()==1){
            cursor.moveToNext();
            int index1 = cursor.getColumnIndex("username");
            int index2 = cursor.getColumnIndex("password1");
            username = cursor.getString(index1);
            password1 = cursor.getString(index2);
            userbean ub=new userbean();
            ub.setUsername(username);
            ub.setPassword1(password1);
            cursor.close();
            return ub;
        }else {
            return null;
        }
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

如何调用

创建一个user实类
public class userbean {
    private String id;
    private String username;
    private String password1;
    private String password2;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword1() {
        return password1;
    }

    public void setPassword1(String password1) {
        this.password1 = password1;
    }

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }



}
数据添加
 //数据添加
 myDbHelper = new MyDbHelper(RegisterActivity.this, "db7.db", null, 1);
                         Boolean flag = myDbHelper.insertUser(ub.getUsername(), ub.getPassword1(), ub.getPassword2());

数据删除
 //获取编辑框中输入的内容
                String selection = e_selection.getText().toString();
                myDbHelper = new MyDbHelper(deteleActivity.this, "db10.db", null, 1);
                Boolean flag = myDbHelper.delatedData(selection);
                if (flag == true) {
                    //如果添加成功,将数据回传的结果设置为2
                    setResult(2);
                    Toast.makeText(deteleActivity.this, "删除成功!", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(deteleActivity.this, "删除失败!", Toast.LENGTH_LONG).show();
                }
                break;
数据修改
                    //数据添加
                    myDbHelper=new MyDbHelper(modifyinfo.this,"db7.db",null,1);
                    Boolean flag=myDbHelper.updateUser(Name,Password1,Password2);
                    if (flag==true){
                        //如果添加成功,将数据回传的结果设置为2
                        // Intent intent1=new Intent();
                        //   intent1.putExtra("return","信息已成功收到");
                        setResult(2);
                        Toast.makeText(modifyinfo.this,"修改成功!",Toast.LENGTH_LONG).show();

                    }else{
                        Toast.makeText(modifyinfo.this,"修改失败!",Toast.LENGTH_LONG).show();
                    }
数据查询
   //判断用户是否存在
                     myDbHelper = new MyDbHelper(RegisterActivity.this, "db7.db", null, 1);
                     userbean findusername = myDbHelper.queryUser(getusername);
                     if (findusername == null) {
                         ub.setUsername(getusername);

Litepal

LitePal是一款开源的 Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发最常用到的一些数据库功能进行了封装,使得不用编写一行 SOL,语句就可以完成各种建表和增删改查的操作。

配置Litepal

  1. 编辑 app/build.gradle文件,在 dependencies 闭包中添加如下内容
 //litePal
    implementation 'org.litepal.android:core:1.6.1'
  1. 接下来需要配置 litepal.xml 文件。右击app/src/main 日录→New→Directory,创建一个 assets 目录,然后在assets目录下再新建一个litepal.xml文件,
<litepal>
    <!--数据库名称-->
    <dbname value="fruit"/>
    <!--数据库版本-->
    <version value="1"/>
    <list>
        <!--映射   每一张表 -->
        <mapping class="com.example.fruit.bean.User"/>
   </list>

</litepal>
  1. 配置一下 LitePalApplication,修改 AndroidManifest.xml中的代码
 android:name=".MyApplication"
  • MyApplication的作用:

    Android提供了一个Application类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。而我们可以定制一个自己的 Application 类,以便于管理程序内一些全局的状态信息。

    经过这样的配置之后,LitePal就能在内部自动获取到Instance了并初始化了 LitePal 数据库

public class MyApplication extends Application {
    public static MyApplication Instance;
    @Override
    public void onCreate() {
        super.onCreate();
        Instance = this;
        //初始化LitePal数据库
        LitePal.initialize(this);

    }
    private Activity mMainActivity;

    public Activity getMainActivity() {
        return mMainActivity;
    }

    public  void setMainActivity(Activity mainActivity) {
        mMainActivity = mainActivity;
    }
}

如何调用

创建实体类:

通过注解定义数据库表结构,创建对应的实体类。


public class Goods extends DataSupport implements Serializable {
    private Integer typeId;//类型
    private String title;//标题
    private String img;//图片
    private String content;//内容
    private String price;//价格
    private String date;//时间

    public Integer getTypeId() {
        return typeId;
    }

    public void setTypeId(Integer typeId) {
        this.typeId = typeId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Goods(Integer typeId, String title, String img, String content, String price, String date) {
        this.typeId = typeId;
        this.title = title;
        this.img = img;
        this.content = content;
        this.price = price;
        this.date = date;
    }
}

添加修改数据

判断数据库中是否存在了该商品,存在不保存,不存在则添加商品,或重新设定。

 public void save1(View view) {
        String title=etTitle.getText().toString();
        String price=etprice.getText().toString();
        String img=etImg.getText().toString();
        String content=etContent.getText().toString();
        Integer typeId=spType.getSelectedItemPosition();
        if ("".equals(title)) {
            Toast.makeText(myActivity,"标题不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        if ("".equals(price)) {
            Toast.makeText(myActivity,"价格不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        if ("".equals(img)) {
            Toast.makeText(myActivity,"图片地址不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        if ("".equals(content)) {
            Toast.makeText(myActivity,"描述不能为空", Toast.LENGTH_LONG).show();
            return;
        }
        Goods goods=null;
        //如果 title与 mfruit 的标题不同,或者 mfruit 为 nu11,
        // 这段代码将执行査询并返回第一个找到的 Fruit 对象给 fruit 变量。
        // 如果查询结果为空,fruit 仍然保持为 nu11 。
        if(!title.equals(mgoods!=null?mgoods.getTitle():"")) {
            goods = DataSupport.where("title=?", title).findFirst(Goods.class);
        }
            if (goods == null) {
                if (mgoods != null) {
                    goods = DataSupport.where("title=?", mgoods.getTitle()).findFirst(Goods.class);
                    goods.setTypeId(typeId);
                    goods.setTitle(title);
                    goods.setPrice(price);
                    goods.setImg(img);
                    goods.setContent(content);
                } else {
                    goods = new Goods(typeId, title, img, content, price, sf.format(new Date()));
                }
                goods.save();
                setResult(RESULT_OK);
                finish();
                Toast.makeText(myActivity, "保存成功", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(myActivity, "该标题已存在", Toast.LENGTH_LONG).show();
            }
        }

}
删除数据
 private List<Goods> list =new ArrayList<>();
  Goods goods=list.get(i);
  .....
    public void onClick(DialogInterface dialog, int which) {
                                list.remove(goods);
                                goods.delete();
                                notifyDataSetChanged();
                                Toast.makeText(mActivity,"删除成功", Toast.LENGTH_LONG).show();}
查找数据
  Goods mgoods=(Goods) getIntent().getSerializableExtra("goods");
            tvTitle.setText(mgoods.getTitle());
            tvPrice.setText(mgoods.getPrice());
            tvContent.setText(mgoods.getContent());
            tvDate.setText(String.format("上架时间:%s",mgoods.getDate()));
            Glide.with(mActivity)
                    .asBitmap()
                    .load(mgoods.getImg())
                    .error(R.drawable.ic_error)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(ivImg);

序列化

序列化是一个重要的概念,它涉及到将对象的状态信息转换为可以存储或传输的形式(如保存到文件、通过网络发送等),以及之后能够将这些信息恢复回原来的对象。

什么是序列化和反序列化

  • 序列化:将java堆内存中的对象转为二进制字节码;

  • 反序列化:将二进制字节码转为java对象

为什么要序列化(序列化转成二进制码的目的)?

一句话解释:可传输、可存储、持久化。

将内存中的对象的状态信息转换为可以存储或者传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或者持久性存储区。以后,可以从存储区中读取或者反序列化对象的状态,重新创建该对象。简单地说,序列化就是讲运行时的对象状态转换成为二进制,然后保存到流、内存或者通过网络传输给其他端.

序列化(Serialization)

序列化是指将数据结构或对象状态转换为可以存储或传输的格式的过程。这种格式通常是平台无关的,可以是二进制流、文本文件(如XML、JSON)等。序列化的目的是将对象的状态保存下来,以便可以在程序的后续运行中重新加载,或者通过网络传输到另一个系统或应用程序中。

序列化通常涉及以下几个步骤:

  1. 遍历对象:访问对象的所有成员变量。
  2. 转换成员变量:将成员变量的值转换为可以存储或传输的格式。
  3. 写入:将转换后的数据写入到存储介质(如文件、数据库)或通过网络发送到其他系统。

反序列化(Deserialization)

反序列化是序列化的逆过程,即将存储或传输的格式转换回原始的数据结构或对象的过程。反序列化的目的是重新构造对象,使其具有序列化时的状态。

反序列化通常涉及以下几个步骤:

  1. 读取:从存储介质(如文件、数据库)或网络接收序列化后的数据。
  2. 解析:解析接收到的数据,提取出对象的成员变量值。
  3. 重构对象:使用提取出的成员变量值,重新构造出原始的对象。

serialVersionUID

序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

标签:存储,return,String,SharedPreferences,key,Android,数据,public
From: https://blog.csdn.net/m0_71214256/article/details/142202024

相关文章

  • MyBatis 注解式开发:简洁高效的数据库访问新方式
    文章目录一、MyBatis简介二、注解式开发的优势三、MyBatis注解式开发的基本用法四、MyBatis常用注解介绍五、复杂查询的实现六、总结在Java开发中,MyBatis是一个非常流行的持久层框架,它提供了一种灵活、高效的方式来访问数据库。除了传统的XML配置方式,MyBatis......
  • Redis集群:构建高性能和高可用的键值存储系统
    引言Redis,即RemoteDictionaryServer,是一种开源的高性能键值数据库。它支持多种类型的数据结构,如字符串、哈希、列表、集合、有序集合等。随着业务的发展,单个Redis实例可能无法满足大规模数据存储和高并发访问的需求。Redis集群提供了一种解决方案,通过分布式存储和自动分片来......
  • 数据库设计基础
    数据库的三级模式是指数据库系统中数据的三个不同层次的抽象模型,主要包括:内部模式:这是数据库的物理存储结构,描述了数据在存储介质上的具体存储方式。它包括数据的存储格式、数据的压缩和加密方式、索引的使用等。内部模式是数据库的最底层,通常由数据库管理系统负责管理。概念模......
  • 数据结构之美-深入理解树形结构
    一认识树形结构树形结构是一种广泛应用的非线性数据结构,它在计算机科学和日常生活中都有广泛的应用。比如文件系统,邮件系统,编译器语法树,决策树,网络通信,甚至机器学习当中,都有树形数据结构的影子。本文旨在梳理日常用到的各类树形结构以及其优点和劣势,让渎者对树形结构有一个深入......
  • elementUI--el-form表单数据校验
    一、普通的值类型的数据校验①设置 el-form-item的prop 值与 formdata中定义的key 保持一致`②如果rules需要通过el-form统一设置,rules的key 定义也与prop保持一致(如果不一致,需要在el-form-item中手动指定)③复杂的校验函数可通过 validator 单独定义<el-for......
  • 利用Pandas和Matplotlib进行数据探索性可视化:最佳实践与技巧
    数据可视化是数据分析中不可或缺的一环,它帮助我们更好地理解数据、发现趋势和模式,并有效地传达我们的发现。在Python领域,Pandas和Matplotlib是两个非常强大的库,它们提供了丰富的功能来进行数据分析和可视化。本文将介绍如何结合使用Pandas和Matplotlib进行数据探索性可视化的最佳实......
  • MySQL数据库索引设计的主要原则
    在MySQL数据库中,索引设计是提高查询性能的关键因素之一。什么是索引?索引是数据库中用于提高数据检索效率的数据结构。它类似于书籍的目录,允许用户快速找到所需的数据,而无需扫描整个数据集。在数据库系统中,索引通常用于加速查询操作,特别是对于大型数据集。以下是索引的一些关......
  • 开源数据集 FreiHAND rgb 三维手势建模 手部关键点 >> DataBall
    开源数据集FreiHANDrgb三维手势建模手部关键点manohand混合现实深度学习人工智能FreiHAND是一个用于评估和训练深度神经网络以从单色图像中估计手部姿态和形状的数据集,这是在我们的论文中提出的。其当前版本包含32560个独特的训练样本和3960个独特的评估样本。训......
  • 信息学奥赛初赛天天练-88-CSP-S2023阅读程序1-数据类型、unsigned 关键字、二进制、位
    信息学奥赛初赛天天练-88-CSP-S2023阅读程序1-数据类型、unsigned关键字、二进制、位运算、左移、右移、异或运算PDF文档公众号回复关键字:202409132023CSP-S阅读程序1判断题正确填√,错误填⨉;除特殊说明外,判断题1.5分,选择题3分,共计40分)01#include<iostream>......
  • A-计算机毕业设计定制:93904 家庭健康管理系统(免费领源码)可做计算机毕业设计JAVA、PHP
    摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,家庭健康管理系统被用户普遍使用,为方便用户能够可以随时进行家庭健康管理系统的数据信息管理,特开发了SSM家庭健康管理系......