Android进阶:Android数据库操作—步骤2: SQLite数据库

1. Sqlite 简介


Sqlite 是一种轻量级,零配置的,可嵌入的程序驱动型的二进制文件,同时也是一种 关系型数据库。

SQLite 是一个开源的关系型数据库,实现自包容、零配置、支持 事务的SQL数据库引擎。

其特点是高度便携、使用方便、结构紧凑、 高效、可靠。

鉴于 Sqlite 数据库的这些优点,现在流行的操作系统 Android 和 ios都选择使用 Sqlite 作为数据存储的主要方式。

2. Sqlite 的使用场景


现在的主流移动设备像 Android、iPhone 等都使用 SQLite 作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,

也许就要使用到 SQLite 来存储我们大量的 数据,所以我们就需要掌握移动设备上的 SQLite 开发技巧。

对于 Android 平台来说, 系统内置了丰富的 API 来供开发人员操作 SQLite,我们可以轻松的完成对数据的存 取

Android进阶:Android数据库操作—步骤2: SQLite数据库

Android进阶:Android数据库操作—步骤2: SQLite数据库

Android进阶:Android数据库操作—步骤2: SQLite数据库

数据库建表:  

SQLPro for SQLite for Mac 图形化SQLITE数据库 密码:1cnq

 Android进阶:Android数据库操作—步骤2: SQLite数据库

CREATE TABLE IF NOT EXISTS info_tb (
  id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  name varchar(30) NOT NULL,
  age integer,
  gender var(2) NOT NULL
);

 

DML(数据库操作语言)

添加操作:

INSERT INTO 表名(列1,列2) VALUES (值1,值2)

INSERT INTO 表名 VALUES (值1,值2,值3)

注意事项:

  1. 数据类型要对应
  2. 数据个数要对应
  3. 顺序要对应
  4. 一定要包含所有非空列
  5. 自动增长列 (1.给一个不存在的数据 2.给一个null)
//方式1 指定列(所有非空列)
insert into info_tb(id,name,age,gender)values(null,'张三',15,'男')
//方式2
insert into info_tb(name,age,gender)values('张三',15,'男')
//方式3 不指定列
insert into info_tb values(null,'张三',18,'男')

 

删除:针对记录(行)而言

DELETE FROM 表名 [WHERE <删除条件>]

//1删除所有整张表
delete from info_tb
//2指定条件删除
delete from info_tb where name='张三'

 

修改:

UPDATE 表名 SET 列名1 = 更新值1,列名2=更新值2, ... 列名n=更新值n [WHERE <更新条件>]

//1不指定条件,所有记录受影响,name属性都改成张
update info_tb 
             set name='张'
//2指定条件更新
update info_tb 
             set name='张三'  where age=18

Android进阶:Android数据库操作—步骤2: SQLite数据库

 

查询:产生的是虚拟的结果集,并不是真的把数据取出来给客户端(想拍照一样)

SELECT * FROM 表名

//1不指定条件,查询该表所有记录 *号代表所有列
select*from info_tb
//2查询部分列 select 列名1,列名2 from 表名 不要星号
select  name,age from info_tb 
//3 查询满足某个条件
select  * from info_tb  where name='张三'

手机数据库文件的导入(将这个数据导入到模拟器中)

File Explorer->选中文件夹——>右键upload——>选中上传的文件

 

SQLITE的两个类:

SQLiteOpenHelper(数据库帮助类)

Android平台里一个数据库辅助类,用于创建或打开数据库,并且对数据库的创建和版本进行管理

 

     /**
                 * SQLiteOpenHelper 帮助类打开或创建数据库
                 */
                //参数1:上下文
                //参数2:数据库名称
                // (如果不指定路径默认在内存私有目录 data/data/包名/xx.db)
                // 指定路径,则在指定的路径下
                //参数3:游标 设为null
                //参数4:版本号
                String path="test.db";
                SQLiteOpenHelper helper=new SQLiteOpenHelper(this,path,null,1) {
                    @Override
                    public void onCreate(SQLiteDatabase db) {
                        //创建
                        Toast.makeText(MainActivity.this,"数据库创建",Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                        //升级
                        Toast.makeText(MainActivity.this,"数据库升级",Toast.LENGTH_SHORT).show();
                    }
                };
                //用于获取数据库对象
                //1如果数据库存在则打开
                //2如果数据不存在则调用oncreate方法创建数据库再打开数据库
                //3d数据库存在,版本号升高了,则调用版本升级方法
                helper.getReadableDatabase();//返回值是SQLiteDataBase实例

Sqlite 数据库中获取数据库对象的两个方法:

  1.  获取数据库实例时使用了 getWritableDatabase()方法。

  2.  在 getReadableDatabase()方法中,首先判断是否已存在数据库实例并且是打

    开状态,如果是,则直接返回该实例,否则试图获取一个可读写模式的数据库实 例,如果遇到磁盘空间已满等情况获取失败的话,再以只读模式打开数据库,获 取数据库实例并返回,然后为数据库对象赋值为最新打开的数据库实例。

  3.  getReadableDatabase()一般都会返回和 getWritableDatabase()一样的数据 库实例,所以我们在 DBManager 构造方法中使用 getWritableDatabase()获取 整个应用所使用的数据库实例是可行的

  4. 当 调 用 SQLiteOpenHelper 的 getWritableDatabase() 或 者getReadableDatabase()方法获取用于操作数据库的 SQLiteDatabase 实例的时候,如果数据库不存在,Android 系统会自动生成一个数据库,接着调用onCreate()方法。

  5. onCreate()方法在初次生成数据库时才会被调用,在 onCreate()方法里可以生成 数据库表结构及添加一些应用使用到的初始化数据。

  6.  onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时 才需改变版本号,而数据库的版本是由程序员控制的。

SQLiteDatabase(数据库对象类)

用于管理和操作SQLite数据库,几乎所有的数据库操作, 最终都将由这个类完成。

 

SQLiteDatabase对象的操作(一)

  • rawQuery():查询
  • execSQL():添加、删除、修改、创建

添加操作:

                //用于获取数据库对象
                //1如果数据库存在则打开
                //2如果数据不存在则调用oncreate方法创建数据库再打开数据库
                //3d数据库存在,版本号升高了,则调用版本升级方法
                SQLiteDatabase db = helper.getReadableDatabase();
                //db.rawQuery(); 查询操作 select *from 表名
                //db.execSQL(); 添加、删除、修改、创建表
                //获取编辑框的内容
                String nameStr=name.getText().toString();
                String ageStr=name.getText().toString();
                //添加方式1
//                String sql="insert into info_table(name,age,gender) values('"+nameStr+","+ageStr+",'"+genderStr+"')";
//                db.execSQL(sql);
                //添加方式2
                String sql2="insert into info_table(name,age,gender) values(?,?,?)";
                db.execSQL(sql2,new String[]{nameStr,ageStr,genderStr});

查询操作: 

 //查询
                //select*from 表名 where _id=?
                //查询所有数据
                String sql="select*from info_tb";
                //通过判断是否输入编号来进行查询区别
                String numStr=number.getText().toString();
                if(!numStr.equals("")){
                    sql+=" where _id="+numStr;
                }
                Log.e("TAG",sql);
                //查询结果
                Cursor cursor=db.rawQuery(sql,null);
                //参数1:上下文 参数2:资源布局 参数3:cursor 参数4:属性名 参数5:显示控件id的数组 参数6:flag
                SimpleCursorAdapter cursorAdapter=new SimpleCursorAdapter(
                        this,
                        R.layout.item,
                        cursor,
                        new  String[]{"_id","name","age","gender"},
                        new int[]{R.id.info_id,R.id.info_name,R.id.info_age,R.id.info_gender},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
                );
                list.setAdapter(cursorAdapter);
                break;

_id中加入下划线是方便SimpleCursorAdapter的使用 

Android进阶:Android数据库操作—步骤2: SQLite数据库

删除操作:

  //删除
                String delete_sql="delete from info_tb where _id=?";
                db.execSQL(delete_sql,new String[]{numStr});

修改操作:

         String update_sql="update info_tb set name=?,age=?,gender=?  where _id=?";
                db.execSQL(update_sql,new String[]{nameStr,ageStr,genderStr,numStr});

完整代码:(代码比较冗余)

public class MainActivity extends AppCompatActivity {

    private EditText name;
    private EditText age;
    private EditText number;
    private Button insert;
    private Button select;
    private Button delect;
    private Button update;
    private RadioGroup gendergp;
    private String genderStr = "男";
    private SQLiteDatabase db;
    private ListView list;
    private RadioButton gender_male;

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

    }

    public void init() {
        /**
         * SQLiteOpenHelper 帮助类打开或创建数据库
         */
        //参数1:上下文
        //参数2:数据库名称
        // (如果不指定路径默认在内存私有目录 data/data/包名/xx.db)
        // 指定路径,则在指定的路径下
        //参数3:游标 设为null
        //参数4:版本号
        //添加操作
        //数据库名称
        //如果只有一个数据库名称,那么这个数据库的位置会是在私有目录中
        //如果带SD卡路径,那么数据库位置则在指定的路径下
        String path = "test.db";
        Log.e("TAG", path);
        SQLiteOpenHelper helper = new SQLiteOpenHelper(this, path, null, 1) {
            @Override
            public void onCreate(SQLiteDatabase sqLiteDatabase) {
                //创建
                Toast.makeText(MainActivity.this, "数据库创建", Toast.LENGTH_SHORT).show();
                //如果数据库不存在,则会调用onCreate方法,那么我们可以将表的创建工作放在这里面完成
                /**/
                String sql = "create table info_tb (_id integer primary key autoincrement," +
                        "name varchar(20)," +
                        "age integer, " +
                        "gender varchar(4) )";
                sqLiteDatabase.execSQL(sql);
            }

            @Override
            public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
                //升级
                Toast.makeText(MainActivity.this, "数据库升级", Toast.LENGTH_SHORT).show();
            }
        };
        //用于获取数据库库对象
        //1.数据库存在,则直接打开数据库
        //2.数据库不存在,则调用创建数据库的方法,再打开数据库
        //3.数据库存在,但版本号升高了,则调用数据库升级方法
        db = helper.getReadableDatabase();

        //db.rawQuery(); 查询操作 select *from 表名
        //db.execSQL(); 添加、删除、修改、创建表
    }

    private void initView() {
        name = findViewById(R.id.name_edt);
        age = findViewById(R.id.age_edt);
        number = findViewById(R.id.number);
        gendergp = findViewById(R.id.gender_gp);
        gender_male = findViewById(R.id.male);
        list = findViewById(R.id.info_list);
        //单选的监听
        gendergp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == R.id.male) {
                    genderStr = "男";
                } else {
                    genderStr = "女";

                }
            }
        });
        insert = findViewById(R.id.insert_btn);
        select = findViewById(R.id.select_btn);
        delect = findViewById(R.id.delect_btn);
        update = findViewById(R.id.update_btn);

    }

    public void operate(View v) {
        //获取编辑框的内容
        String nameStr = name.getText().toString();
        String ageStr = age.getText().toString();
        String numStr = number.getText().toString();
        switch (v.getId()) {
            case R.id.insert_btn:
                //添加操作
                //添加方式1
//                String sql="insert into info_table(name,age,gender) values('"+nameStr+","+ageStr+",'"+genderStr+"')";
//                db.execSQL(sql);
                //添加方式2
                String sql2 = "insert into info_tb(name,age,gender) values(?,?,?)";
                db.execSQL(sql2, new String[]{nameStr, ageStr, genderStr});
                Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
                break;
            case R.id.select_btn:
                //查询
                //select*from 表名 where _id=?
                //查询所有数据
                String sql = "select*from info_tb";
                //通过判断是否输入编号来进行查询区别
                if (!numStr.equals("")) {
                    sql += " where _id=" + numStr;
                }
                Log.e("TAG", sql);
                //查询结果
                Cursor cursor = db.rawQuery(sql, null);
                //参数1:上下文 参数2:资源布局 参数3:cursor 参数4:属性名 参数5:显示控件id的数组 参数6:flag
                SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(
                        this,
                        R.layout.item,
                        cursor,
                        new String[]{"_id", "name", "age", "gender"},
                        new int[]{R.id.info_id, R.id.info_name, R.id.info_age, R.id.info_gender},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
                );
                list.setAdapter(cursorAdapter);
                Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delect_btn:
                //删除
                String delete_sql = "delete from info_tb where _id=?";
                db.execSQL(delete_sql, new String[]{numStr});
                Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
                break;
            case R.id.update_btn:
                //更新
                String update_sql = "update info_tb set name=?,age=?,gender=?  where _id=?";
                db.execSQL(update_sql, new String[]{nameStr, ageStr, genderStr, numStr});
                Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
                break;
        }
        //每次执行完一次操作都要清空一下编辑框
        name.setText("");
        age.setText("");
        gender_male.setChecked(true);
        number.setText("");
    }

    //android6.0之后要动态获取权限
    private void checkPermission(Activity activity) {
        // Storage Permissions
        final int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(MainActivity.this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

SQLiteDatabase对象的操作(二)

  • 查询:query(table, columns, selection, selectionArgs, groupBy, having, orderBy)
  • 添加:insert(table, nullColumnHack, values)
  • 删除:db.delete(table, whereClause, whereArgs)
  • 修改:db.update(table, values, whereClause, whereArgs)

这四个方法都不需要写sql语句

添加操作:

  • 添加:insert(table, nullColumnHack, values)
  • 参数1:表名 
    参数2:可以为空的列
    参数3:ContentValues 类型的变量,是键值对组成的 Map,key 代表列名,value 代表该列要插入的值 插入的值
    返回值:添加的id号
   ContentValues values=new ContentValues();
                values.put("name",nameStr);
                values.put("age",ageStr);
                values.put("gender",genderStr);
                db.insert("info_tb",null,values);

查询操作:

  • 查询:query(table, columns, selection, selectionArgs, groupBy, having, orderBy)
  • 参数1:表名 
  • 参数2:你所要查询的列。new String[]{"name","age",gender"}  查询所有 传入null或者new String[]{"*"}
  • 参数3:select 列名 from 表名 where 列1=值1  selection代表 "列1=?and 列2=?"(条件:针对列) 没有条件填null
  • 参数4:(条件值数组)条件对应的值数组 new String[]{"值1","值2"}   没有条件填null
  • 参数5:分组(group by age)通过年龄分组,不分组填null
  • 参数6:当通过group by对数据分组后,可以通过having来去除不符合条件的组(去除age<=23的记录) 不分组填null
  • 参数7:按什么排序 order by age 通过年龄排序 desc降序  不排序填null
  • 返回值:是Cursor结果集
  • 将所有的 SQL 语句都组织到一个 字符串中,使用占位符代替实际参数,selectionArgs 就是占位符实际参数集;下面 的几种参数都很类似,columns 表示要查询的列所有名称集,selection 表示 WHERE 之后的条件语句,可以使用占位符,groupBy 指定分组的列名,having 指 定分组条件,配合 groupBy 使用,orderBy 指定排序的列名,limit 指定分页参数, distinct 可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、 groupBy、having、orderBy、limit 这几个参数中不包括“WHERE”、“GROUP BY”、 “HAVING”、“ORDER BY”、“LIMIT”等 SQL 关键字。

Android进阶:Android数据库操作—步骤2: SQLite数据库

 

          //查询
                Cursor cursor =db.query("info_tb",null,null,null,null,null,null);
                //参数1:上下文 参数2:资源布局 参数3:cursor 参数4:属性名 参数5:显示控件id的数组 参数6:flag
                SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(
                        this,
                        R.layout.item,
                        cursor,
                        new String[]{"_id", "name", "age", "gender"},
                        new int[]{R.id.info_id, R.id.info_name, R.id.info_age, R.id.info_gender},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
                );
                list.setAdapter(cursorAdapter);

删除操作:

  • 删除:db.delete(table, whereClause, whereArgs)
  • 参数1:表名
  • 参数2:删除的条件
  • 参数3:删除条件的值
  • 返回值:影响的行数
  //删除
                int count=db.delete("info_tb","_id=?",new String[]{numStr});
                if (count>0)
                Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();

修改操作:

  • 修改:db.update(table, values, whereClause, whereArgs)
  • 参数1:表名
  • 参数2:ContentValues数组 更新的列名数组
  • 参数3:条件
  • 参数4:条件值数组
  • 返回值:影响的行数
  • update 的第二个参数也很类似,只不过它是更新该字段 key 为最新的 value 值,第三个参数 whereClause 表示 WHERE 表达式,比如“age > ? and age < ?”等, 最后的 whereArgs 参数是占位符的实际参数值;delete 方法的参数也是一样。

        //更新
                //update 表名  set 列名=xx,列名=xx where 列名=值
                ContentValues values2=new ContentValues();
                values2.put("name",nameStr);
                values2.put("age",ageStr);
                values2.put("gender",genderStr);
                int count2=db.update("info_tb",values2,"_id=?",new String[]{numStr});
                if (count2>0)
                Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();

总结

SQLite数据库是个轻量级的数据库,本质上是个二进制文件。

在Android平台上,SQLiteDatabase类下提供了两套方法操作数据

Android进阶:Android数据库操作—步骤2: SQLite数据库

DAO类(Data Access Oject 数据访问对象类)

StudentDao.java

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Dao (Data access Object)数据连接对象类
 */
public class StudentDao {
    private SQLiteDatabase db;

    public StudentDao(Context context) {
        String path = "test.db";
        SQLiteOpenHelper helper = new SQLiteOpenHelper(context, path, null, 2) {
            @Override
            public void onCreate(SQLiteDatabase db) {
                String sql = "create table info_tb(_id integer primary key autoincrement," +
                        "name varchar(20)," +
                        "age integer," +
                        "gender varchar(4))";
                db.execSQL(sql);
            }

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

            }
        };
        //拿到SQLiteDatabase实例
        db = helper.getReadableDatabase();
    }

    //添加操作
    public void addStudent(StudentInfo Info) {
        String sql = "insert into info_tb(name,age,gender) values(?,?,?)";
        db.execSQL(sql, new String[]{Info.getName(), Info.getAge() + "", Info.getGender()});
    }

    //查询操作 返回结果集
    public Cursor selectStudent(String... strs) {
        //查询所有(没有参数)
        //按条件查询(带参数)(参数1:条件,参数2:条件值)
        String sql = "select * from info_tb";
        if (strs.length != 0) {
            sql += " where " + strs[0] + "='" + strs[1] + "'";
        }
        Cursor c = db.rawQuery(sql, null);
        return c;
    }

    //删除操作
    public void deleteStudent(String... strs) {
        String sql = "delete from info_tb where " + strs[0] + "='" + strs[1] + "'";
        db.execSQL(sql);
    }

    //修改操作
    public void updateStudent(StudentInfo info) {
        String sql = "update info_tb set name=?,age=? ,gender=? where _id=?";
        db.execSQL(sql, new Object[]{info.getName(), info.getAge(), info.getGender(), info.getId()});

    }


}

StudentInfo.java //学生信息类

public class StudentInfo {
    private int id;
    private String name;
    private int age;
    private String gender;

    public StudentInfo(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public StudentInfo(String name, int age, String gender, int id) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

 MainActivity.java 操作类

public class MainActivity3 extends AppCompatActivity {

    private EditText name;
    private EditText age;
    private EditText number;
    private RadioGroup gendergp;
    private String genderStr = "男";
    private ListView list;
    private RadioButton gender_male;
    private StudentDao dao;


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

    }

    private void initView() {
        name = findViewById(R.id.name_edt);
        age = findViewById(R.id.age_edt);
        number = findViewById(R.id.number);
        gendergp = findViewById(R.id.gender_gp);
        gender_male = findViewById(R.id.male);
        list = findViewById(R.id.info_list);
        //单选的监听
        gendergp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == R.id.male) {
                    genderStr = "男";
                } else {
                    genderStr = "女";

                }
            }
        });

    }

    public void operate(View v) {
        //获取编辑框的内容
        String nameStr = name.getText().toString();
        String ageStr = age.getText().toString();
        String numStr = number.getText().toString();
        dao = new StudentDao(this);
        switch (v.getId()) {
            //插入操作
            case R.id.insert_btn:
                StudentInfo info = new StudentInfo(nameStr, Integer.parseInt(ageStr), genderStr);
                dao.addStudent(info);
                Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
                break;
            //查询操作
            case R.id.select_btn:
                String[] params = getParams(nameStr, ageStr, numStr);
                Cursor c;
                if (params[0] != null)
                    c = dao.selectStudent(params[0], params[1]);
                else {
                    c = dao.selectStudent();
                }
                //参数1:上下文 参数2:资源布局 参数3:cursor 参数4:属性名 参数5:显示控件id的数组 参数6:flag
                SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(
                        this,
                        R.layout.item,
                        c,
                        new String[]{"_id", "name", "age", "gender"},
                        new int[]{R.id.info_id, R.id.info_name, R.id.info_age, R.id.info_gender},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
                );
                list.setAdapter(cursorAdapter);
                Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show();
                break;
            //删除操作
            case R.id.delect_btn:
                String[] params2 = getParams(nameStr, ageStr, numStr);
                if (!params2.equals(null))
                    dao.deleteStudent(params2[0], params2[1]);
                Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
                break;
            //修改操作
            case R.id.update_btn:
                //更新
                StudentInfo info2 = new StudentInfo(nameStr, Integer.parseInt(ageStr), genderStr, Integer.parseInt(numStr));
                dao.updateStudent(info2);
                Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
                break;
        }
        //每次执行完一次操作都要清空一下编辑框
        name.setText("");
        age.setText("");
        gender_male.setChecked(true);
        number.setText("");
    }

    //拿到条件数组
    public String[] getParams(String nameStr, String ageStr, String numStr) {
        String[] params = new String[2];
        if (!nameStr.equals("")) {
            params[0] = "name";
            params[1] = nameStr;
        } else if (!ageStr.equals("")) {
            params[0] = "age";
            params[1] = ageStr;
        } else if (!numStr.equals("")) {
            params[0] = "_id";
            params[1] = numStr;
        }
        return params;
    }

    //android6.0之后要动态获取权限
    private void checkPermission(Activity activity) {
        // Storage Permissions
        final int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(MainActivity3.this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(MainActivity3.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

将数据库的数据装成ArrayList显示到ListView上 在步骤1的listview1中实现了,。

  public ArrayList<Student> getStudentInList(String... strs){
        ArrayList<Student> list = new ArrayList<>();
        Cursor c = getStudent(strs);
        while (c.moveToNext()){
            int id = c.getInt(0);
            String name = c.getString(1);
            int age = c.getInt(2);
            String gender = c.getString(3);
            Student s = new Student(id,name,age,gender);
            list.add(s);
        }
        return list;
    }