第二天

1、数据库介绍(SQLite)
        什么情况下使用数据库?
        在有大量相似的数据存储的时候,就需要用到数据库
File类在什么时候创建文件?
    在调用输出流的时候创建
抽象类的做法:继承下,然后重写方法
2、数据库的创建
      [1]、创建一个类继承SQLiteOpenHelper
    
    
  1. /*
  2. 构造方法参数说明
  3. context : 上下文
  4. name : 数据库名称
  5. factory : 相当于结果集ResultSet,为空就行
  6. version : 数据库版本号,必须要大于等于1,并且只能升级不能降级使用
  7. */
  8. public class MyOpenHelper extends SQLiteOpenHelper {
  9. public MyOpenHelper(Context context) {
  10. super(context, "pr.db", null, 1);
  11. }
  12. //数据库第一次创建的时候调用,特别适合做表结构的初始化
  13. @Override
  14. public void onCreate(SQLiteDatabase sqLiteDatabase) {
  15. }
  16. //数据库升级的时候调用,这个方法适合做表结构的更新
  17. @Override
  18. public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
  19. }
    [2]  实例化MyOpenHelper,获取数据库对象
     
     
  1. MyOpenHelper myOpenHelper = new MyOpenHelper(getApplicationContext());
  2. //如果数据库未创建就会首先创建数据库,如果已经创建,那么就以读写方式打开
  3. SQLiteDatabase writableDatabase = myOpenHelper.getWritableDatabase();
  4. //如果数据库未创建就会首先创建数据库,如果已经创建,那么就以读写方式打开 和
  5. //getWritableDatabase()相比, 如果磁盘满了的话,这个方法会返回一个只读对象
  6. SQLiteDatabase readableDatabase = myOpenHelper.getReadableDatabase();


                
3、 数据库的onCreate()和onUpgrade()
    onCreate()在数据库创建的时候调用,适合进行初始化,在SQLite中id一般写成_id,SQlite底层不区分数据类型,全部以String类型存储
    意外收获:
        [1] 添加数据库表的列 alter table table_name add column_name 类型
        [2] 修改MySQL的密码
           
   
   
  1. 这种方式也需要先用root命令登入mysql,然后执行:
  2. SET PASSWORD FOR root=PASSWORD('123456');

           
4、使用SQL语句对数据库进行增删改查
        [1]添加一条数据    ,删除,修改操作都相似
        
   
   
  1. readableDatabase.execSQL("insert into table info(name,phone)value(?,?)",new Object[]{"zhangsan","13888888"});
        [2] 查找的方法
    
    
  1. //查询会返回一个Cursor对象,这个对象很像ResultSet,使用moveToNext()进行移动, 
  2. Cursor cursor = readableDatabase.rawQuery("select * from info", null);
  3. if(cursor != null && cursor.getCount() > 0){
  4. while(cursor.moveToNext()){
  5. //列标是从0开始的
  6. Log.d("MainActivity",cursor.getString(1));
  7. }
    [3]
       优点:灵活,适合多表查询
        缺点:容易写错
    [4] 打开sqlite数据库文件,控制台语句
        sqlite3 数据库文件
    [5] 改变dos的编码方式语句
        chcp 936  改为gbk编码
        chcp 65001 改为utf-8编码
5、使用谷歌封装好的api对数据库增删改查
        [1]插入一条记录
            
   
   
  1.      //[1]获取数据库对象
  2. SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  3. //[2]new一个ContentValues对象,用于传参
  4. ContentValues contentValues = new ContentValues();
  5. //[3]向ContentValues中添加数据
  6. contentValues.put("name","王五");
  7. contentValues.put("phone","110");
  8. //[4]调用google封装的api进行插入数据
  9. long info = db.insert("info", null, contentValues); //参数说明:1:表名,2:如果不添加数据,那么第二个参数就会用到,插入的数据
  10. //[5]输出插入结果
  11. if(info > 0)
  12. Toast.makeText(this,"插入成功",Toast.LENGTH_SHORT).show();
  13. else
  14. Toast.makeText(this,"插入失败",Toast.LENGTH_SHORT).show();
  15. //[6]关闭数据库
  16. db.close();
       [2]删除
   
   
  1. //[1]获取数据库对象
  2. SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  3. //[2]执行删除语句
  4. int info = db.delete("info", "name=?", new String[]{"王五"});
  5. if (info > 0)
  6. Toast.makeText(this, "删除了"+info+"条记录", Toast.LENGTH_SHORT).show();
  7. else
  8. Toast.makeText(this,"删除失败",Toast.LENGTH_SHORT).show();
  9. //[3]关闭数据库
  10. db.close();
        [3]修改数据
        
   
   
  1. //[1]获取数据库对象
  2. SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  3. //[2]new ContentValues存储需要升级的键值对
  4. ContentValues contentValues = new ContentValues();
  5. contentValues.put("name","张三");
  6. contentValues.put("phone","114");
  7. //[3]执行修改语句
  8. int info = db.update("info", contentValues, "name=?", new String[]{"王五"});
  9. //[4]查看修改结果
  10. if(info > 0)
  11. Toast.makeText(this,"修改了"+info+"条记录",Toast.LENGTH_SHORT).show();
  12. else
  13. Toast.makeText(this,"修改失败",Toast.LENGTH_SHORT).show();
  14. //[4]关闭数据库
  15. db.close();
        [4]查询数据
    
    
  1. //[1]获取数据库对象
  2. SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  3. //[2]获取Cursor
  4. Cursor info = db.query("info", null, "name=?", new String[]{"王五"}, null, null, null);
  5. //[3]遍历查看结果
  6. if(info.getCount() > 0){
  7. while(info.moveToNext())
  8. {
  9. Log.d("query",info.getString(1));
  10. Log.d("query",info.getString(2));
  11. }
  12. }
  13. //[4]关闭数据库
  14. db.close();


6、两种增删改查的优缺点
        [1]使用传统的SQL语句
              优点:灵活,适合多表查询
             缺点:容易写错
        [2]使用google封装的api
             优点:不容易写错sql语句
             缺点:不容易进行多表查询
7、android中数据库事务的介绍
    [1]数据库的事务指的是在同时进行多个任务的时候,要么同时成功,要么失败后回滚,
    [2]android中的事务的标准写法
            
   
   
  1. SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  2. db.beginTransaction(); //开启事务
  3. try {
  4. db.execSQL("update account set money=money-100 where name=\"张三\""); //这两句代表要执行的逻辑
  5. db.execSQL("update account set money=money+100 where name=\"王五\"");
  6. db.setTransactionSuccessful(); //如果两个事件都完成了,那么就设置成功的标志
  7. Toast.makeText(this,"转账成功",Toast.LENGTH_SHORT).show();
  8. } catch(Exception e){
  9. Toast.makeText(this,"服务器忙,请稍后再试",Toast.LENGTH_SHORT).show();
  10. }finally {
  11. db.endTransaction(); //结束事务
  12. }

8、ListView入门
    [1]在布局文件中定义ListView
    
    
  1. <ListView
  2. android:id="@+id/lv"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"></ListView>

    [2]定义ListView的适配器 继承baseAdapter
    
    
  1. private class MyAdapter extends BaseAdapter

    [3]实现baseAdapter中的getCount()方法和getView()方法
    
    
  1. //这个方法决定ListView一共有多少的item
  2. @Override
  3. public int getCount() {
  4. return 6; //返回多少显示多少
  5. }
  6. //这个方法决定要显示的内容
  7. @Override
  8. public View getView(int i, View view, ViewGroup viewGroup) {
  9. Button btn = new Button(getApplicationContext()); //返回什么显示什么
  10. btn.setText("点吧"+i);
  11. return btn;
  12. }
       显示如下
 
9、ListView优化
 [1]  为什么优化,对于应用内存的使用应该越少越好,并且安卓虚拟机为每个应用分配的内存也是一定的,如果大量消耗内存,唯一的结果就是用户等待,只到将无用资源释放掉才可以继续等待,那么怎么解决呢?
在getView里面有这个一个参数View view
    
   
   
  1. public View getView(int i, View view, ViewGroup viewGroup)
[2]   这个view是一个old view,当一个item被滑出屏幕并不会被直接回收,而是进入了一个backStack栈中,而这个参数 代表的就是这个对象,所以是可以复用的
    
    
  1. Button btn;
  2. if(view == null){ //如果view为空,那么说明没有可复用的对象,那么创建
  3. btn = new Button(getApplicationContext());
  4. Log.d("view","创建对象");
  5. }else{
  6. btn = (Button) view; //如果view不为空,那么就存在可复用对象
  7. Log.d("view","复用对象");
  8. }
  9. btn.setText("点吧"+i);
  [3]  如果拖得快的话,几乎每一条都是在创建对象,但是  这样更改后,只是创建了第一屏的对象,然后就是复用,就像扶梯似的,每下去一个,就会从下面出现一个
   [4] 如果在ListView中,高是wrap_content,那么android会进行多次校验,以保证内容正确的展示,这也是效率低的原因之一,所以在使用的时候,还是用match_parent比较好
10、ListView显示数据的原理
       [1] MVC:Model View Controller
            M层:处理数据和业务逻辑       (数据)
            V层:处理界面的显示结果        (view)
            C层:起到桥梁作用,来控制V层和M层通信 (adapter)
11、ListView显示复杂界面
        由于在getView()方法中的返回值决定了显示的item的形式,如何返回一个复杂的item呢?
        [1]  定义item要显示 的界面,再写一个布局文件
     [2]  将item加载到item中
        
    
    
  1. public View getView(int i, View view, ViewGroup viewGroup) {
  2. View view1;
  3. if(view == null){
  4. //[1]加载复杂布局
  5. view1 = View.inflate(getApplicationContext(),R.layout.item_layout,null);
  6. }else{
  7. view1 = view;
  8. }
  9. return view1;
  10. }
    [3给ListView设置适配器
        
   
   
  1. //获取ListView实例
  2. ListView listView = (ListView) findViewById(R.id.lv);
  3. //设置适配器
  4. listView.setAdapter(new MyAdapter());

12、获取打气筒常用api
  
   
   
  1.  //下面的这几种获取方式没有区别,使用其中的任何一种都能获取打气筒
  2. //[1]使用View的静态方法获取
  3. view1 = View.inflate(getApplicationContext(),R.layout.item_layout,null);
  4. //[2]使用布局资源加载器
  5. view1 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_layout,null);
  6. //[3]使用获取打气筒服务获取
  7. LayoutInflater systemService = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
  8. systemService.inflate(R.layout.item_layout,null);

13、arrayAdapter使用
    [1] 什么时候适合用ArrayAdapter?
            在数据相似的时候,可以是普通文本,也可以是一些其他的对象,但是在item中不能存在多个控件,这种情况ArrayAdapter无法使用
    [2] 使用方法
    
    
  1. // [1] 创建ArrayAdapter对象
  2. ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.item_layout,R.id.test1,objects);
  3. //参数一:上下文
  4. //参数二:布局文件
  5.        //参数三:布局中的具体控件
  6.        //参数四:数据对象
  7. //[2] 获取ListView对象
  8. ListView lv = (ListView) findViewById(R.id.lv);
  9. //[3] 设置适配器
  10. lv.setAdapter(adapter);

14、权重
    [1]为了大体的指定空间的位置,一般用在线性布局里面
    
   
   
  1. android:layout_weight="1"

14、simpleAdapter使用
    
  
  
  1. // [1] 获取ListView控件
  2. ListView listView = (ListView)findViewById(R.id.lv);
  3. // [2] 准备加载适配器需要的数据
  4. List<Map<String, String>> data = new ArrayList<>();
  5. Map<String,String> map1 = new HashMap<>();
  6. map1.put("name","张三");
  7. map1.put("phone","1388888");
  8. Map<String,String> map2 = new HashMap<>();
  9. map2.put("name","赵云");
  10. map2.put("phone","1388888");
  11. Map<String,String> map3 = new HashMap<>();
  12. map3.put("name","关羽");
  13. map3.put("phone","1388888");
  14. Map<String,String> map4 = new HashMap<>();
  15. map4.put("name","刘备");
  16. map4.put("phone","1388888");
  17. Map<String,String> map5 = new HashMap<>();
  18. map5.put("name","貂蝉");
  19. map5.put("phone","1388888");
  20. Map<String,String> map6 = new HashMap<>();
  21. map6.put("name","曹操");
  22. map6.put("phone","1388888");
  23. data.add(map1);
  24. data.add(map2);
  25. data.add(map3);
  26. data.add(map4);
  27. data.add(map5);
  28. data.add(map6);
  29. // [3] 加载适配器
  30. /**
  31. * 适配器的参数说明
  32. * 参数一:上下文
  33. * 参数二: List<Map<java.lang.String, ?>> data,
  34. * 参数三:资源文件
  35. * 参数四、五:对应显示的内容from to
  36. */
  37. SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(),data,R.layout.item_layout,new String[]{"name","phone"},new int[]{R.id.tv_name,R.id.tv_phone});
  38. // [4] 设置适配器
  39. listView.setAdapter(adapter);
15、读出数据库中的数据,然后展示在ListView中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值