《第一行代码》 6.4 SQLite数据库存储

    特点:适用于存储大量复杂的数据。

6.4.1 创建数据库

1. SQLiteOpenHelper帮助类(抽象类),助于数据库的创建和升级

(1)两个构造方法供选,一般选参数少的那个:

         SQLiteOpenHelper(参数1,参数2,参数3,参数4)

           -参数1:Context;

           -参数2:数据库名,创建数据库使用的名字就是这里指定的;

           -参数3:允许在查询数据时返回一个自定义Cursor,一般写null;

           -参数4:当前数据库的版本号,在升级时用得到。

(2)两个抽象方法需要重写

         -onCreate():创建

         -onUpgrage():升级

(3)两个重要实例方法,用于打开(没有就创建)一个数据库,都返回一个可对数据库读写的对象。

        -getReadableDatabase():磁盘满时,只可读;

        -getWritableDatabase():磁盘满时,出现异常。

(4)使用步骤:构建SQLiteOpenHelper对象——调用getReadableDatabase()/getWritableDatabase()创建。创建的数据库存储在:data/data/<package name>/databases/下。

2. 范例:使用SQLiteOpenHelper创建数据库

(1)新建类,MyDatabaseHelper.java

public class MyDatabaseHelper extends SQLiteOpenHelper {
    //建表语句
    public static final String CREATE_BOOK="create table book ("
            +"id integer primary key autoincrement, "
            +"author text, "
            +"price real, "
            +"pages integer, "
            +"name text)";
    private Context mContext;

    //构造函数
    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,int version){
        super(context, name, factory,version);
        mContext=context;
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "create succeeded",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){}
}

(2)布局,layout_main.xml

    <Button
        android:id="@+id/create_database"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="create database"/>

(3)主活动,MainActivity.java

public class MainActivity extends AppCompatActivity {
    private MyDatabaseHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper=new MyDatabaseHelper(this, "BookStore.db",null,1); //实例化对象
        Button createDatabase=(Button) findViewById(R.id.create_database);
        createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });

    }
}

(4)运行结果


    可以通过Android Device Monitor找到我们的数据库(权限问题导致无法看到,参看上一条博客),但看不到里面的内容。

(5)查看数据库内部内容

     采用adb工具。

     1. 打开cmd

     2. 输入:adb shell

     3. 输入:cd /data/data/com.example.databasetest/databases(有个s啊)

     4. 输入:ls  (是L的小写+s),这下可以看到目录里的文件了

     5. 输入:sqlite3 BookStore.db   ,现在可以对这个数据库进行管理操作啦

     6. 输入:.table   ,查看数据库里的表。android_metadata是默认的

     7. 输入:.schema    ,查看建表时的语句


6.4.2 升级数据库

1. onUpgrade()方法

2. 范例:添加一张Category表来记录图书的分类

(1)MyDatabaseHelper.java   中增加建表语句

 public static final String CREATE_CATEGORY="create table category ("
            +"id integer primary key autoincrement, "
            +"category_name text, "
            +"category_code integer)";
 @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "create succeeded",Toast.LENGTH_SHORT).show();
    }

(2)MyDatabaseHelper.java   当表已存在时,删除重建

 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }

(3)MainActivity.java    执行onUpgrade()

 dbHelper=new MyDatabaseHelper(this, "BookStore.db",null,2);//只要把版本号改成2

(4)查看结果

    按照上一节的办法,采用adb工具查看BookStore.db数据库内是否多了一个表。

(5)遇到了一个问题——可以打开data,可是当输入sqlite3 BookStore.db,出错:unable to open database file.

      郁闷:明明都能打开data目录了,说明读写权限应该没错才是呀。难道是database的读写权限变了,打开Android Device Monitor一看,还真是!

     解决办法:参看上一节的那个办法,再次改变data的权限(adb shell——su——chmod -R 777 /data——chmod -R 777 /data/data)这就好啦


6.4.3 添加数据

1. insert()方法

    语法:insert(参数1,参数2,参数3)

           -参数1:表名

           -参数2:在未指定添加数据的情况下给某些为空的列自动赋值null,一般不用该功能,填null就好

           -参数3:ContentValues对象,提供一系列重载的put()方法。用于向ContentValues中添加数据。

2. 范例:添加数据

(1)activity_main.xml  ,放个“添加”按键

<Button
        android:id="@+id/add_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Add Data"/>

(2)MainActivity.java    ,为按键添加事件

Button addData =(Button) findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db=dbHelper.getWritableDatabase();
                ContentValues values=new ContentValues();
                //组装第一条数据
                values.put("name","The Da Vinci Code");
                values.put("author","Dan Brown");
                values.put("pages",454);
                values.put("price",16.96);
                db.insert("Book", null, values);
                values.clear();
                //组装第二条数据
                values.put("name","The Lost Symbol");
                values.put("author","Dan Brown");
                values.put("pages",520);
                values.put("price",12.96);
                db.insert("Book", null, values);
            }
        });

(3)运行结果

  采用adb工具查看book中数据是否已添加成功。打开BookStore.db,然后输入“select * from Book;“来查看里面的数据。

!!!一定要在SQL语句后加“;”



6.4.4 更新数据

1. update()方法

    语法:update(参数1,参数2,参数3,参数4)

           -参数1:表名

           -参数2:ContentValues对象

           -参数3、4:用于约束更新某一行或某几行中的数据,不指定则默认更新所有行

2. 范例:修改一本书的价格

(1)activity_main.xml  ,加个“更新数据”按钮

 <Button
        android:id="@+id/update_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Update Data"/>

(2) MainActivity.java   ,响应按键

Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =dbHelper.getWritableDatabase();
                ContentValues values=new ContentValues();
                values.put("price",9.9);
                db.update("Book",values,"name=?",new String[]{"The Da Vinci Code"});
            }
        });

(3)运行结果



6.4.5 删除数据

1. delete()方法

    语法:delete(参数1,参数2,参数3)

           -参数1:表名

           -参数1、2:用于约束更新某一行或某几行中的数据,不指定则默认更新所有行

2. 范例:删除页码大于500的书本记录

(1)activity_main.xml  ,加个“删除数据”按钮

 <Button
        android:id="@+id/update_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Update Data"/>

(2) MainActivity.java   ,响应按键

 Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db=dbHelper.getWritableDatabase();
                db.delete("Book","page > ?",new String[]{"500"});
            }
        });

(3)运行结果


520页的那条记录不见了



6.4.6 查询数据

1. query()方法,至少有7个参数

    语法:query(参数1,参数2,参数3....参数7)

    -参数1:表名

    -参数2:指定查询哪几列,不指定则默认查询所有列;

    -参数3、4:用于约束查询某一行/某几行的数据,不指定则默认查询所有列(就像约束条件);

    -参数5:指定需要去group by的列,不指定则表示不对查询结果进行group by操作;

    -参数6:对group by之后的数据进行进一步地过滤,不指定则不进行过滤;

    -参数7:指定查询结果的排序方式

    返回值是Cursor对象。

2. 范例:

(1)layout_main.xml   ,加个按键

    <Button
        android:id="@+id/query_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:text="Query Data"/>

(2)MainActivity.java     ,响应按键

 Button queryData=(Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                //查询Book表中的所有数据
                Cursor cursor = db.query("Book", null, null, null, null, null, null);
                if (cursor.moveToFirst()) {  //将数据的指针移到第一行的位置
                    do {
                        //遍历Cursor对象,取出数据并打印
                        //getCulumnIndex():获得某一列在表中对应位置的索引,将这个索引传到相应的取值方法中
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        Log.d("MainActivity", "book name is " + name);
                        Log.d("MainActivity", "book author is " + author);
                        Log.d("MainActivity", "book pages are " + pages);
                        Log.d("MainActivity", "book price is " + price);
                    } while (cursor.moveToNext());
                }
                cursor.close();
            }
        });

(3)运行结果



6.4.7 使用SQL操作数据库

    和前面所学方法地位是平行的,对于SQL大神来说可能更喜欢用这个,作为小白,我也了解一下。


猜你喜欢

转载自blog.csdn.net/qq_39915585/article/details/79753924
6.4