开发者

Android入门之使用SQLite内嵌式数据库详解

目录
  • 介绍
  • SQLite常用的三个类介绍
  • SQLiteOpenHelper类的使用
    • public void onCreate
    • public void onUpgrade
  • 使用SQLite操作数据库方法介绍
    • API的使用
    • 原生SQL的使用
    • 区分何时使用API何时使用原生SQL
  • SQLite数据库管理
    • Windows下的SQLite管理工具
    • MAC下的SQLite管理工具
  • 课程目标
    • 前端代码
      • 后端代码
        • UserBean.Java
        • SQLite的核心操作-DBAdapter.java
        • MainActivity.java
      • 运行效果

        介绍

        android内带SQLite内嵌式数据库了。这对于我们存储一些更复杂的结构化数据带来了极大的便利。比如说我们要存储应用内的常用联系人,购物车暂存信息,常量。必竟从XML或者是json里取数据都没有一条Select语句来得简单。

        SQLite常用有五种数据类型:

        • NULL
        • INTEGER
        • REAL(浮点数)
        • TEXT(字符串文本)
        • BLOB(二进制对象)

        虽然只有五种,但是对于varchar,char等其他数据类型都是可以保存的,如下create table语句依然是可以生效的:

        create table user(name varchar(20))
        

        SQLite常用的三个类介绍

        • SQLiteOpenHelper:抽象类,我们通过继承该类,然后重写数据库创建以及更新的方法, 我们还可以通过该类的对象获得数据库实例,或者关闭数据库;
        • SQLiteDatabase:数据库访问类:我们可以通过该类的对象来对数据库做一些增删改查的操作;
        • Cursor:游标,有点类似于JDBC里的resultset,结果集!可以简单理解为指向数据库中某 一个记录的指针;

        这三个类我们直接来看下面的Sample代码各位就知道是什么样的组合应用了。

        private SQLiteDatabase db;
        private Context context = null;
        private DBOpenHelper dbOpenHelper;
        private String DB_NAME="user.db";
        private static final String DB_TABLE = "t_user_login";
         
        dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION);
        try {
             db = dbOpenHelper.getWritableDatabase();
             db.open();
             StringBuilder sqlStr = new StringBuilder();
             sqlStr.append("select loginId,password,user_name from ").append(DB_TABLE);
             Cursor cur = db.rawQuery(sqlStr.toString(), null);
             while (cur.moveToNext()) {
                    String loginId = cur.getString(cur.getColumnIndexOrThrow("loginId"));
                    String password = cur.getString(cur.getColumnIndexOrThrow("password"));
                    String userName = cur.getString(cur.getColumnIndexOrThrow("user_name"));
                    UserBean user = new UserBean();
                    user.setLoginId(loginId);
                    user.setPassword(password);
                    user.setUserName(userName);
                    userList.add(user);
            }
        } catch (SQLiteException ex) {
             Log.e(TAG, ">>>>>>open db error: " + ex.getMessage(), ex);
         
        }finally {
                 try{
                   db.close();
                 }catch(Exception e){}
        }

        使用上和JDBC几乎一样,此处的Cursor相当于JDBC里的ResultSet。

        敲黑板重要提醒-Android中如何正确使用db.open()/db.close()

        在我们的例子里我们在每一个业务方法操作都会使用db.open一下,在finally块里db.close一下。

        同时要在Activity的onStop方法中去dbclose()掉它。

        记得,它就和水龙头一样,用完就要关。

        SQLiteOpenHelper类的使用

        这个类通常我们都要新建一个其它的类来extends这个类才能使用,主要的是这个类里有这么两个方法是很有用的。

        public void onCreate

        方法全签名:public void onCreate(SQLiteDatabase db)

        这个类的作用就是当SQLiteOpenHelper被实例化时,第一次用来做“初始化数据库”用的。比如说我们有一个类如下

        private static class DBOpenHelper extends SQLiteOpenHelper {
        

        然后当你实例化这个类时

        dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION);
        

        它会自动触发这个onCreate方法,在onCreate方法中我们可以做表创建以及数据初始化操作如:

                private static final String DB_CREATE = "create table " +
                        DB_TABLE + " (" + KEY_ID + " VARCHAR(20) primary key , " +
                        KEY_PASSWORD + " text not null, " + KEY_NAME + " text not null);";
         
                @Override
                public void onCreate(SQLiteDatabase db) {
                    Log.i(TAG, ">>>>>>execute create table->" + DB_CREATE);
                    db.execSQL(DB_CREATE);
                    StringBuilder initDataSql = new StringBuilder();
                    initDataSql.append("INSERT INTO ").append(DB_TABLE).
                            append("(").append(KEY_ID).append(",").append(KEY_PASSWORD).
                            append(",").append(KEY_NAME).append(")").append("values(?,?,?)");
                    Log.i(TAG, ">>>>>>execute initDataSql->" + initDataSql.toString());
                    db.execSQL(initDataSql.toString(), new String[]{"root", "111111", "root"});
                    Log.i(TAG, ">>>>>>db init successfully");
                }

        public void onUpgrade

        方法全签名:public void onUpgrade(SQLiteDatabase db, int _oldVersion, int _newVersion)

        它有一个_newVersion这么一个参数,这个参数也很有意思。当你在实例化SQLiteOpenHelper类传入的DB_VERSION参数>就近一次实例化这个类传入的DB_VERSION参数时,它就会触发这个onUpgrade()方法,在这个方法里我们一般是根据业务场景的需要,没有一概而论该怎么办,通用的做法有:

        • 重新执行一遍onCreate();此时所有的数据会被清空并初始化;
        • 有些Android发版时不需要做全数据库清除,往往太过危险,而是会执行alter更改表结构、新建表、新插入-insert一些数据或者是稍带着update一些数据;

        因此我才说,不一概而论而是需要依赖于你的实际业务场景来做操作。在我们的例子里我们会在onUpgrade里再执行一下onCreate()。

        使用SQLite操作数据库方法介绍

        这一块在使用上分两块。它类似Hibernate一样,也有API和原生SQL之分。

        API的使用

        即不需要书写SQL,如下样例:

            public long addItem(UserBean user) throws Exception {
                try {
                    ContentValues newValues = new ContentValues();
                    newValues.put(KEY_ID, user.getLoginId());
                    newValues.put(KEY_PASSWORD, user.getPassword());
                    newValues.put(KEY_NAME, user.getUserName());
                    Log.i(TAG, "addItem successfully with loginId->" + user.getLoginId() + " password->" + user.getPassword());
                    return db.insert(DB_TABLE, null, newValues);
                } catch (Exception e) {
                    Log.e(TAG, "addItem error: " + e.getMessage(), e);
                    throw new Exception("addItem error: " + e.getMessage(), e);
                }
            }
        

        我们可以看到全程没有使用SQL。

        原生SQL的使用

            public List<UserBean> queryAll() {
                List<UserBean> userList = new ArrayList<UserBean>();
                try {
                    StringBuilder sqlStr = new StringBuilder();
                    sqlStr.append("select loginId,password,user_name from ").append(DB_TABLE);
                    Cursor cur = db.rawQuery(sqlStr.toString(), null);
                    while (cur.moveToNext()) {
                        String loginId = cur.getString(cur.getColumnIndexOrThrow("loginId"));
                        String password = cur.getString(cur.getColumnIndexOrThrow("password"));
                        String userName = cur.getString(cur.getColumnIndexOrThrow("user_name"));
                        UserBean user = new UserBean();
                        user.setLoginId(loginId);
                        user.setPassword(password);
                        user.setUserName(userName);
                        userList.add(user);
                    }
                } catch (Exception e) {
                    Log.e(TAG, ">>>>>>queryAll error: " + e.getMessage(), e);
                }
                return userList;
            }

        区分何时使用API何时使用原生SQL

        如何区分呢?

        答案很简单,以下是最佳实践 :

        • 单表操作,就使用API好了;
        • 跨表(>1个表)的操作或者是较复杂的逻辑如果使用API会产生循环套来套去不如写一条长点的SQL那么请直接使用原生SQL;

        在样例前我们最后要了解一下,SQLite数据库管理工具。

        SQLite数据库管理

        Android里的SQLite一旦生成后它必须导出到AndroidStudio外部才能管理。按照如下步骤来导出SQLite数据库

        先使用Device File Explorer打开data->data->你的包全路径下/databases,这里面有一个.db文件就是SQLite数据库文件。另一个.db-journal是Transaction日志,我们后面讲SQLite的Transaction时会讲到。

        Android入门之使用SQLite内嵌式数据库详解

        选择这个user.db右键选->save as,就可以导出到本地磁盘了。

        然后你可以使用如下工具去管理SQLite数据库文件。

        Windows下的SQLite管理工具

        请使用SQLite Expert Professional,我使用的是5.4.4。不过这个是收费的,它长这个样但相当专业(收费的当然专业)。

        Android入门之使用SQLite内嵌式数据库详解

        MAC下的SQLite管理工具

        请使用SQLiteManager,完全免费并且和Windows的SQLite Expert Professional收费的一样功能全。为什么呢?难道因为MAC贵。。。所以。。。有预收费之说:)?

        好了,原理介绍完毕,我们要进入实践课程了。

        课程目标

        Android入门之使用SQLite内嵌式数据库详解

        1.该APP启动会创建user.db数据库,新建一张t_user_login表并初始化一条root/111111数据进入内嵌SQLite数据库;

        2.用户名密码输入root/111111点【登录】按钮可以得到登录成功,如果输入其它的不存在的帐户信息会以Toast显示“登录失败请校验你的用户名和密码”;

        3.用户名密码输入任意值,点击【增加一条记录】按钮,可以插入一条数据到内嵌SQLite;

        4.点击【查询所有记录】会以Log和Toast显示目前所有的相对应的表内的数据即:select *操作;

        5.例子中对于单表的插入操作我们使用的是Android自带的SQLiteOpenHelper的原生API;

        6.校验登录和查询所有记录我们用的是原生SQL+Cursor;

        下面就进入代码部分吧。

        前端代码

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout 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:orientation="vertical"
            tools:context=".MainActivity">
         
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
         
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="用户登陆" />
         
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:text="请输入用户名" />
         
                <EditText
                    android:id="@+id/editLoginid"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="用户名" />
         
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="请输入密码" />
         
                <EditText
                    android:id="@+id/editPassword"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="密码"
                    android:inputType="textPassword" />
         
                <Button
                    android:id="@+id/buttonLogin"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="登录" />
         
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#dfdfdf" />
            </LinearLayout>
         
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <Button
                    android:id="@+id/buttonAddItem"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:text="增加一条记录"/>
                <Button
                    android:id="@+id/buttonQueryAll"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:text="查询所有记录"/>
            </LinearLayout>
        </LinearLayout>

        后端代码

        UserBean.java

        package org.mk.android.demo.demosimplesqlite;
         
        import java.io.Serializable;
         
        public class UserBean implements Serializable {
         
            public String getLoginId() {
                return loginId;
            }
         
            public void setLoginId(String loginId) {
                this.loginId = loginId;
            }
         
            private String loginId = "";
         
            public String getPassword() {
                return password;
            }
         
            public void setPassword(String password) {
                this.password = password;
            }
         
            public String getUserName() {
                return userName;
            }
         
            public void setUserName(String userName) {
                this.userName = userName;
            }
         
            private String password = "";
            private String userName = "";
        }

        SQLite的核心操作-DBAdapter.java

        package org.mk.android.demo.demosimplesqlite;
         
        import android.content.ContentValues;
        import android.content.Context;
        import android.database.Cursor;
        import android.database.sqlite.SQLiteDatabase;
        import android.database.sqlite.SQLiteException;
        import android.database.sqlite.SQLiteOpenHelper;
        import android.util.Log;
         
        import java.util.ArrayList;
        import java.util.List;
         
        public class DBAdapter {
            private static final String TAG = "DemoSQLite";
            private static final String DB_NAME = "user.db";
            private static final String DB_TABLE = "t_user_login";
            private static final int DB_VERSION = 2;
         
            public static final String KEY_ID = "loginId";
            public static final String KEY_PASSWORD = "password";
            public static final String KEY_NAME = "user_name";
            private SQLiteDatabase db;
            private Context context = null;
            private DBOpenHelper dbOpenHelper;
         
            public DBAdapter(Context ctx) {
                context = ctx;
            }
         
            public void close() {
                try {
                    if (db != null) {
                        db.close();
                        db = null;
                    }
                } catch (Exception e) {
                }
            }
         
            public void open()  {
                dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION);
                try {
                    db = dbOpenHelper.getWritableDatabase();
                } catch (SQLiteException ex) {
                    Log.e(TAG, ">>>>>>open db error: " + ex.getMessage(), ex);
         
                }
            }
         
            public long addItem(UserBean user) throws Exception {
                try {
                    ContentValues newValues = new ContentValues();
                    newValues.put(KEY_ID, user.getLoginId());
                    newValues.put(KEY_PASSWORD, user.getPassword());
                    newValues.put(KEY_NAME, user.getUserName());
                    Log.i(TAG, "addItem successfully with loginId->" + user.getLoginId() + " password->" + user.getPassword());
                    return db.insert(DB_TABLE, null, newValues);
                } catch (Exception e) {
                    Log.e(TAG, "addItem error: " + e.getMessage(), e);
                    throw new Exception("addItem error: " + e.getMessage(), e);
                }
            }
         
            public List<UserBean> queryAll() {
                List<UserBean> userList = new ArrayList<UserBean>();
                try {
                    StringBuilder sqlStr = new StringBuilder();
                    sqlStr.append("select loginId,password,user_name from ").append(DB_TABLE);
                    Cursor cur = db.rawQuery(sqlStr.toString(), null);
                    while (cur.moveToNext()) {
                        String loginId = cur.getString(cur.getColumnIndexOrThrow("loginId"));
                        String password = cur.getString(cur.getColumnIndexOrThrow("password"));
                        String userName = cur.getString(cur.getColumnIndexOrThrow("user_name"));
                        UserBean user = new UserBean();
                        user.setLoginId(loginId);
                        user.setPassword(password);
                        user.setUserName(userName);
                     www.devze.com   userList.add(user);
                    }
                } catch (Exception e) {
                    Log.e(TAG, ">>>>>>queryAll error: " + e.getMessage(), e);
                }
                return userList;
            }
         
            public int checkLogin(String loginId, String pwd) {
                int result = 0;
                StringBuilder sqlStr = new StringBuilder();
                sqlStr.append("SELECT COUNT(*) FROM ").append(DB_TABLE).append(" WHERE ").append(KEY_ID).append("=? AND ").append(KEY_PASSWORD).append("=?");
                Log.i(TAG, ">>>>>>execute checkLogin SQL: " + sqlStr.toString());
                Log.i(TAG, ">>>>>>LoginId->" + loginId + " password->" + pwd);
                try {
                    Cursor cur = db.rawQuery(sqlStr.toString(), new String[]{loginId, pwd});
                    if (cur != null) {
                        cur.moveToFirst();
                        result = cur.getInt(0);
                    }
                } catch (Exception e) {
                    Log.e(TAG, "checkLogin dao error: " + e.getMessage(), e);
                }
                return result;
            }
         
            private static class DBOpenHelper extends SQLiteOpenHelper {
         
                public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
                    super(context, name, factory, version);
                }
         
                private static final String DB_CREATE = "create table " +
                        DB_TABLE + " (" + KEY_ID + " VARCHAR(20) primary key , " +
                        KEY_PASSWORD + " text not null, " + KEY_NAME + " text not null);";
         
                @Override
                public void onCreate(SQLiteDatabase db) {
                    Log.i(TAG, ">>>>>>execute create table->" + DB_CREATE);
                    db.execSQL(DB_CREATE);
                    StringBuilder initDataSql = new StringBuilder();
                    initDataSql.append("INSERT INTO ").append(DB_TABLE).
                            append("(").append(KEY_ID).append(",").append(KEY_PASSWORD).
                            append(",").append(KEY_NAME).append(")").append("values(?,?,?)");
                    Log.i(TAG, ">>>>>>execute initDataSql->" + initDataSql.toString());
                    db.execSQL(initDataSql.toString(), new String[]{"root", "111111", "root"});
                    Log.i(TAG, ">>>>>>db init successfully");
                }
         
                @Override
                public void onUpgrade(SQLiteDatabase db, int _oldVersion, int _newVersion) {
                    //db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
                    //onCreate(_db);
                    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
                    onCreate(db);
         
                }
            }
        }

        MainActivity.java

        这个就来得相对简单了。

        packzZGQFQyVage org.mk.android.demo.demosimplesqlite;
         
        import androidx.appcompat.app.AppCompatActivity;
         
        import android.content.Context;
        import android.database.sqlite.SQLiteDatabase;
        import android.database.sqlite.SQLiteOpenHelper;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.widget.Button;
        import android.widget.EditText;
        import android.widget.Toast;
         
        import java.util.ArrayList;
        import java.util.List;
         
         
        public class MainActivity extends AppCompatActivity {
            private static final String TAG = "DemoSQLite";
         
            private SQLiteDatabase db;
            private Context context;
            private DBAdapter dbAdapter;
         
            private EditText editLoginId;
            private EditText editPassword;
            private Button buttonLogin;
            private Button buttonAddItem;
            private Button buttonQueryAll;
            private String strLoginId;
            private String strPassword;
         
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentViewzZGQFQyV(R.layout.activity_main);
                context = getApplicationContext();
                buttonLogin = (Button) findViewById(R.id.buttonLogin);
                buttonAddItem = (Button) findViewById(R.id.buttonAddItem);
                buttonQueryAll = (Button) findViewById(R.id.buttonQueryAll);
                editLoginId = (EditText) findViewById(R.id.editLoginid);
                editPassword = (EditText) findViewById(R.id.editPassword);
                dbAdapter = new DBAdapter(context);
         
                buttonLogin.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        try {
                            dbAdapter.open();
                            strLoginId = editLoginId.getText().toString();
                            strPassword = editPassword.getText().toString();
                            int answer = dbAdapter.checkLogin(strLoginId, strPassword);
                            Log.i(TAG, ">>>>>>checkLogin is->" + answer);
                            if (answer != 1) {
                                Toast.makeText(context, "登录失败请校验你的用户名和密码", Toast.LENGTH_LONG).show();
                            } else {
                                Toast.makeText(context, "登录成功", Toast.LENGTH_LONG).show();
                            }
                        } catch (Exception e) {
                            Log.e(TAG, ">>>>>>checkLogin error: " + e.getMessage(), e);
                        } finally {
                            dbAdapter.close();
                        }
                    }
                });
                buttonAddItem.setOnClickListener(new View.OnClickListener() {
                    @Override
                    pub开发者_JAVA学习lic void onClick(View view) {
                        try {
                         编程客栈   dbAdapter.open();
                            strLoginId = editLoginId.getText().toString();
                            strPassword = editPassword.getText().toString();
                            UserBean user = new UserBean();
                            user.setLoginId(strLoginId);
                            user.setPassword(strPassword);
                            user.setUserName(strLoginId);
         
                            long result = dbAdapter.addItem(user);
                            Toast.makeText(context, "增加一条数据成功", Toast.LENGTH_LONG).show();
         
                        } catch (Exception e) {
                            Log.e("TAG", ">>>>>>addItem error: " + e.getMessage(), e);
                        } finally {
                            dbAdapter.close();
                        }
                    }
                });
                buttonQueryAll.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        try {
                            dbAdapter.open();
                            StringBuilder sb = new StringBuilder();
                            List<UserBean> userList = new ArrayList<UserBean>();
                            userList = dbAdapter.queryAll();
                            if (userList != null && userList.size() > 0) {
                                userList.forEach(v -> {
                                    sb.append("loginId->").append(v.getLoginId())
                                            .append(js"  password->").append(v.getPassword())
                                            .append(" userName->").append(v.getUserName())
                                            .append("\n");
                                });
                                Log.i(TAG,sb.toString());
                                Toast.makeText(context, "查询所有数据\n" + sb.toString(), Toast.LENGTH_LONG).show();
         
                            }
                        } catch (Exception e) {
                            Log.e(TAG, ">>>>>>queryAll error: " + e.getMessage(), e);
                        } finally {
                            dbAdapter.close();
                        }
                    }
                });
            }
         
            @Override
            protected void onStart(){
                super.onStart();
                dbAdapter.open();
            }
            @Override
            protected void onStop() {
                super.onStop();
                dbAdapter.close();
            }
        }

        运行效果

        Android入门之使用SQLite内嵌式数据库详解

        Android入门之使用SQLite内嵌式数据库详解

        Android入门之使用SQLite内嵌式数据库详解

        自己动一下手试试吧。

        以上就是Android入门之使用SQLite内嵌式数据库详解的详细内容,更多关于Android SQLite内嵌式数据库的资料请关注我们其它相关文章!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜