美文网首页
Android jetpack (Room篇1)

Android jetpack (Room篇1)

作者: 坑逼的严 | 来源:发表于2021-05-17 15:01 被阅读0次

用一个案例记录一下room笔记

实现本地数据库的学生列表的增删改查

image.png

按添加,弹出对话框,填入信息后添加一条数据到数据库,删除所有点击后清空student表下的数据,点击列表条目弹出修改框修改用户信息。当然每一次进入、添加、删除、修改等操作后自动查询用户信息并更新列表数据。
编写数据库先按3步走,entity -》Dao -》DataBase
引入room

implementation 'androidx.room:room-runtime:2.3.0-alpha03'
annotationProcessor 'androidx.room:room-compiler:2.3.0-alpha03'

1、我们先搭好实例类。

@Entity(tableName = "student")
public class Student {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    public int id;
    @ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
    public String name;
    @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)
    public int age;

    //room 需要的构造方法
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Ignore
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Ignore //添加忽略标签,这样的话room不会管这个方法或者变量
    public Student(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

关于注释,Entity是对表的标注,可以命名表的名称,PrimaryKey是主键它可以设置自增长,ColumnInfo是对列的注释,可能重命名列的名称和类型。Ignore是忽略的意思。
接下来是Dao

@Dao
public interface StudentDao {
    @Insert
    void insertStudent(Student... students);

    @Delete
    void deleteStudent(Student... students);

    @Query("DELETE FROM student")
    void deleteAllStudent();

    @Update
    void updateStudent(Student... students);

    @Query("SELECT * FROM student")
    List<Student> getAllStudent();

    @Query("SELECT * FROM student WHERE id = :id")
    List<Student> getAllStudentByID(int id);

    @Query("SELECT * FROM student")
    LiveData<List<Student>> getAllStudentByLiveData();
}

首先这是一个接口,具体的实现交给Room生成,Dao注释必须加上,否则编译报错。值得强调的一点,Query注释是可以写删除、修改等sql语句的。
接下来是database

@Database(entities = {Student.class}, version = 1,exportSchema = false)
public abstract class MyDataBese extends RoomDatabase {
    private static MyDataBese instance;
    private static final String mDBName="my_db.db";

    public static synchronized MyDataBese getInstance(Context context) {
        if(instance == null){
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    MyDataBese.class,
                    mDBName)
                    .build();
        }
        return instance;
    }
    public abstract StudentDao getStudentDao();
}

他是一个抽象类,因为getStudentDao是由room自动生成。这里用Room.databaseBuilder生成了最简单的配置。Database注释里面entities 就是代表自己数据库里有的表实例,exportSchema 是额外生成的数据库升级文件json数据。后面讲到数据库升级再设置为TRUE。
对了记住一点,room操作数据时默认需要在子线程下进行,否则会报错,如果需要在主线程进行,那么就添加allowMainThreadQueries()设置。

instance = Room.databaseBuilder(context.getApplicationContext(),
                    MyDataBese.class,
                    mDBName)
                    .allowMainThreadQueries()
                    .build();

数据库准备好了,那就准备我们的activity吧,当然需要结合我们的viewmodel、databinding、livedata去做。

public class RoomActivity extends AppCompatActivity {

    private ActivityRoomBinding mBinding;
    private MyViewModel mViewModel;
    private MyAdapter mAdapter;
    private StudentDao mStudentDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_room);
        mBinding.setOnClick(this);
        mViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
        initView();
        initDataBese();
    }

    private void initDataBese() {
        mStudentDao = MyDataBese.getInstance(this).getStudentDao();
        mStudentDao.getAllStudentByLiveData().observe(this, new Observer<List<Student>>() {
            @Override
            public void onChanged(List<Student> students) {
                Log.d("yanjin","size = "+students.size());
                mAdapter.updateList(students);
            }
        });
    }

    private void initView() {
        //initRecycleview
        initRecycleview();
    }

    private void initRecycleview() {
        mBinding.mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new MyAdapter(mViewModel.getStudents().getValue());
        mAdapter.setListener(new MyAdapter.OnLongClickListener() {
            @Override
            public void onLongClick(Student student) {
                //update student
                updateStudent(student);
            }
        });
        mBinding.mRecyclerView.setAdapter(mAdapter);
    }

    public void onClickView(View view){
        int id = view.getId();
        if(id == R.id.add){
            addStudent();
        }else if(id == R.id.delete_all){
            DeleteAllStudentAsyncTask task = new DeleteAllStudentAsyncTask(mStudentDao);
            task.execute();
        }
    }

    private void addStudent() {
        View view = getLayoutInflater().inflate(R.layout.add_student_layout,null);
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("添加学生")//设置对话框 标题
                .setView(view);
        builder.create();
        final AlertDialog dialog = builder.show();
        final EditText editName = view.findViewById(R.id.et_name);
        final EditText editAge = view.findViewById(R.id.et_age);
        view.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String ages = editAge.getText().toString().trim();
                    //有可能出现string转int出错
                    Integer age = Integer.valueOf(ages);
                    String name = editName.getText().toString().trim();
                    Student student = new Student(name,age);
                    AddStudentAsyncTask task = new AddStudentAsyncTask(mStudentDao);
                    task.execute(student);
                    dialog.dismiss();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });
    }

    private void updateStudent(Student student) {
        View view = getLayoutInflater().inflate(R.layout.update_student_layout,null);
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("添加学生")//设置对话框 标题
                .setView(view);
        builder.create();
        final AlertDialog dialog = builder.show();
        final EditText editName = view.findViewById(R.id.et_name);
        final EditText editAge = view.findViewById(R.id.et_age);
        final int id = student.getId();
        editName.setText(student.getName());
        editAge.setText(student.getAge()+"");
        view.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String ages = editAge.getText().toString().trim();
                    //有可能出现string转int出错
                    Integer age = Integer.valueOf(ages);
                    String name = editName.getText().toString().trim();
                    Student student = new Student(id,name,age);
                    UpdateStudentAsyncTask task = new UpdateStudentAsyncTask(mStudentDao);
                    task.execute(student);
                    dialog.dismiss();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });
    }
}

viewmodel

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<Student>> mStudents;

    public MutableLiveData<List<Student>> getStudents() {
        if(mStudents == null){
            mStudents = new MutableLiveData<>();
            mStudents.setValue(new ArrayList<Student>());
        }
        return mStudents;
    }
}

MyAdapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<Student> list;
    public MyAdapter(List<Student> list){
        this.list = list;
    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        RoomItemLayoutBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.room_item_layout, parent, false);
        return new ViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        final Student student = list.get(position);
        holder.mBinding.setStudent(student);
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if(mListener != null){
                    mListener.onLongClick(student);
                }
                return false;
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public void updateList(List<Student> students) {
        list.clear();
        list.addAll(students);
        notifyDataSetChanged();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        RoomItemLayoutBinding mBinding;
        public ViewHolder(@NonNull RoomItemLayoutBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }
    }

    public interface OnLongClickListener{
        void onLongClick(Student student);
    }
    private OnLongClickListener mListener;

    public void setListener(OnLongClickListener mListener) {
        this.mListener = mListener;
    }
}

AddStudentAsyncTask

public class AddStudentAsyncTask extends AsyncTask<Student, Void, Void>{
    private StudentDao mStudentDao;
    public AddStudentAsyncTask(StudentDao dao){
        mStudentDao = dao;
    }
    @Override
    protected Void doInBackground(Student... students) {
        mStudentDao.insertStudent(students);
        return null;
    }
}

DeleteAllStudentAsyncTask

public class DeleteAllStudentAsyncTask extends AsyncTask<Void, Void, Void>{
    private StudentDao mStudentDao;
    public DeleteAllStudentAsyncTask(StudentDao dao){
        mStudentDao = dao;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        mStudentDao.deleteAllStudent();
        return null;
    }
}

UpdateStudentAsyncTask

public class UpdateStudentAsyncTask extends AsyncTask<Student, Void, Void>{
    private StudentDao mStudentDao;
    public UpdateStudentAsyncTask(StudentDao dao){
        mStudentDao = dao;
    }
    @Override
    protected Void doInBackground(Student... students) {
        mStudentDao.updateStudent(students);
        return null;
    }
}

接下来的弹窗布局和列表条目布局如下:
add_student_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical">
    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:inputType="text"
        android:hint="请输入名字"/>
    <EditText
        android:id="@+id/et_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:inputType="number"
        android:hint="请输入年龄"/>
    <Button
        android:id="@+id/btn_ok"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ok"/>
</LinearLayout>

update_student_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical">
    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:inputType="text"
        android:hint="请输入名字"/>
    <EditText
        android:id="@+id/et_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:inputType="number"
        android:hint="请输入年龄"/>
    <Button
        android:id="@+id/btn_ok"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ok"/>
</LinearLayout>

room_item_layout.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="student"
            type="com.example.myapplication.jetpack.room.Student" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        xmlns:tools="http://schemas.android.com/tools">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="id"
            android:text="@{String.valueOf(student.id)}"
            android:textSize="18sp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:textColor="@android:color/black"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="name"
            android:text="@{student.name}"
            android:textSize="18sp"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:textColor="@android:color/black"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="age"
            android:text="@{String.valueOf(student.age)}"
            android:textSize="18sp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:textColor="@android:color/black"/>
    </RelativeLayout>
</layout>

相关文章

网友评论

      本文标题:Android jetpack (Room篇1)

      本文链接:https://www.haomeiwen.com/subject/qhsjjltx.html