●程式說明--用程式建立SQLite資料庫
=>要先新增一個class繼承SQLiteOpenHelper
=>SQLiteOpenHelper是一個抽象類別,所以要override兩個方法
=>還要加建構式,因為SQLiteOpenHelper這個父類別本身只有有參數的建構式,所以一定要加,不然當父類別的參數要使用到時就會有問題
=>加建構式時,選第一個
=>新增欄位在add column
=>複製新增欄位的語法,按下add column按鈕就會跳出對話框,語法就在對話框上
(一)MyHelper.class
package com.example.student.lu101801;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MyHelper extends SQLiteOpenHelper {
//本來建構式繼承有四個參數,但factory用不到就直接設定null
//資料庫名稱和版本則會直接設定final然後把這三個參數丟到super方法中
//這樣mainactivity要建立MyHelper物件時,就只要丟context這個參數進來就可以
static final String DB_NAME="student.sqlite";
static final int VERSION=4;
public MyHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}
@Override //如果系統中沒有這個資料庫,就會跑onCreate
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//先去SQLite Manager複製create語法,這邊有個技巧事先打好雙引號再貼上語法
//這樣會自動把需要加上反斜線的內容都加好反斜線
//在做版本更新時,除了onUpgrade要加sql語法,onCreate也要加,因為可能有用戶是沒有舊版就直接安裝新版的
String createSQL="CREATE TABLE \"phone\" (\"id\" INTEGER PRIMARY KEY NOT NULL ,\"name\" VARCHAR,\"tel\" VARCHAR,\"addr\" VARCHAR DEFAULT (null) , \"email\" VARCHAR, \"tel2\" VARCHAR)";
//sqLiteDatabase是從參數帶入的SQLiteDatabase
sqLiteDatabase.execSQL(createSQL);
}
@Override //如果系統中有這個資料庫且版本不同,就會跑onUpgrade
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldversion, int newversion) {
Log.d("verson","verson:"+oldversion);
//因為new這個物件時會帶入版本參數,這邊就要做版本的判斷來決定要做甚麼
if (oldversion != 4 )
{
String upgradeSQL = "ALTER TABLE \"main\".\"phone\" ADD COLUMN \"tel2\" VARCHAR";
sqLiteDatabase.execSQL(upgradeSQL);
}
}
}
(二)phone.class
package com.example.student.lu101801;
//注意不要把public寫成static,會把屬性值改掉然後指記憶最後一筆資料
//建一個物件用來存放資料庫的資料
public class phone {
public int id;
public String name;
public String tel;
public String addr;
public String email;
public String tel2;
(三)MainActivity.class
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click1(View view) {
phone p=new phone();
p.name="kent";
p.tel="12345678";
p.tel2="87654321";
p.addr="abceddddd";
p.email="test2@eamil";
add(p);
phone p1=getOne(5);
Log.d("p1","p1"+p1.name);
}
//新增資料的method
public void add(phone p){
//要透過建立MyHelper這個步驟來新增資料庫(沒有就onCreate/有就直接使用/要更新版本就onUpgrade)
//這邊在宣告MyHelper的時候就run onCreate
MyHelper helper=new MyHelper(MainActivity.this);
//呼叫getWritableDatabase()時,就會去執行onCreate中的execSQL();
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues cv = new ContentValues();
//寫入時,每個欄位資料都去對應phone 物件的各個field
cv.put("name",p.name);
cv.put("tel",p.tel);
cv.put("addr",p.addr);
cv.put("email",p.email);
cv.put("tel2",p.tel2);
db.insert("phone", null, cv);
db.close();
}
//讀取資料的method(會傳回phone物件)
public phone getOne(int id){
phone p=new phone();
MyHelper helper=new MyHelper(MainActivity.this);
SQLiteDatabase db=helper.getWritableDatabase();
//因為會帶入一個int id的參數,這邊第三第四個參數也要設定,先在第三個參數設定要如何篩選資料
// 第四個參數是把丟進來的int id轉成字串陣列的第一筆資料再丟給id(參數3)去篩選,這樣就會找到那一筆id的資料
Cursor c = db.query("phone",new String[] {"id","name","tel",
"addr","email","tel2"}, "id=?",
new String[] {String.valueOf(id)}, null, null, null);
c.moveToFirst();
//設定在讀取時,phone class的每個field會去抓哪個欄位的資料
p.id=c.getInt(0);
p.name = c.getString(1);
p.tel = c.getString(2);
p.addr = c.getString(3);
p.email=c.getString(4);
p.tel2=c.getString(5);
db.close();
return p;
}
}
**說明:
這種利用物件來進行資料庫的操作稱為ORM,而資料庫的處理和前面程式的處理分開稱為DAO
●DAO pattern(Design pattern)=>部分程式比照上方
(一)phoneDAO.class
//先用一個DAO定義資料庫有哪些操作(interface),再實作填寫真正的操作內容
public interface phoneDAO {
public void addOne(phone p);
public phone getOne(int id);
public void clearAll();
public phone[] getList();
public void delete(phone p);
public void update(phone p);
}
(二)phone.class
//建一個物件用來存放資料庫的資料
public class phone {
public int id;
public String name;
public String tel;
public String addr;
public String email;
public String tel2;
//為了不影響前面程式,要多寫幾個建構式(因為之前程式new物件的時候不用放參數)
public phone() {
}
//為了方便處理資料,加寫建構式,三個參數是用來新增物件用
public phone(String name, String tel, String addr) {
this.name = name;
this.tel = tel;
this.addr = addr;
}
//四個參數是用來讀取資料用
public phone(int id, String name, String tel, String addr) {
this.id = id;
this.name = name;
this.tel = tel;
this.addr = addr;
}
}
(三) MyHelper.class
public class MyHelper extends SQLiteOpenHelper {
//本來建構式繼承有四個參數,但factory用不到就直接設定null
//資料庫名稱和版本則會直接設定final然後把這三個參數丟到super方法中
//這樣mainactivity要建立MyHelper物件時,就只要丟context這個參數進來就可以
static final String DB_NAME="student.sqlite";
static final int VERSION=4;
public MyHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}
@Override //如果系統中沒有這個資料庫,就會跑onCreate
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//先去SQLite Manager複製create語法,這邊有個技巧事先打好雙引號再貼上語法
//這樣會自動把需要加上反斜線的內容都加好反斜線
//在做版本更新時,除了onUpgrade要加sql語法,onCreate也要加,因為可能有用戶是沒有舊版就直接安裝新版的
String createSQL="CREATE TABLE \"phone\" (\"id\" INTEGER PRIMARY KEY NOT NULL ,\"name\" VARCHAR,\"tel\" VARCHAR,\"addr\" VARCHAR DEFAULT (null) , \"email\" VARCHAR, \"tel2\" VARCHAR)";
//sqLiteDatabase是從參數帶入的SQLiteDatabase
sqLiteDatabase.execSQL(createSQL);
}
@Override //如果系統中有這個資料庫且版本不同,就會跑onUpgrade
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldversion, int newversion) {
Log.d("verson","verson:"+oldversion);
//因為new這個物件時會帶入版本參數,這邊就要做版本的判斷來決定要做甚麼
if (oldversion != 4 )
{
String upgradeSQL = "ALTER TABLE \"main\".\"phone\" ADD COLUMN \"tel2\" VARCHAR";
sqLiteDatabase.execSQL(upgradeSQL);
}
}
}
(四)
//名稱取名為phoneDAO在DB上的實作(可以套用到雲端、檔案....)
public class phoneDAODBImpl implements phoneDAO {
SQLiteDatabase db;
MyHelper helper;
//因為在建立db時要取得mainactivity,所以要加一個建構是在new的時候可以把mainactivity傳進來
public phoneDAODBImpl(Context context) {
helper=new MyHelper(context);
db=helper.getWritableDatabase();
}
//刪除
@Override
public void clearAll()
{
SQLiteDatabase db = helper.getWritableDatabase();
//刪除的語法要用delete from phone,把整個table刪掉
db.execSQL("delete from phone");
db.close();
}
@Override
public phone[] getList() {
SQLiteDatabase db = helper.getWritableDatabase();
//建一個phone型別的arraylist
ArrayList<phone> mylist = new ArrayList();
//這邊因為要取全部的資料所以不要用where
Cursor c = db.query("phone", new String[] {"id","name","tel","addr"}, null, null, null, null, null);
if (c.moveToFirst())
{
do {
phone p = new phone();
p.id = c.getInt(0);
p.name = c.getString(1);
p.tel = c.getString(2);
p.addr = c.getString(3);
//把p的資料加到mylist中
mylist.add(p);
}while(c.moveToNext());
}
//把arraylist轉成array,而且要把這個和mylist資料長度一樣的array轉成phone型別
phone rValue[] = mylist.toArray(new phone[mylist.size()]);
return rValue;
}
@Override
public void addOne(phone p) {
db=helper.getWritableDatabase();
ContentValues cv = new ContentValues();
//寫入時,每個欄位資料都去對應phone 物件的各個field
cv.put("name",p.name);
cv.put("tel",p.tel);
cv.put("addr",p.addr);
cv.put("email",p.email);
cv.put("tel2",p.tel2);
db.insert("phone", null, cv);
db.close();
}
@Override
public phone getOne(int id) {
//要再取得一次database,因為如果先做addOne會把db關閉,這邊要再取得一次
db=helper.getWritableDatabase();
phone p=new phone();
//因為會帶入一個int id的參數,這邊第三第四個參數也要設定,先在第三個參數設定要如何篩選資料
// 第四個參數是把丟進來的int id轉成字串陣列的第一筆資料再丟給id(參數3)去篩選,這樣就會找到那一筆id的資料
Cursor c = db.query("phone",new String[] {"id","name","tel","addr","email","tel2"}, "id=?", new String[] {String.valueOf(id)}, null, null, null);
c.moveToFirst();
//設定在讀取時,phone class的每個field會去抓哪個欄位的資料
p.id=c.getInt(0);
p.name = c.getString(1);
p.tel = c.getString(2);
p.addr = c.getString(3);
p.email=c.getString(4);
p.tel2=c.getString(5);
db.close();
return p;
}
//刪除
@Override
public void delete(phone p) {
SQLiteDatabase db=helper.getWritableDatabase();
//第二個參數是where clause,第三個參數是指定要刪除的那筆資料id
db.delete("phone","id=?",new String[] {String.valueOf(p.id)});
db.close();
}
//更新
@Override
public void update(phone p) {
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("name",p.name);
cv.put("tel",p.tel);
cv.put("addr",p.addr);
cv.put("email",p.email);
cv.put("tel2",p.tel2);
// 第二個參數要更新的資料
//第三個參數是要用甚麼篩選,第四個參數是要更新哪一筆資料
db.update("phone",cv,"id=?",new String[] {String.valueOf(p.id)});
db.close();
}
}
(五)MainAcitivity.class
package com.example.student.lu101801;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click1(View view) {
phone p=new phone();
p.name="kent";
p.tel="12345678";
p.tel2="87654321";
p.addr="abceddddd";
p.email="test2@eamil";
phoneDAODBImpl pi=new phoneDAODBImpl(MainActivity.this);
pi.addOne(p);
phone p1=pi.getOne(3);
Log.d("p1","p1"+p1.addr);
}