Android中SQLite的基本使用(二)
来源:互联网 发布:中小企业网络搭建 编辑:程序博客网 时间:2024/06/05 18:22
根据前面的学习,相信大家都能明白 Android 中 SQLite 数据库是如何创建的,这里我来讲下 SQLite 在 Android 中的数据操作。
数据库表
在我们的 SQLite 数据库中,数据的存储是以表的形式,所以在创建数据库的时候我们也应该创建一张数据表,学习过 SQL 语句的都知道要创建一张完整的数据表,需要表名和列名,而这些事我们有可能要去修改的,所以为了效率,我们应该把这些设置为常量去使用,前面我们建立了一个 Constant 类,让我们添加些数据进去:
public class Constant { public static final String DATABASE_NAME = "info.db"; //数据库名称 public static final int DATABASE_VERSION = 1; //数据库版本 public static final String TABLE_NAME = "person"; //表名 public static final String _ID = "_id"; public static final String NAME = "name"; public static final String AGE = "age";}
可以看到,我们又添加了表名和三个字段,这样就方便我们日后修改。
让我们回到 MySQLiteHelper 类:
public void onCreate(SQLiteDatabase db) { Log.i("TAG", "-------onCreate--------"); String sql = "create table " + Constant.TABLE_NAME + " (" + Constant._ID + " Integer primary key, " + Constant.NAME + " varchar(10)," + Constant.AGE + " Integer)"; db.execSQL(sql); }
execSQL(String sql) 是 SQLiteDatabase 类的执行 SQL 语句的方法,大家将刚才生成的 info.db 删除,再次运行,这样就能在创建数据库文件的时候创建一张 PERSON 的表啦。
我们把生成的 info.db 导出到桌面或者你自己的某个硬盘目录下,用可视化数据库工具打开,你就可以看到数据库的信息,自然也能看到我们新创建的那张表。
我用的是 Navicat Premium,大家可以从这里下载。
SQL语句增删改查
在 Android 中我们可以自己写 sql 语句去执行,但如果觉得写 sql 语句容易出错,也可以调用 api 中的方法。在 SQLite 中,查询操作是特别的,insert,update,delete都对数据做了修改,但 select 只返回结果,所以我们需要能接收这个结果,这样就不能使用 execSQL 方法啦。
我们还有两个方法可以执行查询,分别是 rawQuery 和 query,query() 是 api 拼接 sql 语句,我们暂且不提。
rawQuery(String sql, String[] selectionArgs),sql 就是执行的 select 语句,selectionArgs 是查询条件的占位符,如果没有占位符,就传入null即可,最后会返回一个 Cursor 对象,帮我们确定数据的位置。
DBManager 类是我们用来管理数据库的工具类,execSQL() 是我们必须用到的方法,为了防止出错,我们应该在 DBManager 类中写个方法来判断,同样 rawQuery() 也应该判断。
public static void execSQL(SQLiteDatabase db, String sql) { if (db != null) { if (sql != null && !"".equals(sql)) { db.execSQL(sql); } } } public static Cursor selectDataBySql(SQLiteDatabase db, String sql, String[] selectionArgs) { Cursor cursor = null; if (db != null) { cursor = db.rawQuery(sql, selectionArgs); } return cursor; }
相信大家都能够看懂,这里就不讲啦。
rawQuery 是返回一个 Cursor 游标,那么我们自然需要把它转换为熟悉的 list 集合,首先我们要有存储数据的实体类,这就是 Java Bean 思想。
public class Person { private int _id; private String name; private int age; public Person(int _id, String name, int age) { this._id = _id; this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "_id=" + _id + ", name='" + name + '\'' + ", age=" + age + '}'; } public int get_id() { return _id; } public void set_id(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; }}
有了这个 Person 类,我们就可以在 DBManager 中写从 Cursor 中读数据的方法啦。
public static List<Person> cursorTolist(Cursor cursor) { List<Person> list = new ArrayList<Person>(); while (cursor.moveToNext()) { //getColumnIndex(String columnName) 根据参数中指定的字段名称获取字段下标 int columnIndex = cursor.getColumnIndex(Constant._ID); //getInt(int columnIndex)根据参数中指定的字段下标 获取对应int类型的value int _id = cursor.getInt(columnIndex); String name = cursor.getString(cursor.getColumnIndex(Constant.NAME)); int age = cursor.getInt(cursor.getColumnIndex(Constant.AGE)); Person person = new Person(_id, name, age); list.add(person); } return list; }
根据字段名获取字段下标,再得到字段的 value,懂得一点 Cursor 知识的朋友应该都能明白。
public void click(View view) { switch (view.getId()) { case R.id.btn_insert : SQLiteDatabase db = helper.getWritableDatabase(); for (int i = 1; i <= 30; i++) { String sql1 = " insert into " + Constant.TABLE_NAME + " values(" + i + ",'张三" + i + "'," + i + ") "; DbManager.execSQL(db, sql1); } db.close(); break; case R.id.btn_update : db = helper.getWritableDatabase(); String updatesql=" update "+ Constant.TABLE_NAME + " set " + Constant.NAME + "='xiao' where " + Constant._ID + "=1"; DbManager.execSQL(db,updatesql); db.close(); break; case R.id.btn_delete : db = helper.getWritableDatabase(); String deletesql = " delete from " + Constant.TABLE_NAME + " where " + Constant._ID + "=2"; DbManager.execSQL(db,deletesql); db.close(); break; case R.id.btn_query : db = helper.getWritableDatabase(); String sql = "select * from " + Constant.TABLE_NAME; Cursor cursor = DbManager.selectDataBySql(db, sql, null); List<Person> list = DbManager.cursorTolist(cursor); for (Person p: list) { Log.i("TAG", p.toString()); } db.close(); break; } }
因为这个代码只是测试数据,所以就随便添加,只要实现功能即可。
这些代码是很容易理解的,现在打开模拟器点击按钮来看看。
我们可以看到表中已经有了30条数据,并且 id = 2的数据已经被删除了,id = 1的数据名字也已经别改成了 xiao,这说明我们的功能已经实现了。这里要注意的是,如果你按了几次 insert,会报错,因为 id 重复了,这并没什么。
因为我们执行的 select 是查询全部信息,所以查询结果也显然成功啦。
API 操作
数据库的增删改查需要正确的 SQL 语句,如果对 SQL 语句不熟练的用提供的 api 也是一样的。
insert
insert(String table, String nullColumnHack, ContentValues values)
table:相信大家都能理解是数据表名。
nullColumnStack:因为在 SQLite 中可以允许列中有 NULL,但不能整列都是NULL,这个值代表强行插入null值的数据列的列名,我们都是给 null 就可以了。
values:代表一行记录的数据。insert 方法插入的一行记录使用ContentValues存放,我们看看它的说明。
private HashMap<String, Object> mValues;
可以知道 ContentValues 是一个键为 String 的 HashMap集合,它提供了多种 put(String key, XXX value) (其中key为数据列的列名)方法用于存入数据,多种 getAsXxx(String key) 方法用于取出数据。
insert 方法返回 long,代表新添记录的行号,该行号是一个内部直,与主键id无关,发生错误返回-1。
update
update(String table, ContentValues values, String whereClause, String[] whereArgs)
table 与 values 和 insert 方法是一样的。
whereClause:表示修改条件,满足该whereClause子句的记录将会被更新。
whereArgs:表示修改条件的占位符,用于为whereArgs子句传递参数。
update 方法返回一个 int,表示修改的数据条数。
delete
delete(String table, String whereClause, String[] whereArgs)
table:代表想删除数据的表名。
whereClause:满足该whereClause子句的记录将会被删除。
whereArgs:用于为whereArgs子句传入参数。
与 update 方法中的格式是一样的。
query
query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
- distinct:指定是否去除重复记录。
- table:执行查询数据的表名。
- columns:要查询出来的列名。
- selection:查询条件子句。
- selectionArgs:用于为selection子句中占位符传入参数值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
- groupBy:用于控制分组。
- having:用于对分组进行过滤。
- orderBy:用于对记录进行排序。
- limit:用于进行分页。
最后返回 Cursor 游标。
public void onClick(View view) { switch(view.getId()) { case R.id.btn_insertApi : SQLiteDatabase db = helper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(Constant._ID, 2); //put(表示插入数据库的字段名称,表示插入该字段的具体值) values.put(Constant.NAME, "Lily"); values.put(Constant.AGE, 15); long result = db.insert(Constant.TABLE_NAME, null, values); if (result > 0) { Toast.makeText(this, "插入数据成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "插入数据失败", Toast.LENGTH_SHORT).show(); } db.close(); break; case R.id.btn_updateApi : db = helper.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put(Constant.NAME, "cc");//put(表示需要修改的字段名称, 修改后的字段值)// int count = db.update(Constant.TABLE_NAME, cv, Constant._ID + "=3", null); int count = db.update(Constant.TABLE_NAME, cv, Constant._ID + "=?", new String[]{"3"}); if (count > 0) { Toast.makeText(this, "修改数据成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "修改数据失败", Toast.LENGTH_SHORT).show(); } db.close(); break; case R.id.btn_deleteApi : db = helper.getWritableDatabase(); int count2 = db.delete(Constant.TABLE_NAME, Constant._ID + "=?", new String[]{"1"}); if (count2 > 0) { Toast.makeText(this, "删除数据成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "删除数据失败", Toast.LENGTH_SHORT).show(); } db.close(); break; case R.id.btn_queryApi : db = helper.getWritableDatabase(); Cursor cursor = db.query(Constant.TABLE_NAME, null, Constant._ID + ">?", new String[]{"10"}, null, null, Constant._ID + " asc"); List<Person> list = DbManager.cursorTolist(cursor); for (Person p : list) { Log.i("TAG", p.toString()); } db.close(); break; } }
这可以看到,在写查询条件的时候有两种写法:
db.update(Constant.TABLE_NAME, cv, Constant._ID + "=3", null);db.update(Constant.TABLE_NAME, cv, Constant._ID + "=?", new String[]{"3"});
这两种是完全一样的。
并没有出现强退,我们看看数据表的变化。
可以看到我们已经删除了 id = 1 的数据,并且以前 id = 2 被删除的数据也插入了新的,id = 3 的数据也被修改了,再看看查询。
id > 10 的数据都被输出了,说明我们 api 的功能也都实现啦。
结束语:本文仅用来学习记录,参考查阅。
- Android中SQLite的基本使用(二)
- android中sqlite的使用(二)
- android中使用sqlite的数据库的基本操作
- android中sqlite数据库的基本使用和添加多张表
- Day07-Android中SQLite数据存储,ListView的基本使用
- Android SQLite基本使用
- android中sqlite的使用(一)
- Android中SQLite的基本使用方法
- Android中SQLite的基本用法
- (Android学习笔记二)AChartEngine的使用以及在sqlite中存取DATETIME!
- (Android学习笔记二)AChartEngine的使用以及在sqlite中存取DATETIME!
- android数据库sqlite的基本使用
- Android SQLite数据库的基本使用
- iOS中sqlite的基本使用
- Android SQLite (二) 基本用法
- android中sqlite的使用
- android中SQLite的使用
- android中SQLite的使用
- Android 下 编写自己第一个NDK Demo
- 获取对端IP,端口信息
- eclipse的java classpath variables没有显示
- TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
- mybatis学习之一
- Android中SQLite的基本使用(二)
- 按照官方文档启动不了tensorboard的解决办法
- C++计时
- 解决IE兼容问题
- TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
- vue-cli使用方法
- ANDROID STUDIO系列教程二--基本设置与运行
- python MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") TypeError: __call__() takes exactly 2
- JavaScript之DOM详细使用实例