day03
1 数据库介绍
sqlite
问:什么情况下用数据库? ----------有大量相似结构的数据需要存储的时候
File file = new File("info.txt);
2 数据库的创建
定义一个类继承sqliteOpenHelper
3 数据库的oncreate方法和onupgrade方法
[1]使用SQLite Expert Professional这个工具可以打开我们创建的数据库
[2]需要提前安装SQLite Expert Professional这个工具
4 使用sql语句对数据库进行增删改查
优点:多表查询容易
缺点:<1>sql语句容易写错
<2>执行SQL语句没有返回值 不容易进行判断
4.1 [1]使用命令行工具sqlite3可以打开数据库
[2]改变dos的编码方式 chcp 936 改变成GBK 编码方式 如果改成utf-8 chcp 65001
5 使用谷歌封装好的api对数据库增删改查
优点 [1]写法简单 不需要写复杂的SQL语句 不容易写错
[2]有返回值方便开发者进行开发
缺点 如果有多张表 使用谷歌封装的api不容易进行查询
6 2种增删改查的优缺点
7 Android中数据库的事务的介绍
事务:执行一段逻辑 要么同时成功要么失败 银行转账
//开启事务
db.beginTransaction();
try
{
//实现转账的逻辑
//实际上就写sql语句
db.execSQL("update info set money = money - 100 where name=?",new Object[]{"张三"});
db.execSQL("update info set money = money + 100 where name=?",new Object[]{"李四"});
//给当前事务设置一个成功的标记
db.setTransactionSuccessful();
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), "服务器忙,请稍后再转", 1).show();
}
finally
{
//关闭事务
db.endTransaction();
}
8 listview入门
[1]定义listview在布局中
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:fastScrollEnabled="true"
android:layout_height="match_parent" //要用match_parent,优化
>
[2]定义listview的数据适配器
//[1]找到我们关心的控件
ListView lv = (ListView)findViewById(R.id.lv);
//[2]显示数据 和 其他普通控件(textview)有点区别数据来源于数据适配器
lv.setAdapter(new MyListAdapter());
[3]实现baseAdapter的getCount方法和getView方法
//[3]定义listview的数据适配器
private class MyListAdapter extends BaseAdapter
{
//一共有多少条数据需要展示
public int getCount()
{
return 1000000000;
}
//返回指定position位置对应的对象
public Object getItem(int position)
{
return null;
}
//返回position位置对应id
public long getItemId(int position)
{
return 0;
}
/**
*
* 获取一个view 用来显示listview的数据 会作为listview的一个条目出现
*
* converView 历史缓存对象
*/
public View getView(int position, View converView, ViewGroup parent)
{
TextView tv;
if(converView == null)
{
//创建新的view对象
tv = new TextView(MainActivity.this);
System.out.println("创建新的view对象----" + position);
}
else
{
System.out.println("复用历史缓存对象----" + position);
//若历史缓存对象存在,则用历史缓存对象赋值
tv = (TextView) converView;
}
//System.out.println("getView---" + position);
tv.setText("hahahahha" + position);
return tv;
}
}
9 listview的优化
Out of memory on a 108-byte allocation(内存溢出) 使用converView 历史缓存对象
public View getView(int position, View converView, ViewGroup parent)
{
TextView tv;
if(converView == null)
{
//创建新的view对象
tv = new TextView(MainActivity.this);
System.out.println("创建新的view对象----" + position);
}
else
{
System.out.println("复用历史缓存对象----" + position);
//若历史缓存对象存在,则用历史缓存对象赋值
tv = (TextView) converView;
}
//System.out.println("getView---" + position);
tv.setText("hahahahha" + position);
return tv;
}
10 listview显示数据的原理
mvc模式
Android:
m:mode 数据(javabean)
v:view listview
c:adapter
补充 listview的奇怪现象
以后再使用listview 高度的设置使用 填充父窗体(match_parent)
不管是什么adapter 作用就是把数据展示到listview
11 listview显示复杂的页面
线性布局 相对布局都继承自ViewGroup 可以有自己的孩子
通过一个打气筒 inflate可以把一个布局转换成有一个view对象
12 获取打气筒常用api
[1]view = View.inflate(getApplicationContext(), R.layout.item, null);
[2]view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
[3]LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, null);13 ArrayAdapter的使用
String objects[] = {"老张","老方","老黎","老毕","老刘","老韩"};
//[1]找到我们关心的控件
ListView lv = (ListView) findViewById(R.id.lv);
//[2]创建一个arrayAdapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.item, objects);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.item1, R.id.tv_name, objects);
//[3]设置数据适配器
lv.setAdapter(adapter);
权重一般用在LinearLayout布局
14 simpleAdapter使用
//[1]找到控件
ListView lv = (ListView) findViewById(R.id.lv);
//[1.1]准备listview要显示的数据
List<Map<String, String>> data = new ArrayList<Map<String,String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("name", "官朝辉");
map1.put("phone", "1377888");
Map<String, String> map2 = new HashMap<String, String>();
map2.put("name", "赵云");
map2.put("phone", "999");
Map<String, String> map3 = new HashMap<String, String>();
map3.put("name", "刘备");
map3.put("phone", "1371237888");
Map<String, String> map4 = new HashMap<String, String>();
map4.put("name", "小乔");
map4.put("phone", "2222222");
//[1.1]把map加入到集合中
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
//[2]设置数据设备器
//resource 我们定义的布局文件
// from map集合的键
// to 布局里的控件
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), data, R.layout.item, new String[]{"name","phone"}, new int[]{R.id.tv_name,R.id.tv_phone});
//[3]设置数据适配器
lv.setAdapter(adapter);
15 把数据库里面的数据查询出来展示到listview上
package com.phone.sqliteapi;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private MyOpenHelper myOpenHelper;
private List<Person> lists;
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[0]找到控件
lv = (ListView) findViewById(R.id.lv);
myOpenHelper = new MyOpenHelper(getApplicationContext());
lists = new ArrayList<Person>();
//打开或者创建数据库 如果是第一次就是创建
//SQLiteDatabase sqLiteDatabase = myOpenHelper.getWritableDatabase();
//打开或者创建数据库 如果是第一次就是创建 如果磁盘满了 返回只读的
//SQLiteDatabase readableDatabase = myOpenHelper.getReadableDatabase();
}
//点击按钮增加一条记录
public void click1(View v)
{
//[1]获取数据库对象
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//[2]执行增加一条的SQL语句
//db.execSQL("insert into info(name,phone) values(?,?)", new Object[]{"张三","1388888"});
/**
* table 表名
* ContentValues 内部封装了一个map key:对应列的名字i value对应的值
*/
ContentValues values = new ContentValues();
values.put("name", "王五");
values.put("phone", "110");
//返回值代表插入 新行的id
long insert = db.insert("info", null, values);
//[3]数据库用完需要关闭
db.close();
if(insert > 0)
{
Toast.makeText(getApplicationContext(), "添加成功", 1).show();
}
else
{
Toast.makeText(getApplicationContext(), "添加失败", 1).show();
}
}
//点击按钮删除一条记录
public void click2(View v)
{
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//db.execSQL("delete from info where name=?",new Object[]{"张三"});
//返回值代表影响的行数
int delete = db.delete("info", "name=?", new String[]{"王五"});
db.close();
Toast.makeText(getApplicationContext(), "删除了" + delete + "行", 1).show();
}
//点击按钮更新一条记录
public void click3(View v)
{
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//db.execSQL("update info set phone=? where name=?", new Object[]{"1377777777","张三"});
ContentValues values = new ContentValues();
values.put("phone", "119");
//代表更新了多少行
int update = db.update("info", values, "name=?", new String[]{"王五"});
db.close();
Toast.makeText(getApplicationContext(), "更新了" + update + "行", 1).show();
}
//点击按钮查找记录
public void click4(View v)
{
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
/**
* columns 代表你要查询的列
*/
//Cursor cursor = db.query("info", new String[]{"phone"}, "name=?", new String[]{"王五"}, null, null, null);
Cursor cursor = db.query("info", null, null, null, null, null, null);
//Cursor cursor = db.rawQuery("select * from info", null);
if(cursor != null && cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
//columnIndex代表列的索引
//String name = cursor.getString(1);
//String phone = cursor.getString(2);
//System.out.println("name:" + name + "-----" + phone);
String name = cursor.getString(1);
String phone = cursor.getString(2);
//把数据封装到javabean
Person person = new Person();
person.setName(name);
person.setPhone(phone);
//把javabean加入到集合
lists.add(person);
}
//设置数据适配器
lv.setAdapter(new MyAdapter());
}
cursor.close();
}
private class MyAdapter extends BaseAdapter
{
@Override
public int getCount() {
// TODO Auto-generated method stub
return lists.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null)
{
//创建新的view对象
view = View.inflate(getApplicationContext(), R.layout.item, null);
//view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
//LayoutInflater systemService = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
//view = systemService.inflate(R.layout.item, null);
}
else
{
view = convertView;
}
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);
Person person = lists.get(position);
tv_name.setText(person.getName());
tv_phone.setText(person.getPhone());
return view;
}
}
}
16今日总结
[1]数据库如何创建(掌握)
定义一个类继承SqliteOpenHelper
sqliteDatabase:操作数据库
oncreate方法:当数据库第一次创建的时候调用 特别适合做表结构的初始化
onupgrade方法:当数据库版本进行更新的时候调用
[2]第一种方式对数据库进行增删改查(练习)
传统的SQL语句
[3]谷歌工程师给我们提供操作数据库的api(掌握)
[4]命令行工具可以打开数据库 sqlite3(练习)
[5]数据库的事务(练习)
[6]listview 显示数据 需要数据适配器(掌握)
[7]baseAdapter(掌握)
[8]获取打气筒的常见api(掌握)
<1>view = View.inflate(getApplicationContext(), R.layout.item, null);
<2>view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
<3>LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, null); [9]ArrayAdapter(掌握)
[10]simpleAdapter(了解)
只言片语任我说,提笔句句无需忖。落笔不知寄何人,唯有邀友共斟酌。