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);

你可能感兴趣的:(day03数据库及listview)