Android:用 SQLite 實現 用戶的登錄查詢功能(詳解+效果圖)

前言:

在侃實現功能之前,先來侃侃什麼是SQLite?SQLite的具體應用場合有哪些?(瞭解的大佬就可以跳過啦,嘻嘻,也可以複習一下哦)。

什麼是SQLite?

SQLite是一個進程內的庫,實現了自給自足的、無服務器的、零配置的、事務性的 SQL
數據庫引擎。它是一個零配置的數據庫,這意味着與其他數據庫一樣,您不需要在系統中配置。

就像其他數據庫,SQLite 引擎不是一個獨立的進程,可以按應用程序需求進行靜態或動態連接。SQLite 直接訪問其存儲文件。 --------- 菜鳥教程

爲什麼要用 SQLite?

不需要一個單獨的服務器進程或操作的系統(無服務器的)。

SQLite 不需要配置,這意味着不需要安裝或管理。

一個完整的 SQLite 數據庫是存儲在一個單一的跨平臺的磁盤文件。

SQLite 是非常小的,是輕量級的,完全配置時小於 400KiB,省略可選功能配置時小於250KiB。

SQLite 是自給自足的,這意味着不需要任何外部的依賴。

SQLite 事務是完全兼容 ACID 的,允許從多個進程或線程安全訪問。

SQLite 支持 SQL92(SQL2)標準的大多數查詢語言的功能。

SQLite 使用 ANSI-C 編寫的,並提供了簡單和易於使用的 API。

SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE,
WinRT)中運行。

常見的應用場景:

相信大家都用過像百詞斬,有道詞典等類似的背單詞的軟件,沒有用過的小夥伴可以下載一下嘗試嘗試(無償做廣告),在用這些軟件的時候那些單詞是從哪裏來的呢?想一下,如果我們每次打開軟件的時候都需要去服務器進行下載相應的單詞進行學習,一旦有成千上萬的英語學習愛好者,那服務器就需要面臨崩潰的危機,可能會有人說,升級服務器不就行了,of course。
但是, 百詞斬只是一個內存不到 幾百M 的軟件,用一個超大的服務器顯然不是一個優秀的選擇。(以上經過 zyg teacher 講解後自己的推敲)。
SQLite就可以很好的幫助處理這個問題: 它會將單詞書下載到本地,然後我們每次看單詞時就從本地進行讀取。(而且看看上面SQLite的有點,是不是很適合呢?)

實現功能:

用SQLite製作本地登錄功能
1、包含兩個Actvity:LoginActivity、ListActivity,LoginActivity爲啓動Activity
2、啓動LoginActivity初始化SQLite數據庫
3、在LoginActivity錄入用戶名和密碼時,在SQLite中進行校驗,校驗成功跳轉到ListActivity,否則繼續。
4、ListActivity顯示登錄成功!

實現效果:

首頁:
在這裏插入圖片描述
登錄成功:
在這裏插入圖片描述

登錄失敗:
在這裏插入圖片描述

代碼部分:

目錄結構:
在這裏插入圖片描述
AndroidManifestxml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.newsqlite">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SQLiteListActivity"></activity>
        
        <!--  這裏已經做了修改,啓動時會調用 SQLiteLoginActivity,不再是 MainActivity 了     -->
        <activity android:name=".SQLiteLoginActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <activity android:name=".MainActivity">

        </activity>
    </application>

</manifest>

MainActivity.java
在本項目中用處不大。

	package com.example.newsqlite;
	
	import androidx.appcompat.app.AppCompatActivity;
	
	import android.os.Bundle;
	
	public class MainActivity extends AppCompatActivity {
	
	    @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.activity_main);
	    }
	}

SQLiteDBHelper.java:數據庫幫助類:

package com.example.newsqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import androidx.annotation.Nullable;

/**
 * A helper class to manage database creation and version management.
 *
 * 既然父類是一個幫助類,子類至少也是一個幫助類,而且更加強大
 *
 * */
public class SQLiteDBHelper extends SQLiteOpenHelper {

    // 創建數據庫
    static final String CREATE_SQL[] = {
            "CREATE TABLE news (" +
                    "_id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
                    "title  varchar," +
                    "content  varchar," +
                    "keyword  varchar," +
                    "category  varchar," +
                    "author  INTEGER," +
                    "publish_time  varchar" +
                    ")",
            "CREATE TABLE user (" +
                    "_id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
                    "name  varchar," +
                    "password  varchar," +
                    "email  varchar," +
                    "phone  varchar," +
                    "address  varcher" +
                    ")",
            "INSERT INTO user VALUES (1,'admin',123,'[email protected]',123,'洛陽')",
            "INSERT INTO user VALUES (2,'zhangsan',123,'[email protected]',123,'北京')",
            "INSERT INTO user VALUES (3,'lisi',123,'[email protected]',123,'上海')",
            "INSERT INTO user VALUES (4,'wangwu',123,'[email protected]',123,'深圳')"
    };

    // 調用父類的構造方法(便於之後進行初始化賦值)
    public SQLiteDBHelper(@Nullable Context context, @Nullable String name, int version) {
        super(context, name, null, version);
    }

    /**
     * Called when the database is created for the first time. This is where the
     * creation of tables and the initial population of the tables should happen.
     *
     * @param db The database.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {

        // 創建數據庫
        Log.i("sqlite_____", "create Database");

        // 執行 SQL 語句
        for (int i = 0; i < CREATE_SQL.length; i++) {
            db.execSQL(CREATE_SQL[i]);
        }

        // 完成數據庫的創建
        Log.i("sqlite_____", "Finished Database");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

SQLiteLoginActivity: 登錄

package com.example.newsqlite;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.example.newsqlite.R;
import com.example.newsqlite.SQLiteDBHelper;
import com.example.newsqlite.SQLiteListActivity;


/**
 *  用戶登錄校驗:
 *      1、登錄成功則跳轉到 SQLiteListActivity。
 *      2、登錄失敗則重新登錄。
 *
 * */

public class SQLiteLoginActivity extends AppCompatActivity {

    SQLiteDBHelper dbHelper;

    EditText etUsername;
    EditText etPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite_login);

        // 創建 SQLiteDBHelper 對象,利用構造方法進行初始化賦值
        dbHelper = new SQLiteDBHelper(this,"sqlite.db",1);

        // 通過 id 找到 佈局管理器中的 相關屬性
        etUsername = findViewById(R.id.etUsername);
        etPassword = findViewById(R.id.etPassword);


    }

    // 當用戶點擊提交按鈕時,就會到這裏(單擊事件)
    public void onClick(View view) {

        // 獲取用戶的用戶名和密碼進行驗證
        String username = etUsername.getText().toString();
        String password = etPassword.getText().toString();


        /**
         * Create and/or open a database.
         * */
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        /**
         *
         *  查詢用戶信息,放回值是一個遊標(結果集,遍歷結果集)
         *
         * */
        Cursor cursor = db.query("user",new String[]{"name","password"}, "name=?",new String[]{username},null,null,null,"0,1");

        // 遊標移動進行校驗
        if(cursor.moveToNext()) {
            // 從數據庫獲取密碼進行校驗
            String dbPassword = cursor.getString(cursor.getColumnIndex("password"));
            // 關閉遊標
            cursor.close();
            if(password.equals(dbPassword)) {
                // 校驗成功則跳轉到 SQLiteListActivity
                Intent intent = new Intent(this, SQLiteListActivity.class);
                // 啓動
                startActivity(intent);
                return;
            }

        }

        // 跳轉失敗也要進行關閉
        cursor.close();
        // 跳轉失敗就提示用戶相關的錯誤信息
        Toast.makeText(this,"奧利給不足,輸入信息有誤!",Toast.LENGTH_LONG).show();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dbHelper.close();
    }
}

SQLiteListActivity: 登錄成功跳轉頁面

package com.example.newsqlite;

import androidx.appcompat.app.AppCompatActivity;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class SQLiteListActivity extends AppCompatActivity {

    ListView listView01;
    SQLiteDBHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite_list);

        // 提示信息
        Toast.makeText(this,"登錄成功,奧利給!",Toast.LENGTH_LONG).show();

        listView01 = findViewById(R.id.listView01);

        // 創建 SQLiteDBHelper 對象,利用構造方法進行初始化賦值
        dbHelper = new SQLiteDBHelper(this,"sqlite.db",1);

        // 通過 id 找到 佈局管理器中的 相關屬性
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        Cursor cursor = db.query("user",new String[]{"_id","name"},null,null,null,null,null,null);

        // 適配器,利用適配器進行填充信息,相對於數組來說更加靈活,動態化(爲這種設計點贊)
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_1,
                cursor,
                new String[]{"_id","name"},
                new int[]{android.R.id.text1,android.R.id.text1},
                0
        );
        listView01.setAdapter(adapter);
    }

    /**
     *  關閉 dbHelper.
     * */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        dbHelper.close();
    }

}

activity_sqlite_list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".SQLiteListActivity">

    <ListView
        android:id="@+id/listView01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints">

    </ListView>


</androidx.constraintlayout.widget.ConstraintLayout>

activity_sqlite_login.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".SQLiteLoginActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="150dp">

        <EditText
            android:id="@+id/etUsername"
            android:hint="用戶名"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <EditText

            android:id="@+id/etPassword"
            android:hint="密碼"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"/>
        <Button
            android:text="奧利給"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick"/>
    </LinearLayout>

</RelativeLayout>

總結:

嘻嘻,到此一個簡單的登錄+查詢的小功能就是實現了,再也不用擔心 Teacher 抽作業啦。
如果你 JavaWeb 學的不錯的話,可以類比一下,佈局管理器相當於是 html 文件,中間的
Activity 類比成 Servlet 進行跳轉,數據庫當然就是我們的 Dao 層了。
如果對您有幫助的,別忘了來個三連哦,感激感激。
如果上述的代碼不夠清晰,可以私聊我。
溜了溜了,交作業咯!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章