安卓基础笔记2之SQLit数据库

来源:互联网 发布:服装软件有哪些 编辑:程序博客网 时间:2024/06/03 11:17
  • 知识点

    1. SQLit数据库(安卓自带的)

      • 常见数据库
      • 创建一个工具类
      • 纯sql方式操作数据库
        • 添加
        • 删除
        • 更新
        • 查询
      • 面向对象的方式操作数据库
        • 添加
        • 删除
        • 更新
        • 查询
    2. ListView(安卓核心控件)

  • ListView(理解)
  • ListView入门
  • ListView优化
  • 复杂的ListView

具体细节以及案例
  • ##### 常见数据库
    • Oracle:大型的数据库 ,性能最高
    • Mysql:小型数据库 开源的 免费的
    • DB2:大型数据库,收费
    • Sqlite:微型,免费,美国军舰(Android自带)

  • ###### 创建一个工具类继承SQLiteOpenHelper
  • 要明白的:

    • -构造方法里传的三个参数分别是什么意思 作用是什么?

      • 参数1:Context 上下文环境
      • 参数2:name 数据库文件的名称(xxx.db)
      • 参数3:factory 游标工厂,传入null使用系统默认的游标(可以理解为指向数据库中数据的指针)
      • 参数4:version 数据库版本,==必须大于1==

        • 作用:给创建的子类对象设置好数据库名字以及版本号
    • 明白OnCreate()方法什么时候使用,使用的特点是什么

      • ==当第一次创建数据库的时候调用==
      • 特点: 由系统调用,且只会调用一次
  • 思路:

    • 在==onCrate方法==里创建表
      • 创建表的SQL语句:
      • ==create table 数据表名(_id integer primary key,列名2 数据类型 约束,列名3 数据类型 约束);==
      • SQLite的主键会自动自增,不需要加auto_increment
    • 在==onUpgrade==方法内升级数据库
    • 修改表
      • ==alter table t_user add c_money float==
  • 代码

@Override    public void onCreate(SQLiteDatabase db) {//      创建表结构        String sql = "create table t_user (_id integer primary key,t_name varchar(20),t_age integer ,t_gender varchar(20))";        db.execSQL(sql);    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        String sql = "alter table t_user add c_money float";        db.execSQL(sql);    }

  • ###### 使用SQLiteOpenHelper创建数据库文件
  • 思路

    • 先写UI,创建一个按钮,点击按钮触发创建数据库事件
    • 创建工具类的对象(有参数的构造)

      • MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);
    • 通过.getReadableDatabase()或.getWriteableDatabase()来获取数据库

      • SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
    • 调用.close() 释放资源
// 创建数据库    public void create(View view) {        // 创建工具类的对象        MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,                DB_NAME, null, VERSION);        // 通过.getReadableDatabase()来获取数据库        SQLiteDatabase database = mySQLiteOpenHelper.getReadableDatabase();        // 释放资源        database.close();        Toast.makeText(this, "创建数据库成功", Toast.LENGTH_SHORT).show();    }

  • #### 纯sql方式操作数据库
  • 思路

    • 添加,删除,更新都是调用execSQL(sql,Object[]{})方法,只是sql语句不一样

      • 先写UI,创建一个按钮,点击按钮触发添加数据事件

      • 获取操作的数据库

        • ==MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);==
        • ==SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();==
      • 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式
      • 调用的是 ==execSQL(sql,Object[]{})== 方法
      • 释放资源
    • 查询
      • 先写UI,创建一个按钮,点击按钮触发添加数据事件
      • 获取操作的数据库(跟添加,删除,更新一样)
      • 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式
      • 调用 ==rewQuery(sql,String[]{})== 方法,返回值是Cursor 结果集
        • 判断结果集里是否存在下一个符合条件数据,调用 ==moveToNext()== 方法,用while循环来遍历出要查询的数据
        • 如果存在,通过字段索引,获取字段的内容,调用 ==getXxx()== 方法获取,索引从0开始
        • ==注意:通过索引获取时,是根据你查询的结果为准==
      • 释放资源
// 添加数据    public void insert(View view) {        // 获取操作的数据库        MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,                DB_NAME, null, VERSION);        SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();        // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式        String sql = "insert into t_user (t_name,t_age,t_gender) values(?,?,?)";        database.execSQL(sql, new Object[] { "王莉莉" + new Random().nextInt(100),                new Random().nextInt(108), "" + new Random().nextInt(2) });        // 释放资源        database.close();        Toast.makeText(this, "1成功", Toast.LENGTH_SHORT).show();    }    // 删除数据    public void delete(View view) {        // 获取操作的数据库        MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,                DB_NAME, null, VERSION);        SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();        // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式        String sql = "delete t_user where t_age>?";        database.execSQL(sql, new Object[] { "60" });        // 释放资源        database.close();        Toast.makeText(this, "2成功", Toast.LENGTH_SHORT).show();    }    // 更新数据    public void update(View view) {        // 获取操作的数据库        MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,                DB_NAME, null, VERSION);        SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();        // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式        String sql = "update t_user set t_name=? where t_age<?";        database.execSQL(sql, new Object[] { "王丽丽", 20 });        // 释放资源        database.close();        Toast.makeText(this, "3成功", Toast.LENGTH_SHORT).show();    }    // 查询数据    public void select(View view) {        // 获取操作的数据库        MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,                DB_NAME, null, VERSION);        SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();        // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式        String sql = "select * from t_user where t_age>?";        // 调用 rawQuery() 方法进行查询,第二个参数是string数组,返回的是一个Cursor 结果集        Cursor cursor = database.rawQuery(sql, new String[] { "50" });        // 判断结果集里是否存在下一个符合条件数据,调用moveToNext()方法,用while循环来遍历出要查询的数据        List<User> list = new ArrayList<User>();        while (cursor.moveToNext()) {            // 如果存在,通过字段索引,获取字段的内容,调用getXxx()方法获取,索引从0开始            // 注意:通过索引获取时,是根据你查询的结果为准            String name = cursor.getString(0);            int age = cursor.getInt(1);            String gender = cursor.getString(2);            User user = new User();            user.name = name;            user.age = age;            user.gender = gender;            list.add(user);        }        Log.w("tag", list.toString());        textView.setText(list.toString());        // 释放资源        database.close();        Toast.makeText(this, "5成功", Toast.LENGTH_SHORT).show();    }

  • #### 面向对象的方式操作数据库
  • 思路:
    • 添加数据
      • 先写UI,创建一个按钮,点击按钮触发添加数据事件
      • 获取操作的数据库
      • 调用 ==insert()== 方法
        • 参数1:表名
        • 参数2:一般是null
        • 参数3是一个ContenValues对象,这个类封装的是一个Map数组
          • 调用put(key,values)方法,添加数据
      • 返回值是插入的行数,==long== 类型的,如果插入为0,返回-1
    • -
// 添加数据    public void insert(View v) {        // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        // 调用insert方法,参数3是一个ContenValues对象,这个类封装的是一个Map数组        // insert 返回值是插入的行数,long类型的        ContentValues values = new ContentValues();        values.put("t_name", "王丽丽" + new Random().nextInt(20));        values.put("t_age", 20 + new Random().nextInt(10));        values.put("t_gender", "" + new Random().nextInt(2));        long len = database.insert("s_user", null, values);        database.close();        Toast.makeText(this, "在" + len + "插入了数据", Toast.LENGTH_SHORT).show();    }
  • 删除数据
    • 先写UI,创建一个按钮,点击按钮触发添加数据事件
    • 获取操作的数据库
    • 调用 ==delete()== 方法
      • 参数1:表名
      • 参数2放的是where条件
      • 参数3是参数2里面?的真实值
    • 返回值是受影响的行数,返回类型 ==int==
    • 释放资源
    • -
    // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        // 调用delete()方法,参数2放的是where条件,参数3是参数2里面?的真实值,返回值是受影响的行数,返回类型int        int len = database.delete("s_user", "t_age>?", new String[] { "20" });        database.close();        Toast.makeText(this, len + "受影响", Toast.LENGTH_SHORT).show();    }
  • 更新数据
    • 先写UI,创建一个按钮,点击按钮触发添加数据事件
    • 获取操作的数据库
    • 调用 ==update()== 方法
      • 参数1:表名
      • 参数2是一个ContenValues对象,这个类封装的是一个Map数组
        • 调用put(key,values)方法,添加数据
      • 参数3放的是where条件
      • 参数4是参数3里面?的真实值
    • 返回值是受影响的行数,返回类型 ==int==
    • 释放资源
      -
// 更新    public void update(View view) {        // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        // 调用update()方法,参数2是一个ContenValues对象,这个类封装的是一个Map数组,参数3放的是where条件,参数4是参数2里面?的真实值,返回值是受影响的行数,返回类型int        ContentValues values = new ContentValues();        values.put("t_money", "1000");        int len = database.update("s_user", values, "t_age>?",                new String[] { "19" });        database.close();        Toast.makeText(this, len + "受影响", Toast.LENGTH_SHORT).show();    }
  • 查询数据
    • 先写UI,创建一个按钮,点击按钮触发添加数据事件
    • 获取操作的数据库
    • 调用 ==query()== 方法
      • 参数1:表名
      • 参数2:要查询的字段,放到字符串数组中
      • 参数3放的是where条件
      • 参数4是参数3里面?的真实值
      • 参数5:null
      • 参数6:null
      • 参数7:排序表达式
    • 返回值返回值是 Cursor 结果集
      • 判断结果集里是否存在下一个符合条件数据,调用 ==moveToNext()== 方法,用while循环来遍历出要查询的数据
      • 如果存在,通过字段索引,获取字段的内容,调用 ==getXxx()== 方法获取,索引从0开始
      • ==注意:通过索引获取时,是根据你查询的结果为准==
    • 释放资源
    • -
public void select(View view) {        // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        // 调用了query()方法 参数2:要查询的字段,放到字符串数组中        //  参数3:就是where表达式        //  参数4:用于替换参数3中?号的真实的值,String[]数组中形式        // 参数5:null        // 参数6:null        //  参数7:排序表达式        // 返回类型是一个Cursor对象,结果集        Cursor cursor = database.query("s_user", new String[] { "*" },                "t_age>?", new String[] { "20" }, null, null, "t_age");        List<User> list = new ArrayList<User>();        while (cursor.moveToNext()) {            String name = cursor.getString(1);            int age = cursor.getInt(2);            String gender = cursor.getString(3);            User user = new User();            user.name = name;            user.age = age;            user.gender = gender;            list.add(user);        }        database.close();        Toast.makeText(this, list.toString(), Toast.LENGTH_SHORT).show();    }

  • ##### 数据库升级
  • 思路:
    • 更新数据库:
      • ==注意,只能升版本,不能降版本==
    • 先写UI,创建一个按钮,点击按钮触发添加数据事件
    • 获取操作的数据库
    • 设置版本号,必须大于上一个版本号
    • 释放资源
// 更新数据库    public void shengji(View view) {        // 更新数据库:注意,只能升版本,不能降版本        // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        database.close();        Toast.makeText(this, "升级成功", Toast.LENGTH_SHORT).show();    }
  • ###### 数据库事物(模拟转账)
  • 对事物的理解:
  • 同时执行的多个数据库操作,要么同时成功,要么同时失败,不能出现一个成功一个失败的情况,==事物就是为了确保安全性的==
  • 思路:
    • 先写UI,创建一个按钮,点击按钮触发添加数据事件
    • 获取操作的数据库
    • 开启事物,调用了 ==beginTransaction()== ;方法
    • 提交事物, ==setTransactionSuccessful()==
    • 关闭事务, ==endTransaction()==

- 释放资源

// 开启事物    public void change(View view) {        // 获取工具类的对象        MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,                DB_USER, null, VERSION);        // 通过.getReadableDatabase()创建数据库        SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();        // 更新表中数据,进行模拟转账操作!        // 开启事物,之后的代码都是在临时内存中执行的,并未真正的写入到数据库文件中        database.beginTransaction();        String sql = "update s_user set t_money = t_money-500 where t_name=?";        database.execSQL(sql, new Object[] { "jjjj" });        String sql2 = "update s_user set t_money = t_money+500 where t_name=?";        database.execSQL(sql2, new Object[] { "王丽丽" });        // 提交事物,事物只有提交了才会写到数据库中        database.setTransactionSuccessful();        // 使用完后关闭事务功能        database.endTransaction();        database.close();        Toast.makeText(this, "转账成功", Toast.LENGTH_SHORT).show();    }

  • ###### ListView(理解)
    • 对ListView的理解:
      • ListView是一个可以放很多条目的控件,可以滑动,可以显示一个数据集,如果数据超出屏幕可以上下滑动
      • ==注意,ListView的宽高必须设置为match_parent,不能使用wrap_content。只有加了id才能在布局中看到示例页面==
      • 使用ListView一般都会使用适配器Adapter,在适配器一般会用Adapter的子类BaseAdapter
        • ==getCount()==:ListView一共有多少个条目
        • ==getView()==:设置每一个条目数据,==最后一定要返回对象==
          • ==注意:界面上显示多少个条目该方法就调用多少次,之后滚出来一个条目就调用一次==。
          • ==public View getView(int position, View convertView, ViewGroup parent)==
          • 有三个参数
          • 参数一:int position,放的是索引,跟集合的索引是一样的
          • 参数二:View convertView 一个可以复用的view控件
          • 参数三:一般是null
        • getItem():返回每个条目的对象
        • getItemId():返回当前条目位置。

- 如果是操作是一个TextView,可以用 ==ArrayAdapter== ,这个类底层就已经实现好了,只需要用就行

  • ###### ListView入门
  • 思路:

    • 在main xml中创建一个ListViewko 控件
    • 在MainActivity写业务逻辑
      • 创建一个成员集合,来存放数据
      • 初始化ListView
      • 设置快速滑动 调用 .setsetFastScrollEnabled(true);
      • 设置适配器调用setAdapter()
      • 参数传的一个Adapter一个子类BaseAdapter对象,
      • 创建一个类去继承BaseAdapter,重写BaseAdapter的方法
        • 在getCount()方法里获取总共的条目
        • 在getView里创建一个textView(可以直接new一个)
        • 定义一个字符串根据索引获取集合里的内容
        • 调用 .setText()给TextView赋值
  • ListView优化
  • 为了防止内存溢出

- 在getView()方法里复用convertView

     view view=null;     if(convertView==null){     view = View.inflate(MainActivity.this, R.layout.listview_my, null);//创建view时,调用inflate()方法,获取id时是获取view存在的xml中的xml名字:R.layout.listview_my     }else {        view = convertView;    }

- ###### 复杂的ListView
- 思路:
- 先在main xml 创建一个ListView 控件
- 自己定义一个 xml 放的是存在ListView里面的布局
- 在MainActivity里面写业务逻辑
- 创建一个成员集合,来存放数据
- 初始化ListView
- 设置快速滑动 调用 ==.setsetFastScrollEnabled(true);==
- 设置适配器调用==setAdapter()==
- 参数传的一个Adapter一个子类BaseAdapter对象,
- 创建一个类去继承==BaseAdapter==,重写BaseAdapter的方法
- 在 ==getCount()== 方法里获取总共的条目
- 要用ListView优化->>>(上一个优化代码)
- 在getView里创建一个View
- 获取view资源

            ```            ImageView imageView = (ImageView) view.findViewById(R.id.image);            TextView name = (TextView) view.findViewById(R.id.name);            TextView ageTextView = (TextView) view.findViewById(R.id.age);            TextView genderTextView = (TextView) view.findViewById(R.id.gender);            ```        - **注意:获取View资源一定要调用==View的findViewById==(R.id.image)**          - 调用  ==.setText()== 给TextView赋值              ```            name.setText(user.name);              ageTextView.setText(user.age+"");              genderTextView.setText(user.gender);            ```        - 给条目添加图片

- 具体代码

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 初始化listview        listView = (ListView) findViewById(R.id.contects);        for (int i = 0; i < 100; i++) {            User user = new User();            user.name = "khk"+i;            user.age = i;            user.gender = "女"+i;            alist.add(user);        }//      设置滑动加速器        listView.setFastScrollEnabled(true);//      添加适配器        listView.setAdapter(new BaseAdapter() {            @Override            public View getView(int position, View convertView, ViewGroup parent) {//              获取view对象                View view =null;                if (convertView==null) {                    view = View.inflate(MainActivity.this, R.layout.listview_my, null);                }else {                    view = convertView;                }//              根据索引获取数据                User user = alist.get(position);//              获取view资源                ImageView imageView = (ImageView) view.findViewById(R.id.image);                TextView name = (TextView) view.findViewById(R.id.name);                TextView ageTextView = (TextView) view.findViewById(R.id.age);                TextView genderTextView = (TextView) view.findViewById(R.id.gender);                name.setText(user.name);                ageTextView.setText(user.age+"");                genderTextView.setText(user.gender);//              给条目添加图片                switch (position%10) {                case 0:                    imageView.setImageResource(R.drawable.iv0);                    break;                case 1:                    imageView.setImageResource(R.drawable.iv1);                    break;                case 2:                    imageView.setImageResource(R.drawable.iv2);                    break;                case 3:                    imageView.setImageResource(R.drawable.iv3);                    break;                case 4:                    imageView.setImageResource(R.drawable.iv4);                    break;                case 5:                    imageView.setImageResource(R.drawable.iv5);                    break;                case 6:                    imageView.setImageResource(R.drawable.iv6);                    break;                case 7:                    imageView.setImageResource(R.drawable.iv7);                    break;                case 8:                    imageView.setImageResource(R.drawable.iv8);                    break;                case 9:                    imageView.setImageResource(R.drawable.iv9);                    break;                default:                    break;                }                return view;            }            @Override            public int getCount() {//              获取条目的个数                return alist.size();            }            @Override            public long getItemId(int position) {                return 0;            }            @Override            public Object getItem(int position) {                return null;            }        });    }
- 计时器:
  • 步骤:

    1. 在LinearLayout定义一个button和一个ListView控件
      • 先分配button的空间,把ListView的高度设置match…
      • 也可以设置权重
    2. 获取ListView和button
    3. 点击按钮获取当前时间

      • 调用SimpleDataFormat里面format()方法

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String timeString = format.format(new Date());timeList.add(timeString);
    4. 定义一个集合接收时间字符串

    5. Adapter里有一个方法:notifyDataSetChange() ==让arraylistview(ListView)更新一下数据,重新调用Adapter的getCount和getview();==
    6. //list集合有一个add(adaption,String)让添加的数据加载第一条list.add(0,要添加的数据);
    7. 让ListView滚动到最后一个条目
      • 方法一.
        • 平滑 调用 ==smoothScrollToPosition(一般是放的最后一个条目的索引)== 方法
      • 方法二.
      • 不平滑 让ListView定位定位到哪个条目 调用 ==setSelection()==;

感受和问题

今天主要学了SQLite 和ListView控件 数据库存储数据的两种方式,出现了大量的新方法,虽然操作数据时很多都是相似的,但是大部分都是需要记得东西,感觉一下子接受这些东西有些吃力,可能手速还是跟不上,练习的时间总感觉不够用.
在练习的时候总会因为一些粗心犯了一些很低级的错误,在使用这些方法时容易记混里面参数的意思,在学习ListView时,感觉吃力很多,新单词有些多,容易记混使用方法

经过这些天的学习,明白了就业班和基础班的区别,相比之下在基础班节奏还是慢的,明白了不能拿在基础班的态度,对待就业班,努力的去改善自己的学习方法和节奏,也慢慢的去适应就业班,跟着节奏一点一点的往前跟,希望自己不要掉队,加油!!!

0 0