第6章 数据存储

本系列学习笔记第6章

前言

打算把android基本知识点写一个系列,旨在把android基础书,例如《Android 第一行代码 第2版》、《爱上android》、《疯狂android讲义》等书的一些知识点记录一下,会持续更新内容,为了方便自己复习,也希望可以帮助到大家!

目录

1、持久化技术简介


2、文件存储
    2.1 手机内存存储
        2.1.1 将数据存储到文件中
        2.1.2 从文件中读取数据
    2.2 SD卡存储
        2.2.1 检测SD卡是否可用
        2.2.2 共有和私有的文件路径
        2.2.3 SD卡存储参考工具类
        2.2.4 查询剩余空间

    
3、SharedPreferences存储
    3.1 将数据存储到SharedPreferences中
    3.2 从SharedPreferences中读取数据
    3.3 实现记住密码功能


4、SQLite存储
    4.1 创建数据库
    4.2 升级数据库
    4.3 添加数据
    4.4 更新数据
    4.5 删除数据
    4.6 查询数据
    4.7 使用SQL操作数据库
    4.8 对事务的认识和基本使用


5、使用LitePal操作数据库
    5.1 LitePal简介
    5.2 配置LitePal
    5.3 创建和升级数据库
    5.4 使用LitePal添加数据
    5.5 使用LitePal更新数据
    5.6 使用LitePal删除数据
    5.7 使用LitePal查询数据

1、持久化技术简介

数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会扔失。保存在内存中的数据是处于瞬时状态的,而保存在存储设备中的数据是处于持久状态的,持久化技术则提供了一种机制可以让数据在瞬时状态和持久化状态之间进行转换。

android中的数据存储主要分为5大部分:
1) 文件存储
2) SharedPreference存储
3)数据库存储
4)ContentProvider存储
5)网络存储

2、文件存储

文本存储是android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有的数据都是原封不动的保存到文件当中,因而它比较适用于存储一下比较简单的文本数据或二进制数据。

2.1 手机内存存储

常用的api如下:


image.png
2.1.1 将数据存储到文件中

activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.datatest.MainActivity">

    <EditText
        android:id="@+id/et_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       android:hint="请输入"
       />

</LinearLayout>

MainActivity.java文件

public class MainActivity extends AppCompatActivity {

    private EditText etSave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etSave = (EditText) findViewById(R.id.et_save);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText = etSave.getText().toString();
        save(inputText);
    }

    private void save(String data){
         FileOutputStream fos = null;
         BufferedWriter writer = null;
        try {

            //写入file目录
            fos = openFileOutput("data", Context.MODE_PRIVATE);

            //写入缓存目录
//            fos = new FileOutputStream(new File(getCacheDir(),"cache.txt"));
            writer = new BufferedWriter(new OutputStreamWriter(fos));
            writer.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (writer != null){
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }

        }
    }
}

image.png
image.png
image.png

image.png
2.1.2 从文件中读取数据
public class MainActivity extends AppCompatActivity {

    private EditText etSave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etSave = (EditText) findViewById(R.id.et_save);

        String inputText = load();
        if (!TextUtils.isEmpty(inputText)){
            etSave.setText(inputText);
            etSave.setSelection(inputText.length());
            Toast.makeText(this, "数据读取成功", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText = etSave.getText().toString();
        save(inputText);
    }

    private void save(String data){
         FileOutputStream fos = null;
         BufferedWriter writer = null;
        try {

            //写入file目录
            fos = openFileOutput("data", Context.MODE_PRIVATE);

            //写入缓存目录
//            fos = new FileOutputStream(new File(getCacheDir(),"cache.txt"));
            writer = new BufferedWriter(new OutputStreamWriter(fos));
            writer.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (writer != null){
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }

        }
    }

    private String load(){
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();
        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while((line = reader.readLine()) != null){
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (reader != null){
                try {
                    reader.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}
image.png
2.2 SD卡存储
image.png
image.png
2.2.1 检测SD卡是否可用

    /**
     * 检查SD卡是否可写
     * @return
     */
    public static boolean isExternalStorageWritable(){
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)){
            return true;
        }

        return false;
    }

    /**
     * 检查SD卡是否可读
     * @return
     */
    public static boolean isExternalStorageReadable(){
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
            return true;
        }

        return false;
    }
}
2.2.2 共有和私有的文件路径
image.png

image.png
    private File getAlbumStorageDir(String albumName){
        //获取保存图片的文件夹
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),albumName);

        if (!file.mkdir()){
            Log.d(TAG,"文件夹不存在");

            //如果文件不存在的话,就创建文件
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return file;

    }
image.png

image.png
    private File getAlbumStorageDir(Context context,String albumName){
        //获取保存图片的文件夹
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),albumName);

        if (!file.mkdir()){
            Log.d(TAG,"文件夹不存在");

            //如果文件不存在的话,就创建文件
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return file;

    }
image.png
image.png
    compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'
    compile 'io.reactivex:rxjava:1.1.6' //需要引入Rxjava
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.datatest.MainActivity">

    <EditText
        android:id="@+id/et_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       android:hint="请输入"
       />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存到SD卡"
        android:onClick="saveTo"
        />

</LinearLayout>

public class MainActivity extends AppCompatActivity {

    private EditText etSave;
    private PrintStream printStream;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etSave = (EditText) findViewById(R.id.et_save);

  
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
     
    }

   

    public void saveTo(View view){
        if (ExternalStorageUtils.isExternalStorageWritable()){
            final String content = etSave.getText().toString();
            Toast.makeText(this, "SD卡可用", Toast.LENGTH_SHORT).show();

            RxPermissions.getInstance(this)

                    //申请权限
                    .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(new Action1<Boolean>() {
                        @Override
                        public void call(Boolean aBoolean) {
                            //权限如果通过了,就保存到SD卡中
                            if (aBoolean){
                                saveFileToSDCard(content);
                            }
                        }
                    });
        }
    }

    /**
     * 保存内容的SD卡中
     */
    private void saveFileToSDCard(String content){
        File file = new File(Environment.getExternalStorageDirectory(),"cache.text");
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            printStream = new PrintStream(fos);
            printStream.print(content);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (printStream != null){
                    printStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
2.2.3 SD卡存储参考工具类
image.png
public class FileUtils {
    // 缓存的文件
    public static final String CACHE_DIR = "cache";
    // 保存图片的路径
    public static final String ICON_DIR = "icon";
    // 下载文件的路径
    public static final String DOWNLOAD_DIR = "download";
    // 保存到SD卡的根目录
    private static final String ROOT_DIR = "likeDev";

    public static String getCacheDir(Context context) {
        return getDir(context,CACHE_DIR);
    }

    public static String getIconDir(Context context) {
        return getDir(context,ICON_DIR);
    }

    public static String getDownloadDir(Context context) {
        return getDir(context,DOWNLOAD_DIR);
    }


    public static String getDir(Context context,String name) {
        StringBuilder sb = new StringBuilder();
        if (isSDCardAvailable()) {
            sb.append(getExternalStoragePath());
        } else {
            sb.append(getCachePath(context));
        }
        sb.append(name);
        sb.append(File.separator);
        String path = sb.toString();
        if (createDirs(path)) {
            return path;
        } else {
            return null;
        }
    }
    // 返回SD卡路径
    private static String getExternalStoragePath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath() +
                File.separator +
                ROOT_DIR +
                File.separator;
    }

    /**
     * 判断sd卡是否挂载
     */
    public static boolean isSDCardAvailable() {
        return Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState());
    }
    // 创建文件夹
    private static boolean createDirs(String path) {
        File file = new File(path);
        return !(!file.exists() || !file.isDirectory()) || file.mkdirs();
    }

    private static String getCachePath(Context context) {
        File f = context.getCacheDir();
        return f.getAbsolutePath() + File.separator;
    }
}
2.2.4 查询剩余空间

getFreeSpace():获取剩余空间
getTotalSpace() : 获取总空间

        //获取剩余空间
        long freeSpace = Environment.getExternalStorageDirectory().getFreeSpace();
//        android.text.format.Formatter
        String formatFileSize = Formatter.formatFileSize(this, freeSpace);

3、SharedPreferences存储

不同于文件的存储方式,SharedPreferences是用键值对的方式存储数据

3.1 将数据存储到SharedPreferences中

Android中提供了3种方式来获取SharedPreferences()方法
1)Context类中的getSharedPreferences(String name, int mode)方法
第一个参数是:指定的SharePreferences文件的名称
第二个参数是:用于指定操作模式,目前只有MODE_PRIVATE

2)Activity类中的getPreferences(int mode)方法
参数只有操作模式:MODE_PRIVATE

3)PreferenceManager.getDefaultSharedPreferences(Context context)

使用SharedPreferences文件存储数据的步骤:
1)调用SharedPreferences对象的edit()方法来获取SharedPreferences,Editor对象
2)向SharedPreferences,Editor对象中添加数据,例如添加一个String类型的数据,就使用PutString()
3)apply()方法提交(线程不安全,效率高)或者commit()方法提交(线程安全,效率低)

基本使用如下:

        SharedPreferences preferences = getSharedPreferences("data", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("name","zlc");
        editor.putInt("age",28);
        editor.putBoolean("married",false);
        editor.apply();

3.2 从SharedPreferences中读取数据
        SharedPreferences sp = getSharedPreferences("data", MODE_PRIVATE);
        String name = sp.getString("name", "");
        int age = sp.getInt("age", 0);
        boolean married = sp.getBoolean("married", false);
3.3 实现记住密码功能
public class ActivityCollector {

    public static List<Activity> activities = new ArrayList<>();

    public static void addActivity(Activity activity) {
        activities.add(activity);
    }

    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }

    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
    }

}

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="18sp"
            android:text="Account:" />

        <EditText
            android:id="@+id/account"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="18sp"
            android:text="Password:" />

        <EditText
            android:id="@+id/password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:inputType="textPassword" />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <CheckBox
            android:id="@+id/remember_pass"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="Remember password" />

    </LinearLayout>

    <Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Login" />

</LinearLayout>

public class LoginActivity extends BaseActivity {

    private SharedPreferences pref;

    private SharedPreferences.Editor editor;

    private EditText accountEdit;

    private EditText passwordEdit;

    private Button login;

    private CheckBox rememberPass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        pref = PreferenceManager.getDefaultSharedPreferences(this);
        accountEdit = (EditText) findViewById(R.id.account);
        passwordEdit = (EditText) findViewById(R.id.password);
        rememberPass = (CheckBox) findViewById(R.id.remember_pass);
        login = (Button) findViewById(R.id.login);
        boolean isRemember = pref.getBoolean("remember_password", false);
        if (isRemember) {
            // 将账号和密码都设置到文本框中
            String account = pref.getString("account", "");
            String password = pref.getString("password", "");
            accountEdit.setText(account);
            passwordEdit.setText(password);
            rememberPass.setChecked(true);
        }
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String account = accountEdit.getText().toString();
                String password = passwordEdit.getText().toString();
                // 如果账号是admin且密码是123456,就认为登录成功
                if (account.equals("admin") && password.equals("123456")) {
                    editor = pref.edit();
                    if (rememberPass.isChecked()) { // 检查复选框是否被选中
                        editor.putBoolean("remember_password", true);
                        editor.putString("account", account);
                        editor.putString("password", password);
                    } else {
                        editor.clear();
                    }
                    editor.apply();
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(LoginActivity.this, "account or password is invalid",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

}

4、SQLite存储

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

4.1 创建数据库

activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.mydatabasehelper.MainActivity">

    <Button
        android:id="@+id/btn_create"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="创建数据库"
        />

</LinearLayout>

MyDatabaseHelper.java文件

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String CREATE_BOOK = "create table Book ("
            +"id integer primary key autoincrement, "
            +"author text, "
            +"price real, "
            +"pages integer, "
            +"name text)"
            ;

    private Context mContext;

    public MyDatabaseHelper(Context context, String name, 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, "数据库创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }
}

MainActivity .java文件

public class MainActivity extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    private Button btnCreate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnCreate = (Button) findViewById(R.id.btn_create);
        dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
        btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dbHelper.getWritableDatabase();
            }
        });
    }
}

image.png

按照如下的adb指令即可以查看数据库是否创建成功


image.png
image.png

或者使用AndroidStudio也可以执行查询的命令,参考例子如下:


image.png
image.png
4.2 升级数据库

MyDatabaseHelper.java文件

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String CREATE_BOOK = "create table Book ("
            +"id integer primary key autoincrement, "
            +"author text, "
            +"price real, "
            +"pages integer, "
            +"name text)"
            ;

    private static final String CREATE_CATEGORY = "create table Category ("
            +"id integer primary key autoincrement, "
            +"category_name text, "
            +"category_code integer)"
            ;

    private Context mContext;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "数据库创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }
}
public class MainActivity extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    private Button btnCreate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnCreate = (Button) findViewById(R.id.btn_create);
        dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
        btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dbHelper.getWritableDatabase();
            }
        });
    }
}
image.png
4.3 添加数据

activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.mydatabasehelper.MainActivity">

    <Button
        android:id="@+id/btn_create"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="创建数据库"
        />

    <Button
        android:id="@+id/btn_add"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="添加数据"
        />

</LinearLayout>

MyDatabaseHelper .java文件

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String CREATE_BOOK = "create table Book ("
            +"id integer primary key autoincrement, "
            +"author text, "
            +"price real, "
            +"pages integer, "
            +"name text)"
            ;

    private static final String CREATE_CATEGORY = "create table Category ("
            +"id integer primary key autoincrement, "
            +"category_name text, "
            +"category_code integer)"
            ;

    private Context mContext;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "数据库创建成功!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }
}

MainActivity.java文件

public class MainActivity extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    private Button btnCreate;
    private Button btnAdd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnCreate = (Button) findViewById(R.id.btn_create);
        btnAdd = (Button) findViewById(R.id.btn_add);
        dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
        btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dbHelper.getWritableDatabase();
            }
        });
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("name","第一行代码");
                values.put("author","guolin");
                values.put("pages",500);
                values.put("price",58.0);
                db.insert("Book",null,values);

                values.clear();
                values.put("name","爱上android");
                values.put("author","ylinlin");
                values.put("pages",300);
                values.put("price",48.0);
                db.insert("Book",null,values);
            }
        });
    }
}
image.png

添加数据的另外一种写法例子,直接使用SQL的语句,如下图所示:


image.png
image.png
4.4 更新数据
//        select * from Book;
        btnUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("price",35.0);
                db.update("Book",values,"name = ?",new String[]{"第一行代码"});
            }
        });

修改数据的另外一种写法例子,直接使用SQL的语句,如下图所示:


image.png
4.5 删除数据
        btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                db.delete("Book","pages > ?",new String[]{"400"});
            }
        });
image.png
4.6 查询数据
btnQuery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                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(TAG,"name=========>"+name);
                        Log.d(TAG,"author=========>"+author);
                        Log.d(TAG,"pages=========>"+pages);
                        Log.d(TAG,"price=========>"+price);
                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        });

查询数据的另外一种写法例子,直接使用SQL的语句,如下图所示:


image.png

image.png

image.png

image.png

image.png
4.7 使用SQL操作数据库

对应SQL语句很熟悉的开发人员,上面的增删改查操作可以用SQL语句来代替,具体用法参考于:
http://www.w3school.com.cn/sql/sql_select.asp

4.8 对事务的认识和基本使用
image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

5、使用LitePal操作数据库

5.1 LitePal简介

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

5.2 配置LitePal
image.png
image.png

image.png
image.png
5.3 创建和升级数据库

Book.java 实体类

public class Book extends DataSupport {

    private int id;

    private String author;

    private double price;

    private int pages;

    private String name;

    private String press;

    public int getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

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

    public double getPrice() {
        return price;
    }

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

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public String getName() {
        return name;
    }

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

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

}
        btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LitePal.getDatabase();
            }
        });
image.png

升级数据库

public class Category extends DataSupport{

    private int id;

    private String categoryName;

    private int categoryCode;

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

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public void setCategoryCode(int categoryCode) {
        this.categoryCode = categoryCode;
    }

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

    <dbname value = "BookStore"></dbname>

    <version value = "2"></version>

    <list>
        <mapping class="com.example.litepaltest.Book" />
        <mapping class="com.example.litepaltest.Category" />
    </list>

</litepal>
image.png
5.4 使用LitePal添加数据
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Book book = new Book();
                book.setName("The Da Vinci Code");
                book.setAuthor("Dan Brown");
                book.setPages(454);
                book.setPrice(16.96);
                book.setPress("Unknow");
                book.save();
            }
        });
5.5 使用LitePal更新数据
        btnUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setPrice(14.95);
                book.setPress("Anchor");
                book.updateAll("name = ? and author = ?", "The Da Vinci Code", "Dan Brown");
            }
        });
5.6 使用LitePal删除数据
        btnDel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DataSupport.deleteAll(Book.class,"price < ?","15");
            }
        });
5.7 使用LitePal查询数据
        btnQuery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                List<Book> books = DataSupport.findAll(Book.class);
            }
        });

更多关于Litepal的使用方法,请查看github地址:
https://github.com/LitePalFramework/LitePal

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • 坐在理发店的长凳上,不知错过了几批顾客,直到老板娘大喊:“喂,你理发吗?不理赶紧走!”我才抬起头来,换个座位,随意...
    渺若恒沙阅读 112评论 0 1
  • 一段时间以来,感到十分的疲惫,因为晚上睡得太晚。以前基本上十二点一过就能睡觉,现在差不多要到一点多钟才能睡,早上又...
    谁的梦想在路上阅读 257评论 1 1
  • 8月12日早上10点左右,成都力宝大厦23楼打破了往日的宁静,中国首个“低碳云商”福瑞至控股有限公司的大厅迎来了一...
    一生约阅读 341评论 0 0