day03数据库及listview

经验:1.sqlite表中的类型限定并不起作用,底层所有的数据都是String,为了节约手机内存

2.4.0版本以后数据库在创建时会产生一个临时文件

3.4.4版本以后虚拟机引用了ART模式,使速度更快

4.开发分包示例

1.android下数据库的创建

什么时候使用数据库做数据存储? 有大量具有相同结构的数据需要存储时。

mysql sql2008 sqlite 内置的 轻量级

SqliteOpenHelper:

1.创建一个类继承SqliteOpenHelper,写一个构造方法用来指定数据库的名称版本

2.实现两个方法:

//构造方法 ,用来指定数据库的名称和版本号

public MySqliteOpenHelper(Context context) {

//context :上下文   name: 数据库文件的名称  factory:用来创建cursor对象,默认传null   version:数据库的版本,从android4.0之后只能升不能降。

super(context, "info.db", null, 2);

}

onCreate:数据库第一次创建的时候调用onCreate方法, 特别适合做表结构的初始化

//数据库第一次创建的时候调用onCreate方法, 特别适合做表结构的初始化

@Override

public void onCreate(SQLiteDatabase db) {

//做表结构的初始化就需要执行create table这样的sql语句

//使用db执行sql语句

db.execSQL("create table info (_id integer primary key autoincrement ,name varchar(20) )");

}

//当数据库的版本发生改变的时候会调用onUpgrade方法;特别适合做表结构的修改

@Override

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

//做表结构的修改需要执行sql语句

//          db.execSQL("alter table info add  phone varchar(20)");

System.out.println("oldVersion:"+oldVersion +"  newVersion: "+newVersion);

}

onUpgrade:当数据库的版本发生改变的时候会调用onUpgrade方法;特别适合做表结构的修改

3.创建一个帮助类的实例化对象,并调用getReadableDatabase或getWritableDatabase方法,可以帮助我们创建或打开一个数据库。

*******getReadableDatabase和getWritableDatabase区别:

getReadableDatabase:首先尝试以读写的方式打开数据库,如果磁盘空间满了,会再次尝试以只读方式打开数据库。

getWritableDatabase: 直接以读写方式打开数据库,如果磁盘空间满了,直接报错。

2.Android下数据库的第一种增删改查方法(没有返回值,适合查询使用)

public class InfoDaoUtils {

private MySqliteOpenHelper mySqliteOpenHelper;

public InfoDaoUtils (Context context){

//1.创建帮助类对象

mySqliteOpenHelper = new MySqliteOpenHelper(context);

}

//增加方法

public void insert(UserBean bean){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();//这个方法不要再构造函数中初始化,不方便数据库操作

//3.执行sql语句  sql:sql语句   bindArgs:?sql语句中占位符的值。

db.execSQL("insert into info(name,phone) values(?,?);", new Object[]{bean.name,bean.phone});

//4.关闭数据库对象

db.close();

}

//删除方法

public void delete(String name){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句  sql:sql语句   bindArgs:?sql语句中占位符的值。

db.execSQL("delete from info where name=?;", new Object[]{name});

//4.关闭数据库对象

db.close();

}

//更新方法

public void update(UserBean newuserBean){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句  sql:sql语句   bindArgs:?sql语句中占位符的值。

db.execSQL("update info set phone=? where name=?;", new Object[]{newuserBean.phone,newuserBean.name});

//4.关闭数据库对象

db.close();

}

//查询方法

public void query(String name){

//执行sql语句需要SqliteDatabase对象

ArrayList list = new ArrayList();

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句  sql:sql语句   selectionArgs:?sql语句中查询条件的占位符的值。  返回一个cursor游标结果集对象

Cursor cursor = db.rawQuery("select name,phone from info where name = ? ", new String[]{name});

//4.获取结果集中的数据封装到list中

if(cursor != null && cursor.getCount() > 0){//说明结果集中有数据

while(cursor.moveToNext()){//游标可以指向下一行

//解析一行数据

String name_str = cursor.getString(cursor.getColumnIndex("name"));//通过获取字段编号再获得字段值,不会弄错编号

String phone_str = cursor.getString(cursor.getColumnIndex("phone"));

System.out.println("name : "+name_str + "  phone:"+phone_str);

UserBean userBean = new UserBean();

userBean.name = name_str;

userBean.phone = phone_str;

list.add(userBean);

}

//关闭游标对象

cursor.close();

}

//5.关闭数据库对象

db.close();

}

3.Android下另一种增删改查(谷歌封装的API,有返回值,适合增删改)

public class InfoDaoUtils2 {

private MySqliteOpenHelper mySqliteOpenHelper;

public InfoDaoUtils2 (Context context){

//1.创建帮助类对象

mySqliteOpenHelper = new MySqliteOpenHelper(context);

}

//增加方法

public boolean insert(UserBean bean){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

// db.execSQL("insert into info(name,phone) values(?,?);", new Object[]{bean.name,bean.phone});

ContentValues values = new ContentValues();//底层封装的是一个map

values.put("name", bean.name);

values.put("phone", bean.phone);

//3.执行sql语句

//table: 表名 nullColumnHack:可以为null values:封装要添加的列的值 返回值:新添加这一行的行的id,如果是-1标示添加失败

long result = db.insert("info", null, values);

//4.关闭数据库对象

db.close();

if(result == -1){

return false;

}else{

return true;

}

}

//删除方法

public int delete(String name){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句

//table:表名 whereClause:删除的条件 whereArgs:删除条件占位符的值 返回值:成功删除了多少行

int result = db.delete("info", "name=?", new String []{name});

//4.关闭数据库对象

db.close();

return result;

}

//更新方法

public int update(UserBean newuserBean){

//执行sql语句需要SqliteDatabase对象

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句

ContentValues values = new ContentValues();

values.put("phone", newuserBean.phone);

//table: values:要更新的列 whereClause:更新条件 whereArgs:更新条件占位符的值 返回值:成功修改了多少行

int result = db.update("info", values, "name=?", new String[]{newuserBean.name});

//4.关闭数据库对象

db.close();

return result;

}

//查询方法

public void query(String name){

//执行sql语句需要SqliteDatabase对象

ArrayList list = new ArrayList();

//2.调用getReadableDatabase获取一个SqliteDatabase对象

SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();

//3.执行sql语句

//table :表名 columns:查询哪些列 ,如果传null代表查询所有列 selection:查询的条件 selectionArgs:条件占位符的值 groupBy:按什么分组 having:分组的条件 orderBy :按什么排序

Cursor cursor = db.query("info", new String[]{"name","phone"}, "name = ?", new String[]{name}, null, null, "_id desc");

//4.获取结果集中的数据封装到list中

if(cursor != null && cursor.getCount() > 0){//说明结果集中有数据

while(cursor.moveToNext()){//游标可以指向下一行

//解析一行数据

String name_str = cursor.getString(cursor.getColumnIndex("name"));

String phone_str = cursor.getString(cursor.getColumnIndex("phone"));

System.out.println("name : "+name_str + " phone:"+phone_str);

UserBean userBean = new UserBean();

userBean.name = name_str;

userBean.phone = phone_str;

list.add(userBean);

}

//关闭游标对象

cursor.close();

}

//5.关闭数据库对象

db.close();

}

}

4.数据库事务(适合银行操作,代码块中同时成功或者同时失败)

1.事务对于查询安全性的作用

//做转账业务,执行sql语句

public void transtationAccount(View v){

AccountSqliteOpenHelper accountSqliteOpenHelper = new AccountSqliteOpenHelper(this);

SQLiteDatabase db = accountSqliteOpenHelper.getReadableDatabase();

//开启事务

db.beginTransaction();

try {

db.execSQL("update account set money= money-200 where name=?",new String[]{"李四"});

//模拟一个异常

int i = 100/0;

db.execSQL("update account set money= money+200 where name=?",new String[]{"张三"});

db.setTransactionSuccessful();//设置一个成功的标记

} finally {

db.endTransaction();//结束事务,要判断事务是否成功,如果成功提交所有sql语句,如果失败,回滚所有的sql语句

}

db.close();

}

2.事务对于提高数据库批量操作效率的作用

在批量修改数据的时候,由于事务是在进行事务提交时将要执行的SQL操作一次性打开数据库连接执行,其执行速度比逐条执行SQL语句的速度快了很多倍。因此当我们开发中遇到对数据库的批量操作那么,使用事务是提高效率的重要原则。

publicvoidtestTransactionEfficient(){

PersonOpenHelper helper =newPersonOpenHelper(getContext(),"person",null, 2);

SQLiteDatabase database = helper.getWritableDatabase();

//     ------测试不使用事务时插入1w条数据耗时--------------------

longbeginTime = System.currentTimeMillis();

for(inti=0;i<10000;i++){

database.execSQL("insert into person(name,age,phone) values('text'+"+i+","+i+",'"+(1320000+i)+""+"')");

}

longendTime = System.currentTimeMillis();

System.out.println("不使用事务插入1w条数据耗时:"+(endTime-beginTime)+"毫秒");

//     ---------测试使用事务时耗时-----------------------

beginTime = System.currentTimeMillis();

database.beginTransaction();

for(inti=0;i<10000;i++){

database.execSQL("insert into person(name,age,phone) values('text'+"+i+","+i+",'"+(1320000+i)+""+"')");

}

database.setTransactionSuccessful();

database.endTransaction();

endTime = System.currentTimeMillis();

System.out.println("使用事务插入1w条数据耗时:"+(endTime-beginTime)+"毫秒");

5.获取listview显示的步骤

ListView 是一个在垂直滚动的列表中展示条目的控件。ListView上的条目内容来自于ListAdapter.

1.写布局

2.activity中找到listview

3.写一个类继承BaseAdapter,实现4个方法。

getcount:告诉listview要显示多少个条目

getItem:获取listview指定position条目上的数据对象。 该方法不影响listview的展示,可以先不实现。

getItemId:获取listview指定条目的id. 该方法不影响listview的展示,可以先不实现。

getView:告诉listview每个条目上显示的内容。 listview每显示一个条目getView方法就会被调用一次。 convertView:之前消失的那个item上的view对象

4.创建一个Adapter对象,设置给listview做条目的适配

listview.setAdapter(ListAdapter adapter)

6 常用获取inflate的写法

a.使用View.inflate

//需要创建一个复杂的布局转换成一个view对象。 context :上下文 ,resource :要填充的布局资源的id root:将要填充的布局用root包裹起来返回,一般传null

view = View.inflate(context, R.layout.item_news, null);//将一个布局文件填充成一个view对象

b.使用context.getSystemService

LayoutInflater layoutInfalter = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

view = layoutInfalter.inflate(R.layout.item_news, null);

c.使用LayoutInflate.from

LayoutInflater layoutInfalter = LayoutInflater.from(context);

view = layoutInfalter.inflate(R.layout.item_news, null);

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