【Android】Room数据库的基本使用

【Android】Room数据库的基本使用

【Android】Room数据库的基本使用

一、什么是Room

1.1 Room简介

Room是Android Jetpack组件库中的一部分,对SQLite进行了封装,简化了对SQLite数据库的操作,让开发者使用面向对象的方式(通过Java/Kotlin)来操作SQLite数据库,从而避免了编写大量繁琐的SQL代码和解析数据。

1.2 三大核心组件

  • Entity(实体类):用于表示数据库表的数据结构。
  • DAO(Data A***ess Object):用于定义数据库操作的方法。
  • Database(数据库类):用于创建数据库实例,并将 Entity 和 DAO 关联起来

二、使用步骤

2.1 添加依赖

在app下的build.gradle下添加:

// app/build.gradle
dependencies {
    implementation "androidx.room:room-runtime:2.6.1"
    annotationProcessor "androidx.room:room-***piler:2.6.1"
}

2.2 创建实体类 (Entity)

创建一个表示数据库表的 Java 类:

@Entity(tableName = "user-room")
public class MyUser {
    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "user_age")
    private int age;

    @ColumnInfo(name = "user_name")
    private String name;

    @ColumnInfo(name = "user_email")
    private String email;

    // 构造函数
    public MyUser(int age, String name, String email) {
        this.age = age;
        this.name = name;
        this.email = email;
    }

    // Getter 和 Setter 方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}
  • 各注解作用:
  • @Entity(tableName = "user-room"):标记这是一个数据库表,同时指定表名
  • @PrimaryKey(autoGenerate = true):设置主键并启用自动生成
  • @ColumnInfo(name = "user_age"):设置列名

2.3 创建数据访问对象(DAO)

创建一个接口定义数据库操作:

@Dao
public interface MyUserDao {
    // 插入用户
    @Insert
    void insertUser(MyUser user);
    
    // 更新用户(通过对象)
    @Update
    int updateUser(MyUser user);
    
    // 更新用户(通过名称,将age更新为传入的值)
    @Query("UPDATE `user-room` SET user_age = :age WHERE user_name = :name")
    int updateUser(String name, int age);
    
    // 查询所有用户
    @Query("SELECT * FROM `user-room`")
    List<MyUser> getAllUsers();
    
    // 查询特定用户(通过名称)
    @Query("SELECT * FROM `user-room` WHERE user_name = :name")
    List<MyUser> getUserByName(String name);
    
    // 删除用户(通过对象)
    @Delete
    int deleteUser(MyUser user);
    
    // 删除用户(通过名称)
    @Query("DELETE FROM `user-room` WHERE user_name = :name")
    int deleteUserByName(String name);
}
  • 各注解作用:
  • @Dao:标记这是一个数据访问对象接口
  • @Insert@Update@Delete:由Room 提供的便捷注解,可以自动生成对应 SQL
  • @Query:自定义 SQL 查询,:参数名表示方法参数

2.4 创建数据库类

创建一个抽象类用于扩展 RoomDatabase:

@Database(entities = {MyUser.class}, version = 1)
public abstract class MyUserDatabase extends RoomDatabase {
    public abstract MyUserDao userDao();
    
    // 数据库迁移(版本1到2)
    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            // 添加新列user_email
            database.execSQL("ALTER TABLE `user-room` ADD COLUMN user_email TEXT");
        }
    };
}
  • 各注解作用:
  • @Database(entities = {MyUser.class}, version = 1):标记数据库类,指定包含的表和版本号
  • Migration:定义数据库版本迁移逻辑

关于数据库迁移:

  • 数据库迁移的核心作用是在修改数据库结构后(比如在实体类中添加新字段或是在库中添加新表),安全、无损地将旧版本数据库升级到新版本,同时保留用户的原有数据。

  • 版本迁移逻辑:必须增加数据库的版本号,并提供一个Migration对象来告诉Room如何从旧版本正确迁移到新版本。

2.5 在Activity中使用数据库

在Activity中初始化数据库并执行操作:

public class MainActivity extends App***patActivity {
    private MyUserDatabase userDatabase;
    private EditText nameEditText, ageEditText, emailEditText;
    private TextView resultTextView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 初始化视图
        nameEditText = findViewById(R.id.et_name);
        ageEditText = findViewById(R.id.et_age);
        emailEditText = findViewById(R.id.et_email);
        resultTextView = findViewById(R.id.tv_result);
        
        // 初始化数据库
        userDatabase = Room.databaseBuilder(getApplicationContext(),
                MyUserDatabase.class, "user-database.db")
                .addMigrations(MyUserDatabase.MIGRATION_1_2) // 添加迁移规则
                .build();
        
        // 设置按钮点击事件
        findViewById(R.id.btn_insert).setOnClickListener(v -> insertUser());
        findViewById(R.id.btn_query).setOnClickListener(v -> queryUsers());
        findViewById(R.id.btn_update).setOnClickListener(v -> updateUser());
        findViewById(R.id.btn_delete).setOnClickListener(v -> deleteUser());
    }
    
    // 插入用户
    private void insertUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                int age = Integer.parseInt(ageEditText.getText().toString());
                String email = emailEditText.getText().toString();
                
                MyUser user = new MyUser(age, name, email);
                userDatabase.userDao().insertUser(user);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "用户添加成功", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
    
    // 查询用户
    private void queryUsers() {
        new Thread(() -> {
            List<MyUser> users = userDatabase.userDao().getAllUsers();
            StringBuilder result = new StringBuilder("所有用户:\n");
            
            for (MyUser user : users) {
                result.append("ID: ").append(user.getId())
                      .append(", 姓名: ").append(user.getName())
                      .append(", 年龄: ").append(user.getAge())
                      .append(", 邮箱: ").append(user.getEmail())
                      .append("\n");
            }
            
            runOnUiThread(() -> resultTextView.setText(result.toString()));
        }).start();
    }
    
    // 更新用户
    private void updateUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                int age = Integer.parseInt(ageEditText.getText().toString());
                
                int updatedRows = userDatabase.userDao().updateUser(name, age);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "更新了 " + updatedRows + " 行数据", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
    
    // 删除用户
    private void deleteUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                
                int deletedRows = userDatabase.userDao().deleteUserByName(name);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "删除了 " + deletedRows + " 行数据", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (userDatabase != null && userDatabase.isOpen()) {
            userDatabase.close();
        }
    }
}
2.5.1 创建数据库
 // 初始化数据库
        userDatabase = Room.databaseBuilder(getApplicationContext(),
                MyUserDatabase.class, "user-database.db")
                .addMigrations(MyUserDatabase.MIGRATION_1_2) // 添加迁移规则
                .build();
  • 参数一:上下文
  • 参数二:数据库的class对象
  • 参数三:表示要创建的 SQLite 数据库文件的名称。
2.5.1 增
// 插入用户
    @Insert
    void insertUser(MyUser user);
// 插入用户
    private void insertUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                int age = Integer.parseInt(ageEditText.getText().toString());
                String email = emailEditText.getText().toString();
                
                MyUser user = new MyUser(age, name, email);
                userDatabase.userDao().insertUser(user);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "用户添加成功", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

主要要在非主线程中进行,数据库操作是一个非常耗时的操作,在主线程进行可能会引起卡顿和崩溃,不过在Room操作中可以不用新开线程,因为它内部已经帮我们处理好了

2.5.2 删
// 删除用户(通过对象)
    @Delete
    int deleteUser(MyUser user);
    
    // 删除用户(通过名称)
    @Query("DELETE FROM `user-room` WHERE user_name = :name")
    int deleteUserByName(String name);
// 删除用户
    private void deleteUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                
                int deletedRows = userDatabase.userDao().deleteUserByName(name);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "删除了 " + deletedRows + " 行数据", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
2.5.3 查
// 查询所有用户
    @Query("SELECT * FROM `user-room`")
    List<MyUser> getAllUsers();
// 查询用户
    private void queryUsers() {
        new Thread(() -> {
            List<MyUser> users = userDatabase.userDao().getAllUsers();
            StringBuilder result = new StringBuilder("所有用户:\n");
            
            for (MyUser user : users) {
                result.append("ID: ").append(user.getId())
                      .append(", 姓名: ").append(user.getName())
                      .append(", 年龄: ").append(user.getAge())
                      .append(", 邮箱: ").append(user.getEmail())
                      .append("\n");
            }
            
            runOnUiThread(() -> resultTextView.setText(result.toString()));
        }).start();
    }
2.5.4 改
// 更新用户(通过对象)
    @Update
    int updateUser(MyUser user);
    
    // 更新用户(通过名称,将age更新为传入的值)
    @Query("UPDATE `user-room` SET user_age = :age WHERE user_name = :name")
    int updateUser(String name, int age);
// 更新用户
    private void updateUser() {
        new Thread(() -> {
            try {
                String name = nameEditText.getText().toString();
                int age = Integer.parseInt(ageEditText.getText().toString());
                
                int updatedRows = userDatabase.userDao().updateUser(name, age);
                
                runOnUiThread(() -> Toast.makeText(MainActivity.this, 
                    "更新了 " + updatedRows + " 行数据", Toast.LENGTH_SHORT).show());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

2.6 布局文件(activity_main)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.***/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入姓名"/>
    
    <EditText
        android:id="@+id/et_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入年龄"
        android:inputType="number"/>
    
    <EditText
        android:id="@+id/et_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入邮箱"
        android:inputType="textEmailAddress"/>
    
    <Button
        android:id="@+id/btn_insert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加用户"/>
    
    <Button
        android:id="@+id/btn_query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="查询所有用户"/>
    
    <Button
        android:id="@+id/btn_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="更新用户"/>
    
    <Button
        android:id="@+id/btn_delete"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="删除用户"/>
    
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"/>
</LinearLayout>
转载请说明出处内容投诉
CSS教程网 » 【Android】Room数据库的基本使用

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买