增删改查是一个应用最基础的操作,增删改查的流程走通了,下面的路程也就顺利多了。现在使用Android Studio开发一个简单的应用,该应用就实现了增删改查的操作,看似简单,到底简不简单呢,下面开始操作。
本文的功能
为了简便,增删改查在一个页面实现;
为了简便,activity里面写原生的代码,不使用插件;
为了简便,数据存储在Sqlite数据库文件中,使用GreenDao中间件操作数据库;
对User表进行增删改查,字段有userName,age,userUid
第一步,建立一个app项目,先把界面画出来
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingRight="16dp"
android:paddingBottom="8dp"
tools:context=".MainActivity">
android:id="@+id/userUid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:hint="ID"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:id="@+id/userName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:hint="姓名"
android:imeOptions="actionDone"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/userUid" />
android:id="@+id/sex"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:hint="性别"
android:imeOptions="actionDone"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/userName" />
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="400dp"
android:gravity="left|center_vertical">
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新增"/>
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改"/>
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"/>
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="500dp"
android:gravity="left|center_vertical">
android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="根据id获取一个"/>
android:id="@+id/btn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取所有"/>
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="600dp"
android:gravity="left|center_vertical">
android:id="@+id/showText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
界面效果图:
图-1
对于一个新手,要把界面画画整齐,还是有难度的,这就需要学习xml中的水平布置和垂直布置。
第二步,配置greenDao
在这篇文章中,使用了BaseApplication,也就是在app创建的那一刻去创建了数据库。这样写就有个弊端,如果每一个登录的用户,都创建一个数据库,根据登录唯一标识作为数据库名称,那么在登录的时候,还没有登录成功的时候,是获取不到登录唯一标识的,所以不应该在application里面创建数据库。
实际的应用场景,可能不是在安装app的那一刻创建数据库,有可能是在登录之后进行创建,所以这次对数据库配置文件进行了修改,去掉了BaseApplication类,直接使用DbManager类,进行数据库的操作,其他两个类不变;另外,在DbManager类中增加了关闭数据库的操作,关闭了数据库,同时也要回收DaoMaster和DaoSession,只有把这两项回收了,才能再重新创建数据库连接实例,获取新的session。
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.example.myapplication3.dao.DaoMaster;
import com.example.myapplication3.dao.DaoSession;
/**
* 数据库管理类
*/
public class DbManager {
// 是否加密
public static final boolean ENCRYPTED = false;
private static DbManager mDbManager;
private static DaoMaster.DevOpenHelper mDevOpenHelper;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;
private Context mContext;
private DbManager(Context context) {
this.mContext = context;
// 初始化数据库信息
mDevOpenHelper = new DaoMaster.DevOpenHelper(context, getDbName());
getDaoMaster(context);
getDaoSession(context);
}
public static DbManager getInstance(Context context) {
if (null == mDbManager) {
synchronized (DbManager.class) {
if (null == mDbManager) {
mDbManager = new DbManager(context);
}
}
}
return mDbManager;
}
/**
* 获取可读数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getReadableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}
return mDevOpenHelper.getReadableDatabase();
}
/**
* 获取可写数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getWritableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}
return mDevOpenHelper.getWritableDatabase();
}
/**
* 获取DaoMaster
*
* 判断是否存在数据库,如果没有则创建数据库
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DbManager.class) {
if (null == mDaoMaster) {
MyOpenHelper helper = new MyOpenHelper(context,getDbName(),null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
}
}
}
return mDaoMaster;
}
/**
* 获取DaoMaster
*
* @param context
* @return
*/
// public static DaoMaster getDaoMaster(Context context) {
// if (null == mDaoMaster) {
// synchronized (DbManager.class) {
// if (null == mDaoMaster) {
//
// mDaoMaster = new DaoMaster(getWritableDatabase(context));
// }
// }
// }
// return mDaoMaster;
// }
/**
* 获取DaoSession
*
* @param context
* @return
*/
public static DaoSession getDaoSession(Context context) {
if (null == mDaoSession) {
synchronized (DbManager.class) {
mDaoSession = getDaoMaster(context).newSession();
}
}
return mDaoSession;
}
/**
* 获取数据库名称
* @return
*/
public static String getDbName(){
return "testdb.db";
}
/**
* 关闭数据库
*/
synchronized public void closeDb(){
if(mDevOpenHelper != null){
mDevOpenHelper.close();
}
mDevOpenHelper = null;
mDaoMaster = null;
mDaoSession = null;
}
}
第三步,编辑activity,对事件进行绑定;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.example.myapplication3.dbconfig.DbManager;
import com.example.myapplication3.entity.User;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//新增
findViewById(R.id.btn1).setOnClickListener(this);
//修改
findViewById(R.id.btn2).setOnClickListener(this);
//删除
findViewById(R.id.btn3).setOnClickListener(this);
//获取一个
findViewById(R.id.btn4).setOnClickListener(this);
//获取所有
findViewById(R.id.btn5).setOnClickListener(this);
}
@Override
public void onClick(View view) {
//新增操作
TextView textView = findViewById(R.id.userUid);
User user = new User();
user.setUserId(textView.getText().toString());
textView = findViewById(R.id.sex);
user.setSex(textView.getText().toString());
textView = findViewById(R.id.userName);
user.setUserName(textView.getText().toString());
List list = null;
switch(view.getId()){
case R.id.btn1:
//新增
DbManager.getDaoSession(this).getUserDao().insert(user);
break;
case R.id.btn2:
//修改
DbManager.getDaoSession(this).getUserDao().update(user);
break;
case R.id.btn3:
//删除
DbManager.getDaoSession(this).getUserDao().delete(user);
break;
case R.id.btn4:
//获取一个
user = DbManager.getDaoSession(this).getUserDao().load(user.getUserId());
textView = findViewById(R.id.showText);
textView.setText("ID:"+user.getUserId() +"性别:"+ user.getSex() + "姓名:"+user.getUserName());
break;
case R.id.btn5:
//获取所有
list = DbManager.getDaoSession(this).getUserDao().loadAll();
textView = findViewById(R.id.showText);
textView.setText("ID:"+list.get(0).getUserId() + "性别:" + list.get(0).getSex() + "姓名:"+list.get(0).getUserName()+"总数:" + list.size());
break;
}
}
}
测试结果:
新增-获取单个测试
修改-获取单个测试
新增-获取所有测试
删除-获取所有测试
从测试结果来看,操作都是ok的。当然,这里的实体类中,对用户名和ID都做了唯一标识验证,设置了@Unique,如果不符合表中唯一的话,系统报异常,app就被迫关闭了,嗯,验证没有做,或者再捕捉一下异常,就更完美了。
真实的业务需求,业务场景,需要在页面之间进行跳转,或者打开一个activity,并且需要传递参数等等。本示例并没有涉及到跳转,另外,获取所有的数据,展示的效果也很粗糙,如果一直这样写下去,估计也挺累人的,这不,已经深夜零点半了。
明天继续吧,应该是今晚,今晚争取把butterknife使用起来,毕竟视频都看过了,再不用起来,就彻底的忘记了,打铁要趁热,加油~!