1. 程式人生 > >android的資料儲存(2)(SQLiteDatebase、SQLiteOpenHelper)

android的資料儲存(2)(SQLiteDatebase、SQLiteOpenHelper)

一、android系統的整合輕量級的資料庫,SQLite只是一個嵌入式的資料引擎,專門適用於(手機,PDA)上的適量資料儲存。SQLite資料庫實際上是檔案。

二、android提供了SQLiteDatebase代表一個數據庫(底層就是一個數據庫檔案),一旦程式獲得了代表指定的SQLiteDatebase物件,接下來就可以通過SQLiteDatebase來管理資料。

(1).SQLiteDatabase有以下的靜態方法來開啟一個檔案對應的資料庫:

  • static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags):開啟地址為path的資料庫檔案。

  • static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase.CursorFactory factory):開啟或建立file所代表的SQLite資料庫檔案

  • static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory):開啟或建立path所代表的SQLite資料庫檔案

(2)對資料的操作的兩個方法。

第一個方法:使用sql語句

execSQL(String sql,Object[] bindArgs) 執行帶佔位符的SQL語句

execSQL(String sql):執行sql語句

 

第二個方法:SQLiteDatebase有專門的增刪改查的方式:

  • insert(String table,String nullColumnHack,ContentValues values):向table表中插入資料
  • update(String table,ContentValues values,String whereClause,String[] whereArgs):更新table表中的特定資料
  • delete(String table,String whereClause,String[] whereArgs):刪除table表中的特定資料
  • Cursor query(String table,String columns,String selections,String[] selectionArgs,String groupBy,String having,String orderBy):對table表執行查詢
  • Cursor query(String table,String columns,String selections,String[] selectionArgs,String groupBy,String having,String orderBy,String limit):對table表執行查詢,limit控制至多查詢幾條記錄
  • Cursor query(boolean distinct,String table,String columns,String selections,String[] selectionArgs,String groupBy,String having,String orderBy,String limit):對table表執行查詢,limit控制至多查詢幾條記錄,distinct控制是否去除重複值
  • rawQuery(String sql,String[] selectionArgs):執行帶佔位符的SQL查詢
  • beginTransaction():開始事務
  • endTransaction():結束事務

 

對於查方法都會返回一個Cursor物件,android中提供的Cursor物件類似於jdbc中的ResultSet,對於Cursor同樣提供瞭如下的方法來移動查詢結果的指標。

move(int offset):將記錄指標向下或者向上移動指定行數。

boolean moveToFirst():將記錄指標移動到第一行,如何成功返回true

boolean moveToLast():將記錄指標移動到最後一行,如果成功返回true

boolean moveToNext():將記錄指標一檔到下一行,成功返回true

boolean moveToPosition(int position):將記錄指標移動到指定行,如果成功返回true

boolean moveToPrevious():將記錄指標移動到上一行,成功返回true

一旦移動到其中一行,就可以用,getXxx()方法或者該行的資料

 

 

例項:

1、xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/e_title"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/e_content"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/sqlite_insert"
        android:text="insert"/>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/sqlite_list"/>

</LinearLayout>

2、java程式碼

public class SqLiteActivity extends AppCompatActivity {

    SQLiteDatabase db;
    ListView sq_list;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_activity);
        final TextView e_title=findViewById(R.id.e_title);
        final TextView e_content=findViewById(R.id.e_content);

        //建立資料庫,此處使用絕對路徑
        db=SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString()+"/my.db3",null);
        Toast.makeText(SqLiteActivity.this,"資料庫建立成功",Toast.LENGTH_SHORT).show();
        sq_list=findViewById(R.id.sqlite_list);

        Button sqlite_insert=findViewById(R.id.sqlite_insert);
        sqlite_insert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String tite=e_title.getText().toString();
                String content=e_content.getText().toString();

                try{
                    insertDate(db,tite,content);Cursor cursor=db.rawQuery("select * from news_inf",null);
                    inflateList(cursor);
                }catch (SQLiteException e){
                    db.execSQL("drop table if exists news_info");
                    db.execSQL("create table news_info("
                            +"news_id integer primary key autoincrement,"
                            +"news_title varchar(50),"
                            +"news_content varchar(255))");
                    Toast.makeText(SqLiteActivity.this,"表建立成功",Toast.LENGTH_SHORT).show();

                    //執行insert
                    insertDate(db,tite,content);
                    //執行查詢,查詢所有記錄
                    Cursor cursor=db.rawQuery("select * from news_info",null);
                    inflateList(cursor);
                }
            }
        });
    }

    private void insertDate(SQLiteDatabase db,String title,String content){
        //執行插入,使用含有佔位符的方法
        db.execSQL("insert into news_info values(null,?,?)",new String[]{title,content});

        Toast.makeText(SqLiteActivity.this,"插入成功",Toast.LENGTH_SHORT).show();
    }

    private void inflateList(Cursor cursor){
        //使用SimpleCursorAdapter來填充ListView
        SimpleCursorAdapter adapter=new SimpleCursorAdapter(
                SqLiteActivity.this,
                R.layout.sqlite_list_item,
                cursor,
                new String[]{"list_title","list_content"},
                new int[]{R.id.list_title,R.id.list_content},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

        //顯示資料
        sq_list.setAdapter(adapter);
    }
}

 

三、SQLIteOpenHelper類

在實際專案中通常是繼承SQLiteOpenHelper開發子類,並通過子類的getReadableDatebase(),getWritebleDatebase()的方法代開資料庫。

(1)開發者只需要重寫SQLIteOpenHelper子類的兩個方法,加一個構造方法

構造方法用於建立資料庫  :例如

public MyDatabaseHelper(Context context, String name,SQLiteDatabase.CursorFactory factory, int version) {
    super(context, name,factory,version);
    this.context=context;
}

abstract void onCreate(SQLiteDatebase db):此方法初始使用軟降用於生成表。

abstract void onUpgrade(SQLiteDatebase db,int oldVesion,int newVersion):用於升級軟體更新資料庫的表結構

 

當呼叫,SQLIteOpenHelper子類的getReadableDatebase(),getWritebleDatebase()方法時獲取到SQLiteDatebase的例項,如果資料庫不存在,就呼叫onCreate()方法,可生成表,onCreate()方法只有在初次生成資料庫時才會被呼叫。

 

例項:英語生詞本

1、sqllitehelper_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:orientation="vertical">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="word"
        android:id="@+id/word"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="detail"
        android:id="@+id/detail"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="新增生詞"
        android:id="@+id/add_word"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="key"
        android:id="@+id/key"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查詢"
        android:layout_gravity="center"
        android:id="@+id/search"/>
</LinearLayout>

2、reslut_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:orientation="vertical">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/result_show"/>
</LinearLayout>

3、result_show_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/result_word"
        android:text="aaa"
        android:textSize="24sp"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/result_detail"
        android:text="aaaaaaaaa"
        android:textSize="20sp"/>

</LinearLayout>

4、SqLiteOpenHelperActivity

public class SqLiteOpenHelperActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText word;
    private EditText detail;
    private EditText key;
    private Button add_word;
    private Button search;
    MyDatabaseHelper myDatabaseHelper;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqllitehelper_activity);

        word=findViewById(R.id.word);
        detail=findViewById(R.id.detail);
        key=findViewById(R.id.key);
        add_word=findViewById(R.id.add_word);
        search=findViewById(R.id.search);

        add_word.setOnClickListener(this);
        search.setOnClickListener(this);

        myDatabaseHelper=new MyDatabaseHelper(this,"bookstore",null,1);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.add_word:{
                String word1=word.getText().toString();
                String detail1=detail.getText().toString();
               // Toast.makeText(SqLiteOpenHelperActivity.this,word1+" "+detail1,Toast.LENGTH_SHORT).show();
                word.setText("");
                detail.setText("");
                insertDate(myDatabaseHelper.getReadableDatabase(),word1,detail1);
                break;
            }
            case R.id.search:{
                String key1=key.getText().toString();
                Cursor cursor=myDatabaseHelper.getReadableDatabase().rawQuery("select * from book where word like ? or detail like ?",new String[]{"%"+key1+"%","%"+key1+"%"});
                key.setText("");
                Bundle data=new Bundle();
                data.putSerializable("data",converCursorToList(cursor));
                Intent intent=new Intent(SqLiteOpenHelperActivity.this,ResultActivity.class);
                intent.putExtras(data);
                startActivity(intent);
                break;
            }
            default:
                break;
        }
    }
    private void insertDate(SQLiteDatabase db,String word,String detail){
        db.execSQL("insert into book values(null,?,?)",new String[]{word,detail} );
        Toast.makeText(SqLiteOpenHelperActivity.this,"新增生詞成功",Toast.LENGTH_SHORT).show();
    }
    private ArrayList<Map<String,String>> converCursorToList(Cursor cursor){
        ArrayList<Map<String,String>> result=new ArrayList<>();
        StringBuilder builder=new StringBuilder();
        while (cursor.moveToNext()){
            Map<String,String> map=new HashMap<>();
            map.put("word","word:"+cursor.getString(1));
            map.put("detail","detail:"+cursor.getString(2));
            builder.append(cursor.getString(1)+" "+cursor.getString(2)+"\n");
            result.add(map);
        }
        Toast.makeText(SqLiteOpenHelperActivity.this,builder.toString(),Toast.LENGTH_SHORT).show();
        return result;
    }
    protected void onDestroy(){
        super.onDestroy();
        if(myDatabaseHelper!=null){
            myDatabaseHelper.close();
        }
    }
}

5、ResultActivity.class

public class ResultActivity extends AppCompatActivity {
    private ListView listView;
    protected void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.result_activity);
        listView=findViewById(R.id.result_show);
        Bundle bundle=getIntent().getExtras();
        List<Map<String,String>> data=(ArrayList<Map<String,String>>)bundle.getSerializable("data");
        SimpleAdapter adapter=new SimpleAdapter(ResultActivity.this,data,R.layout.rsult_show_item,
                new String[]{"word","detail"},new int[]{R.id.result_word,R.id.result_detail});
        listView.setAdapter(adapter);
    }
}