1. Sqlite 简介
Sqlite 是一种轻量级,零配置的,可嵌入的程序驱动型的二进制文件,同时也是一种 关系型数据库。
SQLite 是一个开源的关系型数据库,实现自包容、零配置、支持 事务的SQL数据库引擎。
其特点是高度便携、使用方便、结构紧凑、 高效、可靠。
鉴于 Sqlite 数据库的这些优点,现在流行的操作系统 Android 和 ios都选择使用 Sqlite 作为数据存储的主要方式。
2. Sqlite 的使用场景
现在的主流移动设备像 Android、iPhone 等都使用 SQLite 作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,
也许就要使用到 SQLite 来存储我们大量的 数据,所以我们就需要掌握移动设备上的 SQLite 开发技巧。
对于 Android 平台来说, 系统内置了丰富的 API 来供开发人员操作 SQLite,我们可以轻松的完成对数据的存 取
数据库建表:
SQLPro for SQLite for Mac 图形化SQLITE数据库 密码:1cnq
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.给一个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
查询:产生的是虚拟的结果集,并不是真的把数据取出来给客户端(想拍照一样)
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 数据库中获取数据库对象的两个方法:
-
获取数据库实例时使用了 getWritableDatabase()方法。
-
在 getReadableDatabase()方法中,首先判断是否已存在数据库实例并且是打
开状态,如果是,则直接返回该实例,否则试图获取一个可读写模式的数据库实 例,如果遇到磁盘空间已满等情况获取失败的话,再以只读模式打开数据库,获 取数据库实例并返回,然后为数据库对象赋值为最新打开的数据库实例。
-
getReadableDatabase()一般都会返回和 getWritableDatabase()一样的数据 库实例,所以我们在 DBManager 构造方法中使用 getWritableDatabase()获取 整个应用所使用的数据库实例是可行的
-
当 调 用 SQLiteOpenHelper 的 getWritableDatabase() 或 者getReadableDatabase()方法获取用于操作数据库的 SQLiteDatabase 实例的时候,如果数据库不存在,Android 系统会自动生成一个数据库,接着调用onCreate()方法。
-
onCreate()方法在初次生成数据库时才会被调用,在 onCreate()方法里可以生成 数据库表结构及添加一些应用使用到的初始化数据。
-
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的使用
删除操作:
//删除
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 关键字。
//查询
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类下提供了两套方法操作数据
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;
}