12.Android-SQLiteOpenHelper使用

来源:https://www.cnblogs.com/lifexy/archive/2020/01/17/12206278.html
-Advertisement-
Play Games

1.SQLite介紹 SQLite,是一款輕型的資料庫,它的優缺點有如下: 輕量級,適合嵌入式設備,並且本身不依賴第三方的軟體,使用它也不需要“安裝”。 併發(包括多進程和多線程)讀寫方面的性能不太理想。可能會被寫操作獨占,從而導致其它讀寫操作阻塞或出錯 2.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("\r\n 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;
    }
    
}

 

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 註意:非root用戶必須要有sudo許可權 一、安裝前的準備 1.查看當前主機是否有docker組 若沒有輸出結果則新建 再次查看,發現已經有了docker組 2.新增擁有sudo許可權的用戶(若知道root和其他擁有sudo許可權的系統用戶密碼,跳到3;若都沒有,必做) 修改該用戶的密碼 為新增的用戶添 ...
  • 在下這幾天發現我的VPS 總是莫名遭受到 江蘇鎮江那邊的IP 登錄請求攻擊 ,跟蹤了下路由,發現ip是從蒙古那邊出去的,然後意識到可能是有掃描埠的。。 方法一: 現在的互聯網非常不安全,很多人沒事就拿一些掃描機掃描ssh埠,然後試圖連接ssh埠進行暴力破解(窮舉掃描),所以建議vps主機的空間 ...
  • 簡介 Zookeeper下載 官網地址:點我直達 百度雲盤:點我直達 踩坑錄 官網下載一定要下載帶bin的 要不然zookeeper起不起來,找不到載入類,原來從版本3.5.5開始,帶有bin名稱的包才是我們想要的下載可以直接使用的裡面有編譯後的二進位的包,而之前的普通的tar.gz的包裡面是只是源 ...
  • 創建網路 創建配置文件 vim /etc/libvirt/qemu/networks/nfsnobody.xml 創建一個名為nfsnobody的虛擬網路 啟動網路並驗證 virsh 虛擬網路管理命令 增加虛擬網卡 臨時增加 永久增加 ...
  • 建站需要用伺服器,在伺服器選購過程中,除了常見的CPU、記憶體、硬碟、帶寬等配置以外,用戶還需要自行選擇操作系統,大多數雲伺服器都使用Windows Server或Linux操作系統: Windows系統 Windows Server是專為伺服器設計的專有操作系統,包括Microsoft開發的伺服器應 ...
  • 恢復內容開始 Redis數據存儲命令 1. 字元串 Redis字元串的值可以為三種類型: 位元組串(byte string) 整數 浮點數 命令 |公式| 描述 | | GET | GET key name | 獲取存儲在給定鍵中的值 SET | SET key name value name | 設 ...
  • 今天測試Linux 各個軟體源 ,發現mysql 配置官方源之後,yum install -y mysql 安裝了 mysql lastst 最新版, 安裝完之後,奇葩的是沒有提示輸入密碼, 所以 mysql 可以進入 提示輸入密碼,沒有密碼, 再經過幾個折騰,包括什麼跳過密碼驗證等等方法試過之後還 ...
  • 先上GitHub地址:Hugo 一句話描述該框架,以Log的形式告訴我們某個方法傳入的每一個參數以及返回值,以及調用的activity 時間 等其他信息 非常適用方便代碼調試 引入框架: 根目錄下的build.gradle app下的build.gradle 使用方法: 在class前或是方法前加上 ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...