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

  目录

  介绍

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

  SQLite常用有五种数据类型:

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

  create table user(name varchar(20))

  SQLite常用的三个类介绍

  这三个类我们直接来看下面的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()方法,在这个方法里我们一般是根据业务场景的需要,没有一概而论该怎么办,通用的做法有:

  因此我才说,不一概而论而是需要依赖于你的实际业务场景来做操作。在我们的例子里我们会在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 queryAll() {

  List userList = new ArrayList();

  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

  如何区分呢?

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

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

  SQLite数据库管理

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

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

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

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

  Windows下的SQLite管理工具

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

  MAC下的SQLite管理工具

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

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

  课程目标

  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"?>

  

  xmlns:tools="http://schemas.android.com/tools"

  android:layout_width="match_parent"

  android:layout_height="match_parent"

  android:orientation="vertical"

  tools:context=".MainActivity">

  

  android:layout_width="match_parent"

  android:layout_height="wrap_content"

  android:orientation="vertical">

  

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:text="用户登陆" />

  

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:layout_marginTop="10dp"

  android:text="请输入用户名" />

  

  android:id="@+id/editLoginid"

  android:layout_width="match_parent"

  android:layout_height="wrap_content"

  android:hint="用户名" />

  

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:text="请输入密码" />

  

  android:id="@+id/editPassword"

  android:layout_width="match_parent"

  android:layout_height="wrap_content"

  android:hint="密码"

  android:inputType="textPassword" />

  

  android:id="@+id/buttonLogin"

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:text="登录" />

  

  android:layout_width="match_parent"

  android:layout_height="1dp"

  android:background="#dfdfdf" />

  

  

  android:layout_width="match_parent"

  android:layout_height="match_parent">

  

  android:id="@+id/buttonAddItem"

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:layout_marginRight="10dp"

  android:text="增加一条记录"/>

  

  android:id="@+id/buttonQueryAll"

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:layout_marginLeft="10dp"

  android:text="查询所有记录"/>

  

  

  后端代码

  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 queryAll() {

  List userList = new ArrayList();

  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;

  }

  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

  这个就来得相对简单了。

  package 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);

  setContentView(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

  public 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 userList = new ArrayList();

  userList = dbAdapter.queryAll();

  if (userList != null && userList.size() > 0) {

  userList.forEach(v -> {

  sb.append("loginId->").append(v.getLoginId())

  .append(" password->").append(v.getPassword())

  .append(" userName->").append(v.getUserName())

  .append("

  ");

  });

  Log.i(TAG,sb.toString());

  Toast.makeText(context, "查询所有数据

  " + 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内嵌式数据库的资料请关注脚本之家其它相关文章!

  您可能感兴趣的文章: