在Android的项目开发中,都会用到数据库,SQLite作为本地数据库,是一定要会的。Android团队封装了很多对SQLite操作的API。我这里自己写了一个Demo来总结一下SQLit的基本使用方法。

先上截图

Android SQLite增删改查基本用法,通讯录实现_第1张图片Android SQLite增删改查基本用法,通讯录实现_第2张图片Android SQLite增删改查基本用法,通讯录实现_第3张图片

Android SQLite增删改查基本用法,通讯录实现_第4张图片Android SQLite增删改查基本用法,通讯录实现_第5张图片

 

Android专门提供了一个SQLiteOpenHelper帮助类,可以非常简单地对数据库进行创建和升级。

首先创建数据库,我们这里创建一个类继承SQLiteOpenHelper类,并重写onCreate()和onUpgrade()方法:

import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * Created by lenovo on 2018/10/14. */public class DatabaseUtil extends SQLiteOpenHelper {    private static final String DATABASE_NAME = "PhoneBook.db";  //数据库名    private static final int DATABASE_VERSION = 1;               //数据库版本号    public DatabaseUtil(Context context){        super(context,DATABASE_NAME,null,DATABASE_VERSION);    }    /**     * 创建数据库     * */    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        createTable(sqLiteDatabase);    }    /**     * 建立数据表     * */    private void createTable(SQLiteDatabase db){        db.execSQL("create table UserInfo(" +                "id integer primary key autoincrement," +                "userName text," +                "userPhone text)");    }    /**     * 升级数据库     * */    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {    }}

这个类主要用于建立数据库和更新数据库

实例化这个类的时候构造函数传入上下文,并继承父类构造函数,数据库名称和版本号都已经写成了常量。onCreate()方法在创建时和创建后只会调用一次,所以在这里面创建一次数据表就行了,而onUpgrade()方法只有在数据库版本号大于上次传入的值时调用,用于对数据库进行更新操作,如新建表,更改列等。

创建一个Utildao类专门对数据库进行增删改查操作,主要目的是与逻辑代码分开便于代码维护,附上代码:

import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.example.lenovo.work.entity.User;import java.util.ArrayList;import java.util.List;/** * Created by lenovo on 2018/10/16. */public class UtilDao {    private DatabaseUtil du;    private SQLiteDatabase db;    public UtilDao(Context context){        du = new DatabaseUtil(context);        db = du.getWritableDatabase();    }    /**     * 添加数据     * */    public void addData(String tableName,String[] key,String[] values){        ContentValues contentValues = new ContentValues();        for(int i = 0; i < key.length; i ++){            contentValues.put(key[i],values[i]);        }        db.insert(tableName,null,contentValues);        contentValues.clear();    }    /**     * 删除数据     * */    public int delData(String where,String[] values){        int del_data;        del_data = db.delete("UserInfo",where,values);        return del_data;    }    /**     * 修改数据     * */    public void update(String[] values){        db.execSQL("update UserInfo set userName=?,userPhone=? where userName=? ",values);    }    /**     * 查询数据     * */    public List inquireData(){        List list = new ArrayList<>();        Cursor cursor = db.rawQuery("select userName,userPhone" +                " from UserInfo",null);            while(cursor.moveToNext()){                String name = cursor.getString(0);                String phone = cursor.getString(1);                User user = new User();                user.setName(name);                user.setPhone(phone);                list.add(user);            }        return list;    }    /**     * 关闭数据库连接     * */    public void getClose(){        if(db != null){            db.close();        }    }}

我们先调用帮助类的getWritableDatabase()方法,获取可写入的权限。

Android有两种方法对数据进行增删改查操作,一种是Android封装好的方法,另一种是通用的直接执行SQL语句的方法,我这里为了方便部分使用了面向对象方法,部分是直接执行SQL语句的。使用execSQL()方法直接执行SQL语句没有返回值且容易出错,所以我推荐使用Android自带封装好的方法操作数据库。

添加:

这里调用了帮助类的insert方法,第一个参数传入表名,第二个参数暂时用不到传入null,第三个参数传入ContentValues对象,ContentValues对象提供了put()方法重载,用于向ContentValues中添加数据。

 /**     * 添加数据     * */    public void addData(String tableName,String[] key,String[] values){        ContentValues contentValues = new ContentValues();        for(int i = 0; i < key.length; i ++){            contentValues.put(key[i],values[i]);        }        db.insert(tableName,null,contentValues);        contentValues.clear();    }

删除:

调用delete方法,第一个参数传入表名,第二个参数写条件where语句,通常写列名,不写的话删除所有行,第三个传入列名对应的值,最后返回删除的行数。

  /**     * 删除数据     * */    public int delData(String where,String[] values){        int del_data;        del_data = db.delete("UserInfo",where,values);        return del_data;    }

修改:

我这里调用了execSQL方法直接写SQL语句,封装的方法为update请自行搜索,这里第一个值是SQL语句没什么好说的,第二个值为传入的条件值,对应SQL语句里的"?"通配符。

 /**     * 修改数据     * */    public void update(String[] values){        db.execSQL("update UserInfo set userName=?,userPhone=? where userName=? ",values);    }

查询:

查询代码就比较多了,先调用rawQuery方法查询出结果,再把值赋给Cursor对象,它是一个游标,通过while判断它指向的行下面是否还有数据,若有则把当前行的值存储到User实体类里,然后添加到List数组链表中,循环下一次。这里用到List是因为这需要返回给前台的ListView做数据源。

 /**     * 查询数据     * */    public List inquireData(){        List list = new ArrayList<>();        Cursor cursor = db.rawQuery("select userName,userPhone" +                " from UserInfo",null);            while(cursor.moveToNext()){                String name = cursor.getString(0);                String phone = cursor.getString(1);                User user = new User();                user.setName(name);                user.setPhone(phone);                list.add(user);            }        return list;    }

到这里数据访问层和dao层就写好了,接下来实现功能。

因为UtilDao这个类里面的数据库操作方法以后会经常用到,如果每次都 new 一个对象来使用的话会很麻烦,所以我这里使用了MyApplication类来将 UtilDao 类设为全局变量且只有一个实例,这样就方便多了。

import android.app.Application;import com.example.lenovo.work.dbutil.UtilDao;/** * Created by lenovo on 2018/10/16. */public class MyApplication extends Application {    private UtilDao dao;    /**     * 创建时调用     * */    @Override    public void onCreate() {        super.onCreate();        dao = new UtilDao(this);    }    /**     * 后台进程终止,前台程序需要内存时调用此方法,用于释放内存     * 用于关闭数据库连接     * */    @Override    public void onLowMemory() {        super.onLowMemory();        dao.getClose();    }    public UtilDao getDao() {        return dao;    }}

因为Application组件优先于Activity,在程序运行时最先创建且只创建一次。需要在AndroidManifest.xml里标签里添加name属性,这点很重要!!!不然程序崩溃。

android:name=".MyApplication"

布局很简单,这里我就不过多的解释,自行理解:

<?xml version="1.0" encoding="utf-8"?>                            

我们先建一个实体类,用于存储用户信息,作为ListView 的数据源:

public class User {    private String name;    private String phone;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }}

ListView子布局(item):

<?xml version="1.0" encoding="utf-8"?>                        

ListView数据适配器:

import android.content.Context;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.TextView;import com.example.lenovo.work.R;import com.example.lenovo.work.entity.User;import java.util.List;/** * Created by lenovo on 2018/10/14. */public class MyAdapter extends ArrayAdapter {    int resource;    //构造方法传递三个参数,分别为:上下文,列表子布局和列表所需数据    public MyAdapter(Context context, int resource, List list){        //继承父类构造        super(context,resource,list);        //后面会用到        this.resource = resource;    }    //加载适配器时会调用此方法    @NonNull    @Override    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {        //获得当前显示项的User对象        User user = getItem(position);        ViewHolder holder;        //若是第一次加载页面则调用此方法初始化        if(convertView == null){            convertView = LayoutInflater.from(getContext()).inflate(resource,parent,false);            holder = new ViewHolder();            holder.tv_name = convertView.findViewById(R.id.item_name);            holder.tv_phone = convertView.findViewById(R.id.item_phone);            convertView.setTag(holder);        }else{            holder = (ViewHolder) convertView.getTag();        }        //将数据传递给控件并显示        holder.tv_name.setText(user.getName());        holder.tv_phone.setText(user.getPhone());        return convertView;    }        //缓存类,用于存放已存在的对象    class ViewHolder{        TextView tv_name;        TextView tv_phone;    }}

MainActivity:

import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.Button;import android.widget.ListView;import android.widget.TextView;import com.example.lenovo.work.adapter.MyAdapter;import com.example.lenovo.work.dbutil.UtilDao;import com.example.lenovo.work.entity.User;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private TextView textNum;    private Button button;    private ListView listView;    private List list,newList;    private UtilDao dao;    private MyAdapter adapter;    private int listNum = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化控件        initWidget();        //实例dao        DbUtil();        //显示ListView        showListView();        //显示listView的条目数量        linkmanNum();    }    /**     * 初始化控件     * */    private void initWidget(){        button = findViewById(R.id.main_but);        listView = findViewById(R.id.main_list_view);        textNum = findViewById(R.id.main_num);        newList = new ArrayList<>();        list = new ArrayList<>();    }    /**     * 显示ListView     * */    public void showListView(){        //查询数据        /**         * 添加数据到链表中         * **/        list = dao.inquireData();        /**         * 创建并绑定适配器         * */        adapter = new MyAdapter(this,R.layout.item,list);        listView.setAdapter(adapter);        /**         * ListView事件监听         * */        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {                dialogList();                listNum = i;            }        });        button.setOnClickListener(this);    }    /**     * 普通对话框     * */    public void dialogNormal(){        AlertDialog.Builder builder = new AlertDialog.Builder(this);        DialogInterface.OnClickListener dialogOnClick = new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialogInterface, int i) {                User userDel = list.get(listNum);                switch (i){                    case DialogInterface.BUTTON_POSITIVE:                            dao.delData("userName=?",new String[]{userDel.getName()});                            refresh();                        break;                    case DialogInterface.BUTTON_NEGATIVE:                        break;                    default:break;                }            }        };        builder.setTitle("删除联系人");        builder.setMessage("确定要删除吗?");        builder.setPositiveButton("确定", dialogOnClick);        builder.setNegativeButton("取消",dialogOnClick);        builder.create().show();    }    /**     * 选项列表     * */    public void dialogList(){        final String[] items = {"拨打电话","发送短信","编辑","删除"};        AlertDialog.Builder builder = new AlertDialog.Builder(this);        builder.setItems(items, new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialogInterface, int i) {                dialogInterface.dismiss();                //拿到当前选中项的 User 对象                User userNum = list.get(listNum);                Intent intent;                switch (i){                            //拨打电话                    case 0: intent = new Intent(Intent.ACTION_DIAL);                            intent.setData(Uri.parse("tel:" + userNum.getPhone()));                            startActivity(intent);                            break;                            //发送短信                    case 1: intent = new Intent(Intent.ACTION_SENDTO);                            intent.setData(Uri.parse("smsto:" + userNum.getPhone()));                            startActivity(intent);                            break;                    case 2: intent = new Intent(MainActivity.this,AddData.class);                            //传入当前选中项的姓名和电话以在编辑页面中显示在输入框中                            intent.putExtra("edit_name",userNum.getName().toString());                            intent.putExtra("edit_phone",userNum.getPhone().toString());                            startActivityForResult(intent,2);                            break;                            //弹出对话框提示是否删除                    case 3: dialogNormal();                            break;                            default:                                break;                }            }        });        builder.create().show();    }    //刷新    public void refresh(){        //最后查询数据刷新列表        getNotifyData();    }    //页面顶部显示ListView条目数    public void linkmanNum(){        textNum.setText("("+list.size()+")");    }    //点击添加按钮    @Override    public void onClick(View view) {        switch (view.getId()){            case R.id.main_but:                    //跳转到 AddData Activity 传入请求码 1                    Intent intent = new Intent(MainActivity.this,AddData.class);                    startActivityForResult(intent,1);                break;                default:break;        }    }    public void DbUtil(){        dao = ((MyApplication)this.getApplication()).getDao();    }    /**     * 当页面回到此活动时,调用此方法,刷新ListView     * */    @Override    protected void onResume() {        super.onResume();        getNotifyData();    }    /**     * 这个是用来动态刷新 * */    public void getNotifyData(){        //使用新的容器获得最新查询出来的数据        newList = dao.inquireData();        //清除原容器里的所有数据        list.clear();        //将新容器里的数据添加到原来容器里        list.addAll(newList);        //更新页面顶部括号里显示数据        linkmanNum();        //刷新适配器        adapter.notifyDataSetChanged();    }    /**     * 上一个页面传回来的值     * */    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        switch (requestCode){            //请求码为1,表示点击了添加按钮            case 1:                //执行添加方法                if(resultCode == RESULT_OK){                    String[] key = data.getStringArrayExtra("key");                    String[] values = data.getStringArrayExtra("values");                    dao.addData("UserInfo",key,values);                }                break;                //请求码为2,表示点击了编辑按钮            case 2:                //执行修改方法                if(resultCode == RESULT_OK){                    User user = list.get(listNum);                    String name = data.getStringExtra("name");                    String phone = data.getStringExtra("phone");                    String[] values = {name,phone,user.getName()};                    dao.update(values);                }                break;        }    }}

添加修改页面,这两个功能都用的是一个Activity,通过请求码和结果码判断是哪个按钮触发了这个Activity从而实现对应功能业务。

<?xml version="1.0" encoding="utf-8"?>            
import android.content.Intent;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.EditText;import com.example.lenovo.work.dbutil.UtilDao;/** * Created by lenovo on 2018/10/14. */public class AddData extends AppCompatActivity {    private EditText edit_name,edit_phone;    private Button but;    private UtilDao dao;    private Intent intent;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_adddata);        //初始化组件        initWidget();        DbUtil();        /**         * 点击编辑按钮传过来的值         * 用于显示当前编辑项的数据信息         * */        intent = getIntent();        String user_name = intent.getStringExtra("edit_name");        String user_phone = intent.getStringExtra("edit_phone");        edit_name.setText(user_name);        edit_phone.setText(user_phone);        but.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                //获取到两个输入框的值                    String name = edit_name.getText().toString();                    String phone = edit_phone.getText().toString();                    if(!name.equals("") && !phone.equals("")){                        /**                         * 数据库操作需要用到的数据                         * 详情请查看 UtilDao 类下的 addData() 方法                         * */                        String[] key = {"userName","userPhone"};                        String[] values = {name,phone};                        intent = new Intent();                        //点击添加按钮则返回 key 和 values 数组                        intent.putExtra("key",key);                        intent.putExtra("values",values);                        //点击编辑按钮则返回 name 和 phone 字符串                        intent.putExtra("name",name);                        intent.putExtra("phone",phone);                        setResult(RESULT_OK,intent);                        finish();                    } else if(name.equals("") || phone.equals("")){                        finish();                    }            }        });    }    /**     * 初始化控件     * */    private void initWidget(){        edit_name = findViewById(R.id.add_edit_name);        edit_phone = findViewById(R.id.add_edit_phone);        but = findViewById(R.id.add_but);    }    public void DbUtil(){        dao = ((MyApplication)this.getApplication()).getDao();    }}

OK!大功告成! 

最后附上AndroidManifest.xml文件代码:

<?xml version="1.0" encoding="utf-8"?>                                                                                            

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

源码

更多相关文章

  1. Android 中LayoutInflater(布局加载器)源码篇之rInflate方法
  2. Android创建和使用数据库
  3. Android解析Intent Filter的方法
  4. android中访问本机服务器的方法
  5. Android中使用imageviewswitcher 实现图片切换轮播导航的方法
  6. Android NDK环境创建方法简介

随机推荐

  1. Android原生(Native)C开发之二 framebuff
  2. android studio项目转ADT的辛酸历程
  3. 报Only the original thread that create
  4. Android开发应用记录
  5. windows下Android源码的分模块下载
  6. android视频桌面源码,酒店应用源码等
  7. Robolectric框架概述
  8. Flutter布局中嵌入Android原生组件 - 全
  9. 巧用AsyncTask的onProgressUpdate回调
  10. Android网络相关---上网流程