• 12.Android-SQLiteOpenHelper使用


    1.SQLite介绍

    SQLite,是一款轻型的数据库,它的优缺点有如下:

    • 轻量级,适合嵌入式设备,并且本身不依赖第三方的软件,使用它也不需要“安装”
    • 并发(包括多进程和多线程)读写方面的性能不太理想。可能会被写操作独占,从而导致其它读写操作阻塞或出错

    2.SQLiteOpenHelper介绍

    为了在本地创建SQLite数据库,我们需要创建一个SQLiteOpenHelper的子类,这里取名的为MyOpenHelper类,然后还要写构造方法来初始化父类、以及abstract修饰的抽象方法:onCreate(SQLiteDatabase)、onUpgrade(SQLiteDatabase,int,int).

     

    2.1 为什么要创建SQLiteOpenHelper的子类(MyOpenHelper类)?

    因为SQLiteOpenHelper不知道我们要创建的数据库是什么名字,以及表的内容,所以我们要创建MyOpenHelper类.

     

    3.SQLiteOpenHelper构造方法

    构造方法用来创建数据库文件的,构造方法如下:

    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version);
    //第一个参数:上下文
    //第二个参数:数据库文件的名字,如果传入null 则表示创建临时数据库,在应用退出之后,数据就会丢失
    //第三个参数:游标工厂 如果使用系统默认的游标工厂就传入null,一般都填null
    //第四个参数:数据库的版本号 用版本号来控制数据库的升级和降级  版本号从1开始

    比如创建一个demo.db,我们只需要在MyOpenHelper类构造方法里填入下面代码即可:

    super(context, "demo.db", null, 1);

    4.public abstract void onCreate (SQLiteDatabase db)

    • 参数db : 数据库对象,这里通过db.execSQL(String)来创建表.

    onCreate用来创建数据库表结构的,该函数在第一次创建数据库时调用,也就是在调用SQLiteOpenHelper类的getWritableDatabase()或者getReadableDatabase()时会调用该方法,如下图所示:

     可以看到只有调用getWritableDatabase()或者getReadableDatabase()时,才会真正创建数据库。

    • getReadableDatabase() : 获取一个只读数据库(不能写入)
    • getWritableDatabase ()  :  获取一个可写的数据库,不再操作的时候,一定要close()关闭数据库,如果磁盘已满,获取将会报错.

     

    比如创建一个student学生表,标题分别为id、name、score、class,填入下面代码即可:

    5.public abstract void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion)

    • db  :  数据库对象,通过db.execSQL(String)来执行sql语句
    • oldVersion    : 显示之前旧的数据库版本。
    • newVersion  : 显示升级之后的新数据库版本。

    当数据库需要升级时调用。使用此方法删除表、添加表或执行升级到新模式版本所需的任何其他操作。

    如果添加新列,可以使用ALTER TABLE将它们插入活动表。如果重命名或删除列,可以使用ALTER TABLE重命名旧表,然后创建新表,然后用旧表的内容填充新表。

    6.数据库增删改查

    实现了SQLiteOpenHelper的子类(MyOpenHelper类)后,就有了数据库了,接下来我们便可以对SQLiteDatabase进行数据库增删改查

    6.1 通过SQLiteDatabase getWritableDatabase()来获取SQLiteDatabase类.

    SQLiteDatabase类中常用方法如下所示:

    public Cursor rawQuery (String sql, String[] selectionArgs);
    // rawQuery:查询数据库内容,并将查询到的结果集保存在Cursor游标类中,并返回.
    // sql:填入select查询语句
    // selectionArgs:如果sql参数填入的内容是正常语句,则这里填NULL,如果是where子句中包含?,则将会被selectionArgs中的值替换.
    
    void  execSQL(String sql);
    //用来执行INSERT、UPDATE 或 DELETE 的sql语句

    Cursor类游标默认是指向所有结果之前的一行,然后通过moveToNext()方法就能获取每一行结果的内容

    示例如下-读出student表里的内容:

      SQLiteDatabase database =  new MyOpenHelper(this).getWritableDatabase();  //获取数据库
    
      Cursor cursor = database.rawQuery("select * from student", null);  //查询student表内容
    
    
      while (cursor.moveToNext()) {
    
         //可以通过 getXXX方法 获取每一行数据
         String name = cursor.getString(cursor.getColumnIndex("name"));  //获取当前游标所在行下的name列内容
         String score = cursor.getString(cursor.getColumnIndex("score"));//获取当前游标所在行下的score列内容
         System.out.println("name=" + name + " score =" + score);
    
        }
    
      cursor.close();
      database.close();

     

    7.安卓示例-查询添加删除示例

    界面如下:

     

    操作示例如下:

     

    如下图所示,可以看到我们刚刚操作的数据库:

     

    打开后,如下图所示,就可以看到我们刚刚写入的数据:

     

    8.具体代码实现

    8.1 activity_main.xml如下所示:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
    
        <EditText
            android:id="@+id/et_query"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="这里显示要查询的内容"
            android:textSize="12sp"
            android:minLines="10" />
        
        <Button 
            android:id="@+id/btn_query"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@id/et_query"
            android:text="查询内容"
            />
     
        
        <TextView
            android:id="@+id/textView1"
            
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@id/btn_query"
            
            android:paddingTop="50dp"
            android:text="名字:" />
    
        <EditText
            android:id="@+id/et_nameAdd"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/textView1"
            android:layout_toRightOf="@id/textView1"
            android:textSize="11sp" />
        
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/et_nameAdd"
            android:layout_alignBaseline="@id/textView1"
            android:text="成绩:" />
    
        <EditText
            android:id="@+id/et_scoreAdd"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/textView1"
            android:layout_toRightOf="@id/textView2"
            android:textSize="11sp" />
        
         <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/et_scoreAdd"
            android:layout_alignBaseline="@id/textView1"
            android:text="班级:" />
    
        <EditText
            android:id="@+id/et_classAdd"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/textView1"
            android:layout_toRightOf="@id/textView3"
            android:textSize="11sp" />
        
        
        <Button
            android:id="@+id/btn_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/textView1"
            android:layout_toRightOf="@id/et_classAdd"
            android:text="添加"
            android:textSize="11sp" />
       
        
        <TextView
            android:id="@+id/textView4"
            
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentBottom="true"
            android:paddingBottom="20dp"
            android:text="要删除的id:" />
    
        <EditText
            android:id="@+id/et_deleteId"
            android:layout_width="140dp"
          
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/textView4"
            android:layout_toRightOf="@+id/textView4"
            android:textSize="11sp" />
        
         <Button
            android:id="@+id/btn_deleteId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/et_deleteId"
            android:layout_alignParentRight="true"
            android:textSize="13sp" 
            android:text="删除"/>
         
    </RelativeLayout>

    8.2 MyOpenHelper.java如下所示:

    public class MyOpenHelper extends SQLiteOpenHelper {
    
        public MyOpenHelper(Context context) {
            //这里创建一个数据库,名字为demo.db
            super(context, "demo.db", null, 1);
            
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            //onCreate用来创建数据库表结构的,这里创建一个student学生表,标题分别为id、name、score、class
            db.execSQL("CREATE TABLE student ("
                    +"id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    +"name VARCHAR(40) NOT NULL, "
                    +"score INTEGER NOT NULL, "
                    +"class VARCHAR(40) NOT NULL)");
            
            System.out.println("onCreate 创建表");
        }
        
        
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //实现版本升级的函数
            System.out.println("onupgrade  oldVersion"+oldVersion+"newVersion"+newVersion);
            
            switch (oldVersion) {
            case 1:            //如果之前版本号为1.(标题只有id、name、score、class),那么将添加科目和考号标题
                db.execSQL("alter table info add age 科目");
                db.execSQL("alter table info add age 考号");
                break;
    
            }
            
        }
    
    }

    8.3 MainActivity.java如下所示:

    public class MainActivity extends Activity {
    
        private MyOpenHelper openHelper;
        private EditText et_nameAdd;
        private EditText et_scoreAdd;
        private EditText et_classAdd;
        private EditText et_query;
        private EditText et_deleteId;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            openHelper = new MyOpenHelper(this);
            
            et_nameAdd = (EditText)findViewById(R.id.et_nameAdd);
            
            et_scoreAdd = (EditText)findViewById(R.id.et_scoreAdd);
            
            et_classAdd = (EditText)findViewById(R.id.et_classAdd);
            
            et_query = (EditText)findViewById(R.id.et_query);
                   
            et_deleteId = (EditText)findViewById(R.id.et_deleteId);
            
            //实现查询数据库功能
            Button btn_query = (Button)findViewById(R.id.btn_query); 
            btn_query.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    
                    SQLiteDatabase readableDatabase = openHelper.getReadableDatabase();
                    
                    Cursor rawQuery = readableDatabase.rawQuery("select * from student", null);
                    
                    StringBuilder text = new StringBuilder();
                    
                    text.append("query length:"+String.valueOf(rawQuery.getCount()));
                                    
                    while(rawQuery.moveToNext()){
                        
                        String id = rawQuery.getString(rawQuery.getColumnIndex("id"));//获取当前游标所在行下的id列内容
                        String name = rawQuery.getString(rawQuery.getColumnIndex("name")); //获取当前游标所在行下的name列内容
                        String score  = rawQuery.getString(rawQuery.getColumnIndex("score"));//获取当前游标所在行下的score列内容
                        String classs = rawQuery.getString(rawQuery.getColumnIndex("class"));//获取当前游标所在行下的class列内容
                        
                        text.append("
     id:"+id+" 名字:"+name+" 成绩:"+score+" 班级:"+classs);
                    }
                    
                    rawQuery.close();
                    readableDatabase.close();
                    
                    et_query.setText(text.toString());
                }
            });
            
            //实现添加数据项功能
            Button btn_add = (Button)findViewById(R.id.btn_add); 
            btn_add.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    
                    String name = et_nameAdd.getText().toString().trim();
                    String score =  et_scoreAdd.getText().toString().trim();
                    String classs = et_classAdd.getText().toString().trim();
                    
                    if(TextUtils.isEmpty(name)||TextUtils.isEmpty(score)||TextUtils.isEmpty(classs))
                    {
                        Toast.makeText(MainActivity.this, "添加的内容不能为空", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    String sql = "INSERT INTO student(name, score,class) "
                       +"VALUES ('"+name+"', "+score+", '"+classs+"')";
    
                    SQLiteDatabase writableDatabase = openHelper.getWritableDatabase();
                    
                    writableDatabase.execSQL(sql);
                    writableDatabase.close();
                    
                    System.out.println(sql);
                }
                
            });
            
           //实现通过ID号来删除某一行数据项功能
            Button btn_deleteId = (Button)findViewById(R.id.btn_deleteId); 
            btn_deleteId.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    
                    String id = et_deleteId.getText().toString().trim();
                    
                    if(TextUtils.isEmpty(id)){
                        
                        Toast.makeText(MainActivity.this, "删除的内容不能为空", Toast.LENGTH_SHORT).show();
                        return;
                        
                    }else if(!TextUtils.isDigitsOnly(id)){
                        
                        Toast.makeText(MainActivity.this, "请填入要删除的数字!", Toast.LENGTH_SHORT).show();
                        return;
                        
                    }
                    
                    SQLiteDatabase readableDatabase = openHelper.getReadableDatabase();
                    
                    readableDatabase.execSQL("DELETE FROM student WHERE  id = "+id+"");
                    
                    System.out.println("DELETE FROM student WHERE  id = "+id+"");
                    
                    Toast.makeText(MainActivity.this, "已删除ID"+id+"所在的一行!", Toast.LENGTH_SHORT).show();
                }
            });
            
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
        
    }

     

     

     

     

  • 相关阅读:
    [CF1398E] Two Types of Spells
    [CF1399E2] Weights Division (hard version)
    [CF1400E] Clear the Multiset
    Review 2020.10.29
    Review 2020.10.11
    [CF1409F] Subsequences of Length Two
    [CF1413E] Solo mid Oracle
    [2020CCPC威海C] Rencontre
    [2020CCPC威海B] Labyrinth
    phpredis实现简单的消息队列
  • 原文地址:https://www.cnblogs.com/lifexy/p/12206278.html
Copyright © 2020-2023  润新知