SQLite(数据库)的应用

数据库的特点及作用:

1.一个数据库中可以存储多张数据表
2.每一张数据表的作用。类似于excel中表格的作用,即用于存储n多计较复杂的数据
如:存储学生信息    

3.数据库的种类:
MySql   多用于处理电脑端,网页端的数据库
Oracle   与MySql作用类似,只不过能够比MySql存储更多数据,处理更复杂的数据
SQLite   轻量级数据库,多用于负责处理手机端或者平板电脑端的数据库操作

SQLite简介

是一款微型数据库,它用在嵌入式系统中,比如Android系统。它跟传统的数据库有比较大的差别。省略了大多数的功能,比如权限,管理、触发器、存储过程等。只保留对数据库最常用到的增删改查操作。(弱类型的数据库)。
使用方式:

1、自产自销方向(在本工程内创建数据库并使用,不使用别人工程中的数据库,也不让别人使用自身创建的数据库)

创建SQLiteOpenHelper的子类,并按照报错要求添加重写方法和构造方法

private SQLiteDatabase db;
    /**
     * 构造方法
     * @param context  上下文环境,此处的作用:通过此环境获取到程序包名,可以确定数据库文件的存储位置
     * 默认位置: data/data/程序包名/databases文件内
     * 
     * @param name  设置数据库文件的名称
     * @param factory  传参时填null即可
     * @param version 设置数据库的版本号
     */
    public MyHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
        db = getReadableDatabase();
    }

    //通常会将上方的构造方法,直接修改为以下样式
    public MyHelper(Context context) {
        super(context, "ayy", null, 3);
        // TODO Auto-generated constructor stub
        db = getReadableDatabase();
    }

    /**
     * 当第一次创建数据库文件时运行此方法,通常情况下会在此方法中进行创建表的操作
     * 参数:数据库对象,可以通过此对象调用方法实现创建表,或者针对表中数据进行增删改查操作
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.i("oye", "============onCreate");
        /**
         * 通过执行创建表的sql语句实现创建表的需求
         * execSQL方法用于执行方法参数中设置的sql语句
         * 
         * 创建表的sql语句的格式为:
         * create table if not exists 表名 (列名1    列类型     primary key autoincrement,   列名2  列类型。。。。 )
         */

        db.execSQL("create table if not exists stu (_id integer  primary key autoincrement,name  text,  age  integer)");

    }

    /*
     * 当new MyHelper对象时,如果传递的版本号发生改变,就会运行此方法
     * 注意:版本号改变时只能上调,不能下调
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        Log.i("oye", "=====  onUpgrade "+oldVersion+"  "+newVersion);
        // 执行删除原有表的操作
        db.execSQL("drop table if exists stu");

        onCreate(db);
    }

onCreate方法的运行特点:

// 调用构造方法不会造成onCreate方法的运行
        helper = new MyHelper(this, "ayy", null, 3);

        /*
         * 当通过helper对象调用getReadableDatabase或者getWriteableDatabase方法时
         * 先判断默认路径是否有数据文件,如没有,则运行onCreate方法,如已存在数据库文件,则不运行onCreate方法
         * 
         * 两者的区别在于:基本是一样的,只有一种情况两者不同
         * 当数据库已经达到最大存储上限了,如果getWriteableDatabase方法得到SqliteDatabase对象
         * ,并且通过db对象还要添加数据,此时会崩溃,但是如果用getReadableDatabase方法,则不会崩溃,顶多添加失败
         */
//      helper.getReadableDatabase();

通过sql语句实现增删改查操作

//增加数据
    public void add (String name,int age) {
        /**
         * 执行添加数据的sql语句
         * insert into 表名 (列名1,列名2.。。) values (值1,值2.。。。)
         * ? 用于代表占位符,稍后可以有参数二指定的数据中的内容替代?的内容
         */
        db.execSQL("insert into stu (name,age) values(?,?)",new Object[]{name,age});

    }

//删除数据
    public void delete (int id) {
        /**
         * 执行删除的sql语句
         * delete from 表名      删除表中所有的数据
         * 
         * delete from 表名  where  条件表达式   ,  按指定条件删除内容
         */
        db.execSQL("delete from stu where _id = "+id);
    }

//修改数据
    public void update (String name,int age,int id) {
        /**
         * 执行修改的sql语句
         * update 表名   set 列1 = 值1,列2 = 值2.。。。       修改表中所有的数据
         *  update 表名   set 列1 = 值1,列2 = 值2.。。。 where  条件表达式      修改符合条件表达式的内容
         */

        db.execSQL("update stu set name= ?, age = ?  where _id = ?", new Object[]{name,age,id});
    }

//查询所有数据
    public ArrayList<Studeng> getAllData(){
        ArrayList<Studeng> list = new ArrayList<Studeng>();
        /**
         * 执行查询的sql语句
         * select * from 表名
         * 通过rawQuery方法执行sql语句,原因为:通过该方法的返回值可以取出查询到的结果
         * 返回值:Cursor对象,游标对象
         */
        Cursor cursor = db.rawQuery("select * from stu", null);
        //moveToNext:让Cursor向下挪动一行,并在挪动后将该行的所有数据存储到Cursor对象中
        //一旦返回值为false,则代表没有下一行了,即所有数据读取完毕
        while (cursor.moveToNext()) {
            String n = cursor.getString(cursor.getColumnIndex("name"));
            int a = cursor.getInt(cursor.getColumnIndex("age"));
            list.add(new Studeng(n, a));
        }

        return list;
    } 

如查询id为3到5之间的数据

    public ArrayList<Studeng> getData (int startId,int endId) {
        ArrayList<Studeng> list = new ArrayList<Studeng>();

        Cursor cursor = db.rawQuery("select * from stu where _id >= ? and _id <= ?", new String[]{startId+"",endId+""});

        while (cursor.moveToNext()) {
            String n = cursor.getString(cursor.getColumnIndex("name"));
            int a = cursor.getInt(cursor.getColumnIndex("age"));
            list.add(new Studeng(n, a));
        }
        return list;
    }

如查询id为2或者为5的数据

public ArrayList<Studeng> getDataOr (int startId,int endId) {
        ArrayList<Studeng> list = new ArrayList<Studeng>();

        Cursor cursor = db.rawQuery("select * from stu where _id = ? or _id = ?", new String[]{startId+"",endId+""});

        while (cursor.moveToNext()) {
            String n = cursor.getString(cursor.getColumnIndex("name"));
            int a = cursor.getInt(cursor.getColumnIndex("age"));
            list.add(new Studeng(n, a));
        }
        return list;
    }

模糊查询,(如查找所有姓李的)

    public ArrayList<Studeng> getDataLike (String s) {
        ArrayList<Studeng> list = new ArrayList<Studeng>();

        Cursor cursor = db.rawQuery("select * from stu where name like ?", new String[]{"%"+s+"%"});

        while (cursor.moveToNext()) {
            String n = cursor.getString(cursor.getColumnIndex("name"));
            int a = cursor.getInt(cursor.getColumnIndex("age"));
            list.add(new Studeng(n, a));
        }
        return list;
    }

通过系统方法实现增删改查:

//通过db中封装好的方法实现增加数据的操作
    public void addByMethod(String name,int age){
        /**
         * 1. String table  用于设置表名
         * 3. ContentValues对象, 用于设置要添加的数据
         * 特点:专门用于封装数据库数据的类,可以存储多组键值对,键必须是表的表名,值为想要添加的数据
         * 2. 随便写一个表中的列名即可
         * 参数二作用: 当参数二和三都为null时,在执行添加方法时程序会崩溃
         * 如果参数二不为null,参数三为null是,执行添加操作时不会崩溃,只会给表的列中添加值:NULL
         */
        ContentValues values = new ContentValues();
        values.put("name", name);
        values.put("age", age);
        /*
         * 当insert方法的返回值为-1时,代表添加失败
         * 当返回值不为-1时,该数字代表的是新添加的数据在表中对应的id的值
         */
        long id = db.insert("stu", "_id", values);
        Log.i("oye", "insert  id  "+id);
    }

public void deleteByMethod(int id){
        /*
         * String table  设置表名
         * String whereClause  删除条件
         * whereArgs  删除条件中如果有?的占位符时,通过此参数替代?的值
         * 
         * 返回值: 根据指定的删除条件成功删除了几条数据
         */
        int num = db.delete("stu", "_id="+id, null);

        Log.i("oye", "delete num  "+num);
    }

public void updateByMethod (int id,String name) {
        /**
         * table  表名
         * values  ContentValues 用于设置修改后的数据
         * whereClause  修改的条件
         * whereArgs  用于替换条件中的?的值
         */
        ContentValues values = new ContentValues();
        values.put("name", name);
        //根据指定条件,修改的条数
        int num = db.update("stu", values, "_id = ?", new String[]{id+""});
    }

public ArrayList<Studeng> getDataByMethod(){
        ArrayList<Studeng> list = new ArrayList<Studeng>();
        /**
         * 1. table 表名
         * 2. String[] 设置要查询的列名,查询所有列填null即可
         * 3. seletion    查询条件
         * 4. String[] selectionArgs  数组中的值用于替代条件中?的值
         * 5,6 合起来构成分组条件起始就是变相的where查询条件
         * 7. order by 排序    列名   asc或desc   asc升序   desc 降序
         */
        Cursor cursor = db.query("stu", null, null, null, null, null, "age desc");

        while (cursor.moveToNext()) {
            String n = cursor.getString(cursor.getColumnIndex("name"));
            int a = cursor.getInt(cursor.getColumnIndex("age"));
            list.add(new Studeng(n, a));
        }


        return list;
    }

2 进货方向(先获得别人的数据库文件,然后直接使用此文件)

1. 先拥有别人的数据库文件,然后将该文件放置在本机的sd卡或者机身内存中

 /*
         * 参数:通过openDatabase方法可直接打开准备好的数据库文件
         * 1.  要打开的数据库文件对应的存储路径
         * 2. CursorFactory,填null即可
         * 3. flag标识,用于设置数据库打开特点
         * 如:SQLiteDatabase.OPEN_READONLY 以只读方式打开数据库
         * SQLiteDatabase.OPEN_READWRITE  以读写方式打开数据库
         * SQLiteDatabase.CREATE_IF_NECESSARY    当指定路径下存在数据库文件时,则直接打开该文件
         * 当指定路径下不存在数据库文件时,会自动创建一个数据库文件,然后再打开该文件
         * 
         * 备注:如果flag设置的为 SQLiteDatabase.CREATE_IF_NECESSARY  ,那么此时openDatabase方法的作用与openOrCreateDatabase方法一致
         * */
         db =  SQLiteDatabase.openDatabase("/mnt/sdcard/home", null, SQLiteDatabase.CREATE_IF_NECESSARY);

2.SimpleCursorAdapter适配器的一种,专门用于结合数据库使用

(1)获取查询结果Cursor对象

 cursor = db.rawQuery("select * from person", null);

(2)初始化并设置适配器

/**
         * 1. Context
         * 2. 列表中每一个item显示的布局
         * 3. 数据源,此时数据源的类型是一个Cursor对象,并且此适配器,支持数据源传递为null
         * 4. 数据从哪来  ,写查询的数据表中对应的列名
         * 5. 数据到哪去 int[] ,用于填写item布局中控件的id
         * 6. flag标识,固定为:SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
         * 
         * 使用SimpleCursorAdapter时注意:
         *1. 表中主键列的名字必须是_id
         * 2.数据源的Cursor中查询时必须查询主键列
         */
        adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, 
                new String[]{"_id","name"}, new int[]{R.id.textView1,R.id.textView2}, 
                SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

        lv.setAdapter(adapter);

(3)适配器刷新方式:

// 重新读取表中所有数据
                Cursor c = db.rawQuery("select * from person", null);
                //刷新适配器
                adapter.swapCursor(c);  // 交换数据源
                adapter.notifyDataSetChanged();

数据库的事务:
作用:
1. 加速,如:使用了事务操作添加30000条数据的时间要远远少于不使用事务的
2. 提供回滚功能,用于确保数据要么完全完成操作,要么一条都不加
回滚效果如: 要添加10000条数据,但是当添加第2001条数据时,代码写错了,发生异常,才是事务会将原有已添加的2000条数据回滚删除掉.
使用方式:

public void addByTrans () {
        long start = System.currentTimeMillis();
        //1. 在数据库操作执行前,启动事务
        db.beginTransaction();
        //2. 将数据库操作部分通过try--catch包裹起来,
        try {
            for (int i = 0; i < 10000; i++) {
                //if部分用于测试事务的回滚效果
//              if (i == 2000) {
//                  db.execSQL("insert into acs (name,age) values (?,?)",new Object[]{"姓名 "+i,i+1});
//              } else {
                    db.execSQL("insert into ac (name,age) values (?,?)",new Object[]{"姓名 "+i,i+1});
//              }

            }
            //3. 在try语句块的末尾添加事务成功标识
            db.setTransactionSuccessful();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //4. try  catch语句的外面结束事务操作
        db.endTransaction();
        long end = System.currentTimeMillis();

        Log.i("oye", "通过事务添加耗时的毫秒值为:  "+(end-start));

    }

实现截取数据库中指定条数据的方式:

public Cursor getData(int start){
        /*
         * limit  后面跟2个数字
         * 数字1: 从第几行开始读取数据(行数从0开始)
         * 数字2: 总共截取出多少条数据
         * */
        return db.rawQuery("select * from pr limit ?, ?", new String[]{start+"","20"});
    }

创建能够存储图片的数据库的方式:

/**
         *  blob 是SQLite中支持存储的数据类型的一种,用于存储图片对象
         *  实际类型就是byte[]
         */
        db.execSQL("create table if not exists img (_id integer primary key autoincrement,name text,icon blob)");

向数据库中添加图片的方式:

//存入图片数据
    public void addBitmap(String name, Bitmap bitm) {

        //根据Bitmap对象得到对应的byte数组
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitm.compress(CompressFormat.PNG, 100, bos);
        //数组b中存储的就是图片数据
        byte[] b = bos.toByteArray();

        ContentValues values = new ContentValues();
        values.put("name", name);
        values.put("icon", b);
        db.insert("img", "_id", values);
    }

从数据库中取出图片的方式:

//取出图片数据方法
    public Bitmap getBitmap (int id) {

        Cursor cursor = db.rawQuery("select * from img where _id = "+id, null);

        if (cursor.moveToFirst()) {
            byte[] b = cursor.getBlob(cursor.getColumnIndex("icon"));

            return BitmapFactory.decodeByteArray(b, 0, b.length);
        }

        return null;
    }
发布了34 篇原创文章 · 获赞 3 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/The_king_of_Asia/article/details/54861738
今日推荐