什麼是SQLite
SQLite 是一個軟件庫,實現瞭自給自足的、無服務器的、零配置的、事務性的 SQL 數據庫引擎。SQLite 是在世界上最廣泛部署的 SQL 數據庫引擎。SQLite 源代碼不受版權限制。
以下是一些關於SQLite學習的有用的網站:
1、SQLite Home Page – SQLite 官方網站提供瞭最新的 SQLite 安裝版本,最新的 SQLite 資訊以及完整的 SQLite 教程。
2、PHP SQLite3 – 網站提供瞭 SQLite 3 數據庫的 PHP 支持的完整細節。
3、DBD-SQLite-0.31 – SQLite Perl driver 驅動程序與 Perl DBI 模塊一起使用。
4、DBI-1.625 – Perl DBI 模塊為包括 SQLite 在內的任何數據庫提供瞭通用接口。
5、SQLite Python – sqlite3 python 模塊由 Gerhard Haring 編寫的。它提供瞭與 DB-API 2.0 規范兼容的 SQL 接口。
項目簡述
本次的APP主要要實現兩個功能:
1、實現數據庫的操作(創建數據庫、存入數據——註冊、查詢並使用數據——登錄)。
2、基本的頁面跳轉以及跳轉時數據的攜帶。
佈局文件 activity_main.xml
<GridLayout android:layout_width="match_parent" android:layout_height="match_parent" android:rowCount="5" android:columnCount="2"> <TimePicker android:layout_columnSpan="2"/> <TextView android:text="用戶名:" android:layout_row="1" android:layout_column="0" android:layout_marginLeft="65dp" /> <EditText android:id="@+id/username" android:layout_row="1" android:layout_column="1" android:layout_marginLeft="-200dp" android:ems="7" /> <TextView android:text="密碼:" android:layout_row="2" android:layout_column="0" android:layout_marginLeft="80dp" /> <EditText android:id="@+id/password" android:layout_row="2" android:layout_column="1" android:inputType="textPassword" android:layout_marginLeft="-200dp" android:ems="7" /> <LinearLayout android:weightSum="1.5" android:layout_gravity="center" android:layout_marginTop="20dp" android:layout_marginLeft="50dp" > <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登錄" android:layout_weight="0.5" /> <Button android:id="@+id/resign" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="註冊" android:layout_weight="0.5" /> <Button android:id="@+id/btn_new" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="重置" android:layout_weight="0.5" /> </LinearLayout> <DatePicker android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" android:layout_columnSpan="2"/> </GridLayout>
效果如下:
activity_success.xml
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="網上購書系統" android:textSize="25dp" android:textColor="@android:color/holo_blue_light" /> <TextView android:id="@+id/tv_welcome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="xxx 您好" android:textSize="25dp" android:textColor="@android:color/holo_red_light" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歡迎光臨" android:textSize="20dp" android:textColor="@android:color/holo_red_light" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:src="@drawable/hello"/> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登錄時間:xxxx-xx-xx" android:layout_marginTop="10dp" /> <Button android:id="@+id/btn_back" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:text="返回" android:textSize="20dp"/> </LinearLayout>
效果如下:
activity_fault.xml
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="網上購書系統" android:textSize="25dp" android:textColor="@android:color/holo_blue_light" /> <TextView android:id="@+id/tv_welcome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密碼錯誤!" android:textSize="25dp" android:textColor="@android:color/holo_red_light" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:src="@drawable/hello"/> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="請返回重新登錄" android:layout_marginTop="10dp" /> <Button android:id="@+id/btn_back" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:text="返回" android:textSize="20dp"/> </LinearLayout>
效果如下:
數據庫的創建
要想實現安卓app連接數據庫,首先我們要創建一個我們所需要的數據庫,值得一提的是,因為是移動設備上的app,所以這個數據庫的應用和web的數據庫還是有一些區別的,最顯著的一點就是我們要用代碼來實現數據庫的創建,並且這個數據庫是直接保存在我們的移動設備上的。
DateBaseHelper.java
這裡面我們撰寫瞭DateBaseHelper這個類來實現SQLiteOpenHelper這個方法。
/***DATEBASE_NAME是我們數據庫的名字,VERSION_CODE是數據庫的版本號,*TABLE_NAME是我們數據庫中的表的名字;*像這種常量我們之後會定義到Constants.java文件中*/public class DateBaseHelper extends SQLiteOpenHelper { private static final String TAG="DatabaseHelper"; public DateBaseHelper(@Nullable Context context) { super(context, Constants.DATEBASE_NAME, null, Constants.VERSION_CODE); } //創建數據庫(這隻會在程序第一次運行時生效,db文件會被儲存在移動設備中,下次運行不會重復創建) public void onCreate(SQLiteDatabase db) { Log.d(TAG,"創建數據庫..."); //創建數據庫中的字段,這裡隻創建瞭一個name字段和一個password字段 String sql ="create table "+Constants.TABLE_NAME+"(name varchar(20),password varchar(20))"; db.execSQL(sql); }//實現增 public void insert(SQLiteDatabase sqLiteDatabase, String name,String password){ //聲明鍵值對values ContentValues values=new ContentValues(); //分別插入名為name和password的值到鍵值對values的"name"和"password"字段中 values.put("name",name); values.put("password",password); //將鍵值對values插入到數據庫中 sqLiteDatabase.insert(Constants.TABLE_NAME,null,values); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //升級數據庫時的回調(升級前需要更改版本號) Log.d(TAG,"升級數據庫..."); }}
Constants.java
public class Constants { public static String DATEBASE_NAME="10_14homework.db";//數據庫名 public static int VERSION_CODE= 1;//版本號 public static final String TABLE_NAME="customers";//表名}
APP的編寫 DateUtil.java
因為我們的app在登陸後有一個實時返回登錄時間的功能,如下圖:
為瞭讓時間能按照我們預想的格式輸出,所以我撰寫瞭一個DateUtil類來存放時間的格式,其實這裡面就隻用到瞭一個類:SimpleDateFormat(格式化地輸出系統時間)
public class DateUtil {//這裡列舉瞭3個比較常用的時間展現格式,這個自由度很高,可以根據自己的需求來設計 public static String getNowDateTime() { //年-月-日 時:分:秒 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(new Date()); } public static String getNowTime() { //時:分:秒 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } public static String getNowTimeDetail() { //時:分:秒.毫秒 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(new Date()); }}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {//變量聲明 SQLiteDatabase sqLiteDatabase; DateBaseHelper helper; private EditText username; private EditText password; private String name_str; private String paswd_str; private Button resign; private Button login; private Button btn_new; private String mstr=""; private final static String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //控件定位 helper=new DateBaseHelper(this); //傳遞上下文 username=(EditText) findViewById(R.id.username); password=(EditText) findViewById(R.id.password); resign=(Button) findViewById(R.id.resign); login=(Button) findViewById(R.id.login); btn_new=(Button)findViewById(R.id.btn_new); //①以讀寫的方式打開數據庫,一旦數據庫的磁盤空間滿瞭,數據庫就隻能讀而不能寫,倘若使用的是getWritableDatabase() 方法就會出錯 //②還有一個getReadableDatabase()方法也是以讀寫方式打開數據庫,如果數據庫的磁盤空間滿瞭,就會打開失敗,當打開失敗後會繼續嘗試 //以隻讀方式打開數據庫。如果該問題成功解決,則隻讀數據庫對象就會關閉,然後返回一個可讀寫的數據庫對象。 sqLiteDatabase = helper.getWritableDatabase(); //設置按鈕監聽 resign.setOnClickListener(this); login.setOnClickListener(this); btn_new.setOnClickListener(this); } @Override public void onClick(View v) { // 通過id來分配按鈕事件 switch (v.getId()) { //註冊按鈕功能 case R.id.resign: //註冊相關的彈窗設定,如果確定提交,則完成註冊,數據存入數據庫 //AlerDialog:對話框控件 new AlertDialog.Builder(MainActivity.this).setTitle("系統提示") .setMessage("是否確定提交?") //為確定按鈕配置監聽 .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // 獲取EditView中的內容,並將其轉化成字符串型後存入變量中 name_str = username.getText().toString(); paswd_str = password.getText().toString(); //給數據表設置遊標,Cursor是一個遊標,以name字段為依據,query是一種根據條件獲取數據的方法 Cursor cursor = sqLiteDatabase.query(Constants.TABLE_NAME, new String[]{"name"}, "name=" >, new String[]{name_str}, null, null, null); //如果遊標找到瞭所需要的name,則返回已註冊,否則就利用之前寫的insert方法插入數據 if (cursor.getCount() != 0) { Toast.makeText(MainActivity.this, "該用戶已註冊!", Toast.LENGTH_SHORT).show(); } else { helper.insert(sqLiteDatabase, name_str, paswd_str); Toast.makeText(MainActivity.this, "註冊成功,請登錄!", Toast.LENGTH_SHORT).show(); } } }).setNegativeButton("返回", new DialogInterface.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { //這個是點擊返回後的操作,因為不需要,所以不管他直接跳出就好。 } }).show(); break; //登錄按鈕功能,上面解釋過的已省略 case R.id.login: String user_str = username.getText().toString(); String psw_str = password.getText().toString(); //賬號或密碼為空時 if (user_str.equals("")) { Toast.makeText(this, "賬號或密碼不能為空", Toast.LENGTH_SHORT).show(); }else { Cursor cursor = sqLiteDatabase.query(Constants.TABLE_NAME, new String[]{"password"}, "name=?", new String[]{user_str}, null, null, null); //遊標的遍歷,尋找name對應的password的值 if(cursor.moveToNext()){ String psw_query=cursor.getString(cursor.getColumnIndex("password")); //用戶名對應的密碼與輸入的密碼相同時 if(psw_str.equals(psw_query)){ Toast.makeText(this, "登錄成功!", Toast.LENGTH_SHORT).show(); //跳轉到successActivity頁面 Intent intent=new Intent (MainActivity.this,successActivity.class); //intent會攜帶上mstr的值並以username命名 intent.putExtra("username",mstr); //開始跳轉事件 startActivity(intent); break; } //密碼輸入錯誤時 else{ //跳轉到FaultActivity頁面 Intent intent2=new Intent(MainActivity.this,FaultActivity.class); startActivity(intent2); } } //遍歷完後發現在表中找不到遊標攜帶的name的值時 else{ Toast.makeText(this, "賬號不存在,請先註冊!", Toast.LENGTH_SHORT).show(); } } break; //重置按鈕功能 case R.id.btn_new: //將EditView的文本清空 username.setText(""); password.setText(""); break; default: break; } }}
登錄成功和失敗後的頁面編寫 successfulActivity.java
public class successActivity extends AppCompatActivity implements View.OnClickListener {//變量聲明 private String mStr=""; private String mTime; private final static String TAG="successActivity"; private TextView tv_welcome; private TextView tv_time; private Button btn_back; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_success); btn_back=(Button)findViewById(R.id.btn_back); logintime(); welcome(); btn_back.setOnClickListener(this); }//返回登錄時間 private void logintime() { tv_time=(TextView)findViewById(R.id.tv_time); //用DateUtil中的getNowDateTime格式返回登錄時間 mTime = String.format("登錄時間 %s", DateUtil.getNowDateTime()); tv_time.setText(mTime); }//將之前跳轉時攜帶的用戶信息用到歡迎界面中 private void welcome(){ //獲取intent Intent intent=getIntent(); //獲取intent中名為username的數據的值 String username = intent.getStringExtra("username"); tv_welcome=(TextView)findViewById(R.id.tv_welcome); mStr=String.format("%s 您好", username); tv_welcome.setText(mStr); } @Override //返回 實現跳轉回到登錄界面 public void onClick(View v) { Intent intent2=new Intent(successActivity.this,MainActivity.class); startActivity(intent2); }}
FaultActivity.java
//這個頁面沒有什麼花裡胡哨的public class FaultActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_back; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fault); btn_back=(Button)findViewById(R.id.btn_back); btn_back.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent=new Intent(FaultActivity.this,MainActivity.class); startActivity(intent); }}