android数据存储(Preferences,File,SQLite,开源数据库 LitePal)

昨天看到一篇文章程序员如何实现暴富文章来源:小道消息公众号。虽然话题庸俗,但是却很实在。引用作者最后的观点来提醒自己:
放弃幻想,也放弃幻灭,但是不要放弃梦想。
这个时代不会承诺必须给你一套房子,凭什么这么慷慨?
时代只会承诺,你肯定有一些机会。但是当机会来到面前的时候,希望你的能力能够牢牢的抓住它。


任何一个程序都会有一些本地的数据进行存储,有比较私密的,也有缓存数据,有事为了减少网络中的数据,我们也会创建本地的数据库,对于android而言,存储数据的方式有:

  1. SharedPreferences存储
  2. File文件存储
  3. SQLite数据库存储
  4. LitePal的使用

    本节来说说这几种存储模式。

SharedPreferences存储

SharedPreferences存储是以键值对的形式对需要保存的数据进行存储。存储的时候需要提供相应的 key,value,这样在读取的时候通过键值key将数据读取出来。

将数据存储到SharedPreferences中

说说基础:创建的SharedPreferences文件,是存在在你手机/data/data/<package name>/shared_prefs/目录下,在创建的时候需要对文件进行命名和指定对该文件的操作模式。

如何查看AndroidStudio—->Tools—->android—–>Android Device Monitor

创建步骤如下:

  1. 获取SharedPreferences对象

    android获取SharedPreferences对象提供以下几种方式:

    1)Activity类中通过getPreferences(int mode)方法

    该方法接收一个参数(mode—>操作模式)
    mode说明:在android6.0之后的系统中只保留MODE_PRIVATE这一种模式,表示只允许当前的应用程序对该文件进行读写操作
    通过这种方式创建的SharedPreferences文件是以当前活动的类名来进行命名

    2)Activity类中通过getSharedPreferences(String name, int mode)方法

    参数name—>文件名,mode—>操作模式
    这种方式下创建的SharedPreferences文件是以你所创建的文件名进行命名

    3)Context类中getSharedPreferences(String name, int mode)方法

    参数name—>文件名,mode—>操作模式

    4)PreferenceManager类中
    getDefaultSharedPreferences(Context context)方法

    该方法接收一个Context参数,文件名默认为 当前程序的包名为前缀,操作模式默认为MODE_PRIVATE

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

  3. 调用得到的SharedPreferences.Editor对象的putXXXX()方法进行数据的存储。

    Put的值

  4. 之后调用SharedPreferences.Editor对象的apply()方法将添加的数据进行提交,从而完成数据的存储操作。


接下来看看实例:

创建SharedPreferencesActivity并创建相应的布局,提供上述的4中获取SharedPreferences对象的操作按钮,

/**
 * 使用SharedPreferences存储
 * <p>
 * 1.获取SharedPreferences对象
 * 2.调用SharedPreferences.Editor对象添加数据
 * 3.调用apply()方法提交数据
 */

public class SharedPreferencesActivity extends AppCompatActivity {


    private static final String TAG = "SharedPreferencesActiviy";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sharedpreferences);

        //activity中调用getPreferences()方法
        findViewById(R.id.btn_activityPreferences).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putFloat("money", 20.5f);
                editor.apply();
            }
        });


        //activity中调用getSharedPreferences()方法
        findViewById(R.id.btn_activity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sharedPreferences = getSharedPreferences("ACTIVITY_sharedPreferences", MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putString("name", "wedfrend");
                editor.putInt("age", 24);
                editor.putString("sex", "man");
                editor.apply();
            }
        });

        //context调用getSharedPreferences()方法
        findViewById(R.id.btn_Context).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferencesUtils sharedPreferencesUtils = new SharedPreferencesUtils(SharedPreferencesActivity.this);
                sharedPreferencesUtils.putDateToShare("wedfrend");


            }
        });


        //PreferenceManager调用getDefaultSharedPreferences()方法
        findViewById(R.id.btn_defaultSharePreferences).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(SharedPreferencesActivity.this);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putInt("age", 25);
                editor.putString("name", "wedfrend");
                editor.putBoolean("is_man", true);
                editor.apply();
            }
        });
    }

class SharedPreferencesUtils {

    private Context mcontext;


    public SharedPreferencesUtils(Context context) {

        mcontext = context;

    }

    /*存储值*/
    public void putDateToShare(Object object){

        SharedPreferences sharedPreferences = mcontext.getSharedPreferences("CONTEXT_SharePreferences",Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        if(object instanceof String){
            editor.putString("name",(String) object);
        }
        editor.apply();
    }
   }

}

看看执行之后的效果:

看看相应的名称

这些文件无法直接查看,那么我们将这些文件移动到外部,看看ACTIVITY_sharedPreferences.xml文件

shared

跟我们输入的一样。

从SharedPreferences中读取数据

与存储数据类似,读取数据相对简单。步骤如下:

  1. 获取SharedPreferences对象,这里的获取方法与上述的一致,但是要注意的是传入的name参数一定是你本地已经存在这样一个文件。

  2. 调用获取到SharedPreferences对象的getXXXX()方法
    get方法
    接收两个参数,key—>键值,defValue—>自己设置一个默认值
    当在该文件下找不到这个key所对应的的值时,会返回这个相应的默认值。

看看下面的代码:

在上述的Activity的布局中添加获取SharedPreferences文件中的数据按钮,并在Activity中添加添加如下方法

findViewById(R.id.getSharePreferences).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                SharedPreferences sharedPreferences = getSharedPreferences("ACTIVITY_sharedPreferences",MODE_PRIVATE);
                int age = sharedPreferences.getInt("age",10);
                String name = sharedPreferences.getString("name","");
                boolean is_man = sharedPreferences.getBoolean("is_man",false);
                String address = sharedPreferences.getString("address","noAddress");
                Log.i(TAG, "onClick: "+age);
                Log.i(TAG, "onClick: "+name);
                Log.i(TAG, "onClick: "+is_man);
                Log.i(TAG, "onClick: "+address);
            }
        });

可以看到,我们的ACTIVITY_sharedPreferences文件中只存储了age,name,is_man个参数,对于获取address将会返回默认值“noAddress”。看看效果:

查询Share值

File文件存储

文件存储是android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有的文件都是原封不动的保存到文件当中。

我们使用File文件进行存储,相应的文件会保存在/data/date/<package name>/files目录文件夹下。

下面看看实例:

存储File文件

/**
     * 存储方法
     * @param string
     */
    private void saveDataToFiles(String string){
        FileOutputStream fileOutputStream = null;
        BufferedWriter bufferedWriter = null;
        try {
            fileOutputStream = openFileOutput("data",MODE_PRIVATE);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
            bufferedWriter.write(string);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

解释:通过openFileOutput()获取到FileOutputStream对象,在通过FileOutputStream对象构建一个OutputStreamWriter对象,接着在使用OutputStreamWriter构建BufferWriter对象。调用write()方法将数据进行写入。需要注意的是一定要进行try--catch--finally处理。

Context类提供openFileOutput(String name, int mode)方法,用于将数据存储到指定的文件中,该方法同样接收两个参数。name--->文件名,mode--->操作模式看起来是不是很眼熟

mode MODE_PRIVATE 当指定同样的文件名时,如果存在则覆盖原先的所有内容
mode MODE_APPEND 当指定文件存在,则在后面继续添加内容

获取File文件内容

    /**
     * 获取文件中的数据
     * @return
     */
    private String getDataToFiles(){

        FileInputStream fileInputStream = null;
        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = new StringBuilder();
        try {
            fileInputStream = openFileInput("data");
            bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
            String line = "";
            while((line = bufferedReader.readLine())!=null){
                stringBuilder.append(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
                try {
                    if(bufferedReader != null){
                    bufferedReader.close();}
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return stringBuilder.toString();
    }

通过openFileInput()方法获取FileInputStream对象,借助FileInputStream对象构建InputStreamReader对象,借助InputStreamReader构建一个BufferReader对象,调用读取方法。

BufferReader可以通过读行的方式来对文件的内容进行读取。

Context提供openFileInput(String name)方法,name为你的文件名。

实践时间:

创建一个类FilesActivity并创建相应的布局文件,提供两个按钮,一个TextView,一个进行存储,另一个进行读取并将读取的内容显示出来。

public class FilesActivity extends AppCompatActivity {

    private static final String TAG = "FilesActivity";
    TextView show_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_files_activity);

        show_content = ((TextView) findViewById(R.id.show_content));
        findViewById(R.id.saveDataToFiles).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                saveDataToFiles("我们明明知道空气很毒,却还要呼吸;\n"+"明明知道泡面很脏,却还要充饥;\n"+"明明知道一线大城市房价坐地上涨,却还要削尖脑袋往里挤。\n"+"我们这么努力,只是为了追上那个曾经被寄予厚望的自己。");
            }
        });

        findViewById(R.id.saveDataToFiles).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = getDataToFiles();
                show_content.setText(message);

            }
        });
    }
}

相应的两个方法已经在上面介绍过了,只需要你copy进来就好。

效果:

点击按钮之后:

查看文件会有 一个data文件
data

将文件导出查看数据:

导出文件

点击查看文件内容:

查看文件里面存在的内容

这里之所以没有换行是因为你我们读取的时候是按行读取,并且没有添加换行符,只是拼接在了一起。

SQLite数据存储

android嵌入SQLite数据库,在存储数据方面为开发者提供了很大的便利。需要掌握它的使用,而不仅仅是了解。因为ContentProvider也是 需要用到这一块的内容,并且ContentProvider作为四大主键之一,所以掌握SQLite的存储尤其重要。接下来我们看看SQLite。

创建数据库

数据库的存放目录在:data/data/<package name>/databases/目录下。

android为了使开发者更加方便的管理数据库,提供SQLiteOpenHelper帮助类,借助这个类就可以对数据库进行创建和升级。那先说说SQLiteOpenHelper类。

SQLiteOpenHelpter是一个抽象类,所以我们需要使用它必须定义自己的帮助类并继承SQLiteOpenHelper,实现里面的抽象方法onCreate()和onUpgrade()。

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    private static final String TAG = "MySQLiteOpenHelper";

    /**
     *
     * @param context
     * @param name        数据库名
     * @param factory     允许我们在查询的时候返回一个自定义的Cursor,一般传null
     * @param version     数据库版本号,用于对数据库升级操作
     */
    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        Log.i(TAG, "MySQLiteOpenHelper: ");
    }

    /**
     * 创建数据库
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {

        Log.i(TAG, "MySQLiteOpenHelper: ");
        Toast.makeText(mcontext,"Create database success",Toast.LENGTH_SHORT).show();
    }

    /**
     * 升级数据库
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        Log.i(TAG, "MySQLiteOpenHelper: ");
    }


    /**
     * 创建或者打开一个现有数据库,并返回可对数据库进行读写操作的对象,当数据库不可写入的时候,出现异常
     * @return
     */
    @Override
    public SQLiteDatabase getWritableDatabase() {
        Log.i(TAG, "MySQLiteOpenHelper: ");
        return super.getWritableDatabase();
    }

    /**
     * 创建或者打开一个现有数据库,并返回可对数据库进行读写操作的对象,当数据库不可写入的时候,以只读的方式打开数据库
     * @return
     */
    @Override
    public SQLiteDatabase getReadableDatabase() {
        Log.i(TAG, "MySQLiteOpenHelper: ");
        return super.getReadableDatabase();
    }
}

上述代码是创建一个数据库帮助类的基本操作,下面解释:

onCreate()初次创建数据库的时候被调用到
onUpgrade()数据库进行升级的时候调用到
getReadableDatabase()getWritableDatabase()方法都可以创建或打开一个现有数据库,(如果数据库已经存在,则直接打卡;如果不存在,则进行创建)并返回一个可操作数据库的SQLiteDatabase对象。两者的不同点在于当数据库不可写入的时候(磁盘空间已满),getReadableDatabase()以只读的方式打开数据库,而getWritableDatabase()则会出现异常。

MySQLiteOpenHelper是重写的构造方法,参数解释已经在上面进行了说明。

以上是创建数据库帮助类需要了解的内容。

实践时间:

1.我们要创建一个数据库。新建类MySOLiteActivity然后书写创建数据库的方法

public class MySOLiteActivity extends AppCompatActivity {

    private static final String TAG = "MySOLiteActivity";
    MySQLiteOpenHelper mySQLiteOpenHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_solite);
        findViewById(R.id.createDatabase).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mySQLiteOpenHelper = new MySQLiteOpenHelper(MySOLiteActivity.this,"personInfo.db",null,1);
                mySQLiteOpenHelper.getReadableDatabase();
            }
        });
}

首先实例化数据库帮助类MySQLiteOpenHelper

mySQLiteOpenHelper = new MySQLiteOpenHelper(MySOLiteActivity.this,"personInfo.db",null,1);

这个方法实例化的意思是:我们要创建一个名为personInfo的数据库,版本号为1

之后执行

mySQLiteOpenHelper.getReadableDatabase();

方法,就开始创建数据库,此时我们的辅助类MySQLiteOpenHelper开始工作,因为我们是首次创建数据库,所以执行onCreate()里面的内容。

看看打印数据:

创建数据库

2.创建数据库之后,我们需要建表来存储相应的数据,所以这里会使用到建表的SQL语句。

create table Person (id integer primary key autoincrement,name text,age integer,sex text)

这是一个创建一张表的SQL语法,意思是创建一张Person表,id为唯一键值并自动增长,字符串类型的name,整型的age,以及字符串类型的sex。

看看当数据库建立之后的文件:

创建数据库

两个文件,personInfo.db-journal是自动生成文件,所以可以不用理会。

既然说的是SQL语句,如果你对SQL的一些增删改查(CRUD)语法不太清楚,还请麻烦去查查。

我们创建了一张Person表,但是在这种情况下根本看不到?那么该如何知道自己的表是否创建成功,那么android提供另外一种查看方式

那么以这种方式只能看到数据库,如何看到里面的表呢?android提供另外一种方法:

查看数据库内容

android提供查看数据库的调试工具:adb,它放在sdk的platform-tools目录下,需要配置环境变量。

在环境变量 path下添加你的platform-tools的地址。

windows系统下:打开cmd

1 > 输入命令 adb shell 进入设备控制台

进入android adb

2 > 执行命令 ls 查看该设备下的所有文件

ls

还记得我们的数据库存在哪里吗?

data/data/<package name>/databases/

3 > 执行cd data/data/<package name>/databases/命令进入该文件夹
进入数据库

4 > 执行 ls 看看内容

数据库

其实上面叙述的这些我们也可以通过界面化查看。但是现在我们要查看我们创建的数据表,借助sqlite命令来打开数据库。

这个时候我们可以看到前面的#改变为sqlite,标明我们可以使用sql语法来进行查询了。

5 > 执行 sqlite3 <你要查看的数据库名> 命令

sqlite3 personInfo.db

SQLite3

6 > 执行 .table 查看数据表

数据表

看看,我们目前只有一张Person表。

7 > 命令 .schema 命令可以查看建表语句

建表语句


升级数据库

但是onUpgrade()方法什么时候执行呢?这个是进行更新数据库的方法,当你的Version版本改变的时候,这个方法会被触发并执行。

看看下面代码:

public static final String CREATE_CATEGORY = "create table category (id integer primary key autoincrement"+
            "teacher text,grade text)";
@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        Log.i(TAG, "MySQLiteOpenHelper: ");

        db.execSQL(CREATE_CATEGORY);

    }

在onUpgrade()方法在创建一张category 表,调用语句修改为

mySQLiteOpenHelper = new MySQLiteOpenHelper(MySOLiteActivity.this,"personInfo.db",null,2);
mySQLiteOpenHelper.getReadableDatabase();

将数据库版本进行升级,这样的情况下执行onUpgrade()方法。

升级数据库

此时onUpgrade()方法进行执行,我们现在来看看数据表:

数据表

增查改删(CRUD)

对于android数据库操作来讲,android提供API,同时支持纯SQL语法,也提供带占位符的SQL语句。

Create(增加)

android提供的API调用

SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
                //开始添加数据
                contentValues.put("name","wangxiaobo");
                contentValues.put("age",25);
                contentValues.put("sex","man");
                sqLiteDatabase.insert("Person",null,contentValues);
                contentValues.clear();
                //添加第二组数据
                contentValues.put("name","wedfrend");
                contentValues.put("age",24);
                contentValues.put("sex","man");
                sqLiteDatabase.insert("Person",null,contentValues);
contentValues.clear();

纯SQL语法:

sqLiteDatabase.execSQL("insert into Person(name,age,sex) values(\"wedfrend xiaobo\",21,\"man\")");

带占位符的SQL语法:

sqLiteDatabase.execSQL("insert into Person(name,age,sex) values(?,?,?)",new String[]{"wedfrend wang","22","man"});                

查看数据表:
查询数据表内容

//下面的内容只提供android API调用语法
Update(修改)

SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("age",24);
sqLiteDatabase.update("Person",contentValues,"name=?",new String[]{"wangxiaobo"});

再次查询数据库,看是不是将name=wangxiaobo的age更新为24

更新数据

Delete(删除)

SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();
sqLiteDatabase.delete("Person","age > ?",new String[]{"23"});

再次查询数据库,看是否将age大于23的数据全部清除

删除

Retrieve(查询)

SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor = sqLiteDatabase.query("Person",null,null,null,null,null,null);
if(cursor.moveToFirst()){
   do {
        //遍历所有的数据处理
        String name = cursor.getString(cursor.getColumnIndex("name"));
        int age = cursor.getInt(cursor.getColumnIndex("age"));
        String sex = cursor.getString(cursor.getColumnIndex("sex"));
         Log.i(TAG, "onClick: name"+name);
         Log.i(TAG, "onClick: age"+age);
         Log.i(TAG, "onClick: sex"+sex);
        }while(cursor.moveToNext());
}

但我们执行完上面的所有步骤之后,在调用查询语句,此时数据库Person表中只存在两个数据,查询的输出结果如下:

查询语句


至此我们已经将android的存储知识整理完成,难点并没有什么,只是涉及的方法较多,细心的整理以后自己的思路也是更加的清晰了。

相信大家都使用过第三方的插件吧!生活在互联网时代,我们是一批幸运的人,有很多的前辈整理综合的功能真的让我们事半功倍,而且更加否和我们的习惯。

接下来我要说一个第三方开源库 ——LitePal

LitePal数据库开发神器

LitePal是一款开源的android数据库框架,它采用的是(ORM)关系映射的模式,将我们原始的数据库进行封装,否和android的开发思想。并提供增删改查,数据库的创建和升级的功能。完全满足你的所有要求,LitePal的使用文档地址:
https://github.com/LitePalFramework/LitePal

我也是查询文档和网上的资料,整理一下,有误请指正。(个人更建议直接查看官方文档,英文版的读一下还是有好处的)

1.配置LitePal

使用第三方开源库,需要进行库依赖操作

compile 'org.litepal.android:core:1.4.1'

这个版本是官网目前最新的。

引用依赖包之后,我们还需要配置一下 LitePalApplication,这里有两种方法

方法1:在manifest.xml中进行设置:

<application
        android:name="org.litepal.LitePalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        ···

</application>

添加

android:name="org.litepal.LitePalApplication"

才能使得LitePal的所有功能正常工作。

方法2:在实际的项目中,我们需要对Application进行一些个性化的设置,甚至配置一些第三方插件的前提条件,所以一般情况下我们都会自己定义一个Application。

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        LitePal.initialize(this);

    }
}

并重写onCreate()方法,加入

LitePal.initialize(this);

跟在manifest.xml中设置是一样的效果,之后需要在manifest.xml中将自己定义的MyApplication进行声明:

android:name="wedfrend.wang.privateproject.base.MyApplication"

这样的引用在后面其他的开源库需要配置的时候只要在自定义的类中进行使用就好,相对而言,我更加推荐这种方式。

对于Application的讲解后面我会进行整理,目前只需要知道Application是每一个程序都存在的,而且是程序第一个加载的类。

2.需要新建一个 litepal.xml文件。右键app/src/main目录–>New–>Directory,创建一个assets目录。

3.在该目录下创建一个litepal.xml文件,基本内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<litepal>

    <!--数据库的名称-->
    <dbname value="LitePalDatabase"></dbname>

    <!--数据库的版本-->
    <version value="1"></version>

    <!--用于指定所有的映射模型-->
    <list>
        <mapping ></mapping>

    </list>

</litepal>

基本配置

4.创建表:在litepal中,创建表格与我们平时创建的类是一样的。

如下:我们要创建一个Book表,创建类

public class Book extends DataSupport {

    private String name;

    private String author;

    private float prices;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public float getPrices() {
        return prices;
    }

    public void setPrices(float prices) {
        this.prices = prices;
    }
}

这个很熟悉吧,但是要注意的是:类必须继承DataSupport,这样该类才能够正常使用LitePal提供的方法。在litepal还添加了注解的功能,这部分的内容请查看官方的文档。

5.将Book类添加到映射列表litepal中

 <list>
        <mapping class="wedfrend.wang.privateproject.table.Book"></mapping>

</list>

6.至此数据库的基本配置就算完成了,进行创建数据库和相应的表格,只需在你的代码里调用

Connector.getDatabase();

便可以完成数据库的创建。


实例部分

创建数据库

在你的代码中新增一个控件并书写点击方法,进行数据库的创建,当然这种方式创建的数据库的存储目录依然在data/data/<package name>/databases目录下:

findViewById(R.id.LitePalCreateDatabase).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Connector.getDatabase();
            }
        });

查看数据库:
LitePal

此时数据库创建,我们在看看Book表是否存在

查看创建的表

表存在,但是表明为 book 小写,并不是我们的类名,所以这里就要说明一下,LitePal创建数据库的语法如下

CREATE TABLE book(
    id integer primary key autoincrement,
    author text,
    name text,
    price real
);

我们看一下:

查看建表语句

增加数据(save data)

新增一个点击增加数据按钮,并添加以下代码,实例化类,添加数据,最后调用save()方法将数据存储在数据库中。

findViewById(R.id.LitePalAddDatabase).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setName("一个巨人的陨落");
                book.setPrices(84.3f);
                book.setAuthor("Ken Follett");
                //save()方法是继承DataSupport里面的方法
                book.save();

                Book book2 = new Book();
                book2.setName("阿弥陀佛么么哒");
                book2.setPrices(38.0f);
                book2.setAuthor("大冰");
                book2.save();

            }
        });

查看数据库:点击下载你所需要的可视化版本工具,之后在文件管理中导出数据库,便可以查看

数据库查看

更新数据(Update data)

提供三种方式:

1.直接使用find()方法,然后使用save()方法

findViewById(R.id.LitePalUpdateDatabase).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //参数1,查询类,参数2表示id
                Book book = DataSupport.find(Book.class,1);
                Log.i(TAG, "onClick: ------------"+book.getName());
                Log.i(TAG, "onClick: ------------"+book.getAuthor());
                Log.i(TAG, "onClick: ------------"+book.getPrices());
                book.setName("wedfrend");
                book.save();

            }
        });

上述代码将Book数据表中的第一行数据进行修改,将姓名改为“wedfrend”。查看结果:

查询

将第一条数据的姓名wedfrend

修改

2.使用update(long id)方法进行数据的更新。

Book updata_book = new Book();
updata_book.setPrices(0.0f);
updata_book.update(1);

将Book数据表的第一条数据进行修改,价格修改为0.0,查看 结果:

3.使用updateAll(String… conditions)方法更新数据

 Book upDateBook = new Book();
 upDateBook.setAuthor("wedfrend");
 upDateBook.updateAll("name=?","阿弥陀佛么么哒");

将Book数据表进行修改,讲作者改为“wedfrend”当name等于“阿弥陀佛么么哒”的时候,查看数据:

修改书名的作者

删除数据(Delete data)

删除数据提供两种方法:

方法1:

DataSupport.delete(Book.class,2);

方法2:

DataSupport.deleteAll(Book.class,"prices<?","3");

看看数据库的情况:

这里写图片描述

查询数据

提供的方法很灵活,完全符合SQLite语句,所以下面整理一下

//提供方法完全符合SQLite语法

List<Book> bookList = DataSupport.findAll(Book.class);


Book firstBook = DataSupport.find(Book.class,1);

Book FirstBook = DataSupport.findFirst(Book.class);


Book lastBook = DataSupport.findLast(Book.class);

//最后可以使用结合的语句

List<Book> books = DataSupport.select("name","author","prices").where("prices>?","30").order("id").limit(3).offset(0).find(Book.class);

以其中最简单的一种进行查询:

 List<Book> bookList = DataSupport.findAll(Book.class);


                for (Book book:bookList
                     ) {
                    Log.i(TAG, "onClick: book"+book.getName());
                    Log.i(TAG, "onClick: book"+book.getPrices());
                    Log.i(TAG, "onClick: book"+book.getAuthor());
                }

查看结果:
遍历结果

下面说一些附加的内容,进阶版

在查看LitePal的开发文档中,除了这种默认的数据库,就是事先已经在配置文件中写好的以外,还可以动态的创建。

Multiple databases

If your app needs multiple databases, LitePal support it completely. You can create as many databases as you want at runtime. For example:

LitePalDB litePalDB = new LitePalDB("demo2", 1);
litePalDB.addClassName(Singer.class.getName());
litePalDB.addClassName(Album.class.getName());
litePalDB.addClassName(Song.class.getName());
LitePal.use(litePalDB);

重新创建一个初始类型的数据库

LitePalDB litePalDB = LitePalDB.fromDefault("newdb");
LitePal.use(litePalDB);

切换默认的数据库

LitePal.useDefault();

删除数据库

LitePal.deleteDatabase("newdb");

关于默认值:

当你想把一个字段的值更改为默认值时,是不可以使用setXxx()方法的,因为在java中,任何一种数据类型都有默认值,比如:

int ---->0
boolean ---->false
String ---->null

所以要将一个数据更改为默认值,需要进行

Book book = new Book();
book.setToDefault("name");
book.updateAll();

这种方式。

结语:也许数据库在我们实际的开发中很少用到,但是理解并掌握是必须的,在未来也许你能用到呢?


好了,关于android数据的存储方式目前就这么多,相应的代码还是一样,上传至个人Github
https://github.com/wedfrendwang/PrivateProject.git,分支为database,学习愉快!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值