先看运行效果图。
1.在app下的build.gradle。在dependencies{}闭包中添加如下依赖
//room
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
完整的内容如下
plugins {
id 'com.android.application'
}
android {
namespace 'com.example.myapplication001'
compileSdk 32
defaultConfig {
applicationId "com.xfjlfile.app"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
// 设置支持的SO库架构
abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//room。在这里写上你的依赖
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
}
点击Sync进行同步一下。
2.注解使用
注解使用,Room使用很简单的,这里有三个基本的使用注解,
@Database、@Entity、@Dao。分别对于数据库、表、表的具体操作(增删改查)。
例如创建一个数据表User。创建User类。代码内容如下
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
//这是一个实体类对象。
//@Entity就是表示数据库中的表。用这个来注解,一定要写的
@Entity
public class User {
//主键id,自增长
@PrimaryKey(autoGenerate = true)
@NonNull
public int id;
//用户名
@ColumnInfo(name = "user_name", defaultValue = "")
public String userName;
//用户年龄
@ColumnInfo(name = "user_age")
public int userAge;
//用户别称
@ColumnInfo(name = "nick_name")
public String nickName;
//用户地址
@ColumnInfo(name = "address")
public String address;
public User(String userName, int userAge, String nickName, String address) {
this.id = id;
this.userName = userName;
this.userAge = userAge;
this.nickName = nickName;
this.address = address;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserAge() {
return this.userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
public String getNickName() {
return this.nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
}
这个类很平常,主要是注解的说明,这个@Entity就是表示数据库中的表,
User类对应就是User表,@PrimaryKey表示主键,这里是id,
autoGenerate = true 是自增,@NonNull表示不为空。
@ColumnInfo表示表中的列名,name = "user_name"表示列名的值。
Room是对象关系映射型数据库,所以你可以不用写这个@ColumnInfo注解,
写它主要是为了设置列名,不写则使用变量名做为列名。
假设我一个表中有30个字段,实际上用到的只有5个,
那么另外25个就不需要进行创建了,则使用@Ignore注解进行忽略。
例如这样。看如下内容
@Ignore
@ColumnInfo(name = "address")
public String address;
创建UserDao类,代码如下
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
//@Dao就是表的具体操作(增删改查)。用这个来注解,一定要写的
@Dao
public interface UserDao {
/**
* 增加
*
* @param users 用户
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertUser(User... users);
/**
* 查询所有用户
* @return 用户列表
*/
@Query("SELECT * FROM user")
List<User> queryAll();
/**
* 按用户名查询
* @param userName 用户名
* @return 用户
*/
// @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
@Query("SELECT * FROM user WHERE user_name= :userName")
User findByName(String userName);
/**
* 按用户年龄查询
* @param user_Age 用户年龄
* @return 用户
*/
// @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
@Query("SELECT * FROM user WHERE user_age= :user_Age")
User findByAge(String user_Age);
/**
* 按条件查询
* @param userName 用户名称
* @param user_Age 用户年龄
* @param address 用户地址
* @return 用户
*/
// @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
@Query("SELECT * FROM user WHERE user_name= :userName and user_age= :user_Age and address= :address")
User findByAll(String userName,int user_Age,String address);
/**
* 修改
* @param user 根据用户进行修改
*/
@Update
void update(User user);
/**
* 删除
* @param user 根据用户进行删除
*/
@Delete
void delete(User user);
//删除整张表的数据
@Query("DELETE FROM user")
void deleteAll();
}
UserDao是一个接口,主要是定义了一些方法,通过注解在编译的时候会生成实现类。
下面是数据库的创建,新建一个MyDatabase类,继承RoomDatabase,代码如下
import androidx.room.Database;
import androidx.room.RoomDatabase;
//@Database对应数据库。用这个来注解,一定要写的
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
这里的@Database注解表示这个类是用来操作数据库的,entities = {User.class}表示当前数据库中的表,只有一个User表,多的表用英文逗号隔开。version = 1表示数据库的版本,可以做数据库的升级操作。
注意这是一个抽象类,在编译时Room会帮助构建实现类。
现在运行一下,手机或者模拟器都可以。然后什么都不用去做。会出现如下图内容
可以查看到,MyDatabase和UserDao的实现类都自动生成了。
3.主活动MainActivity2类。代码内容如下
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.myapplication001.R;
import java.util.ArrayList;
import java.util.List;
public class MainActivity2 extends AppCompatActivity {
private MyDatabase db;
private List<User> mList = new ArrayList<>();
HomeAdapter homeAdapter;
@SuppressLint({"MissingInflatedId", "WrongViewCast"})
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
}
/**
* 初始化
*/
private void initView() {
//列表
RecyclerView rv = findViewById(R.id.rv);
homeAdapter = new HomeAdapter(getApplicationContext(),mList);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(homeAdapter);
//初始化数据库
initDB();
findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了新增所有", Toast.LENGTH_SHORT).show();
addUser();
}
});
findViewById(R.id.btn_add_yg).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了新增一个用户", Toast.LENGTH_SHORT).show();
addUser_yg();
}
});
findViewById(R.id.btn_delete).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了删除所有", Toast.LENGTH_SHORT).show();
deleteAll();
}
});
findViewById(R.id.btn_sc_mc).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了删除用户名", Toast.LENGTH_SHORT).show();
deleteUser();
}
});
findViewById(R.id.btn_update).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了修改", Toast.LENGTH_SHORT).show();
updateUser();
}
});
findViewById(R.id.btn_query).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了查询所有", Toast.LENGTH_SHORT).show();
queryAll();
}
});
findViewById(R.id.btn_cx).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了查询名称", Toast.LENGTH_SHORT).show();
query_dg();
}
});
findViewById(R.id.btn_nl).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了查询年龄", Toast.LENGTH_SHORT).show();
query_nl();
}
});
findViewById(R.id.btn_tj).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity2.this, "用户点击了按条件查询", Toast.LENGTH_SHORT).show();
query_tj();
}
});
}
/**
* 初始化数据库
*/
private void initDB() {
//本地持久化数据库
db = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, "DemoDB")
//是否允许在主线程上操作数据库,默认false。
.allowMainThreadQueries()
//数据库创建和打开的事件会回调到这里,可以再次操作数据库
.addCallback(new CallBack())
.build();
}
static class CallBack extends RoomDatabase.Callback {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Log.d("111333", "db create");
}
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
Log.d("111333", "db open");
}
}
/**
* 增加所有用户
*/
private void addUser() {
runOnUiThread(() -> {
db.userDao().insertUser(
new User("张三", 20, "张大炮", "北京八宝山4号墓地"),
new User("李四", 60, "尼古拉斯.凯奇", "美国佛罗里达州"),
new User("王五", 70, "爱新觉罗.爱国", "北京故宫乾清宫西北方向角落"),
new User("赵六", 30, "叶赫那拉.啦啦啦", "北京前门外前门大街皮条胡同")
);
Toast.makeText(MainActivity2.this,"增加所有用户成功",Toast.LENGTH_SHORT).show();
});
}
/**
* 增加用户
*/
private void addUser_yg() {
runOnUiThread(() -> {
db.userDao().insertUser(
new User("北京", 25, "顽固派", "广东广州天河区旺角")
);
Toast.makeText(MainActivity2.this,"增加用户成功",Toast.LENGTH_SHORT).show();
});
}
/**
* 删除所有
*/
private void deleteAll() {
runOnUiThread(() -> {
db.userDao().deleteAll();
Toast.makeText(MainActivity2.this, "删除所有成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 删除用户
*/
private void deleteUser() {
runOnUiThread(() -> {
User user = db.userDao().findByName("张三");
if (user == null) return;
//这个是按用户名删除
db.userDao().delete(user);
Toast.makeText(MainActivity2.this, "删除用户成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 修改用户
*/
private void updateUser() {
runOnUiThread(() -> {
User user = db.userDao().findByName("李四");
if (user == null) return;
user.setUserName("赵四");
user.setUserAge(10);
user.setNickName("尼古拉斯.赵四");
user.setAddress("中国东北");
db.userDao().update(user);
Toast.makeText(MainActivity2.this, "修改成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 查询所有用户
*/
private void queryAll() {
runOnUiThread(() -> {
mList.clear();
mList.addAll(db.userDao().queryAll());
homeAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity2.this, "查询所有用户成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 查询名称
*/
private void query_dg() {
runOnUiThread(() -> {
mList.clear();
User user = db.userDao().findByName("王五");
if (user == null) {
Log.d("111333","数据为空");
return;
}else {
Log.d("111333","有数据");
}
mList.add(user);
homeAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity2.this, "查询用户名称成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 查询年龄
*/
private void query_nl() {
runOnUiThread(() -> {
mList.clear();
User user = db.userDao().findByAge("20");
if (user == null) {
Log.d("111333","数据为空");
return;
}else {
Log.d("111333","有数据");
}
mList.add(user);
homeAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity2.this, "查询年龄成功", Toast.LENGTH_SHORT).show();
});
}
/**
* 按条件查询
*/
private void query_tj() {
runOnUiThread(() -> {
mList.clear();
User user = db.userDao().findByAll("赵六",30,"北京前门外前门大街皮条胡同");
if (user == null) {
Log.d("111333","数据为空");
return;
}else {
Log.d("111333","有数据");
}
mList.add(user);
homeAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity2.this, "按条件查询成功", Toast.LENGTH_SHORT).show();
});
}
}
4.主活动MainActivity2的activity_main2布局文件内容如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refreshLa"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="新增所有" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btn_add_yg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="新增一个用户" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除所有" />
<Button
android:id="@+id/btn_sc_mc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除用户名" />
</LinearLayout>
<Button
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/btn_query"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="查询所有" />
<Button
android:id="@+id/btn_cx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="查询王五" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/btn_nl"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="查询年龄20" />
<Button
android:id="@+id/btn_tj"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="按条件查询" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
5.主活动的适配器HomeAdapter类,代码内容如下
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication001.R;
import java.util.List;
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{
private Context mContext;
List<User> list;
public HomeAdapter(Context mContext, List<User> list) {
this.mContext = mContext;
this.list=list;
}
/**
* 设置布局
* @param viewGroup
* @param i
* @return
*/
@Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recycler,viewGroup,false));
return holder;
}
/**
* 为控件绑定数据
* @param myViewHolder
* @param position
*/
@Override
public void onBindViewHolder(MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) {
myViewHolder.tv_id.setText(list.get(position).getId()+"");
myViewHolder.tv_name.setText(list.get(position).getUserName());
myViewHolder.tv_age.setText(list.get(position).getUserAge()+"");
myViewHolder.tv_nickname.setText(list.get(position).getNickName());
myViewHolder.tv_address.setText(list.get(position).getAddress());
}
/**
* 返回项个数
* @return
*/
@Override
public int getItemCount() {
return list.size();
}
/**
* 定义控件并初始化
*/
class MyViewHolder extends RecyclerView.ViewHolder{
TextView tv_id,tv_name,tv_age,tv_nickname,tv_address;
public MyViewHolder(View itemView) {
super(itemView);
tv_id = itemView.findViewById(R.id.tv_id);
tv_name = itemView.findViewById(R.id.tv_name);
tv_age = itemView.findViewById(R.id.tv_age);
tv_nickname = itemView.findViewById(R.id.tv_nickname);
tv_address = itemView.findViewById(R.id.tv_address);
}
}
}
6.主活动的适配器HomeAdapter的item_recycler布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="Id"
android:textColor="@color/black" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="name"
android:textColor="@color/black" />
<TextView
android:id="@+id/tv_age"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="age"
android:textColor="@color/black" />
<TextView
android:id="@+id/tv_nickname"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="nickname"
android:textColor="@color/black" />
<TextView
android:id="@+id/tv_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:padding="10dp"
android:text="address"
android:textColor="@color/black" />
</LinearLayout>
<View
android:id="@+id/view"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:background="#E1DFDF" />
</LinearLayout>