美文网首页
Jetpack下的Room简单使用

Jetpack下的Room简单使用

作者: Smile_188 | 来源:发表于2021-07-15 10:36 被阅读0次

    概述

    Room持久性库在SQLite的基础上提供了一个抽象层,让用户能够在充分利用SQLite的强大功能的同时,获享更强健的数据库访问机制。

    添加依赖

    在app的build.gradle中添加如下依赖:

    
    def room_version ="2.2.6"
    
    implementation"androidx.room:room-runtime:$room_version"
    
    annotationProcessor"androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
    
    // Test helpers
    
    testImplementation"androidx.room:room-testing:$room_version"
    
    

    在app的build.gradle文件中,配置schemaLocation选项为app/schemas,方便我们查看数据库架构信息。

    
    defaultConfig{
    
    ...
    
        //指定room.schemaLocation生成的文件路径
    
        javaCompileOptions{
    
            annotationProcessorOptions{
    
                arguments =["room.schemaLocation":"$projectDir/schemas".toString()]
    
    }
    
    }
    
    }
    
    

    等我们创建好表和数据库等信息的时候,编译一下,会在app/schemas目录下生成这样的Json文件。


    QQ20210715-103958@2x.png

    创建一个实体类,对应数据库中的一张表

    
    @Entity(tableName ="User" ,indices ={@Index(value ={"user_name"}, unique =true)})//数据库实体
    
    public class User {
    
        @PrimaryKey(autoGenerate =true)
    
        private long id;
    
    @ColumnInfo(name ="user_name")
    
        private String name;
    
    @ColumnInfo(name ="user_gender")
    
        private String gender;
    
    private int age;
    
    private int type;
    
    public User() {
    
    }
    
        public User(long id,String name,String gender,int age,int type) {
    
            this.id = id;
    
    this.name = name;
    
    this.gender = gender;
    
    this.age = age;
    
    this.type = type;
    
    }
    
        public User(String name,String gender,int age,int type) {
    
            this.name = name;
    
    this.gender = gender;
    
    this.age = age;
    
    this.type = type;
    
    }
    
    
    • @Entity:注解的类对应数据库中的一张表,我们可以指定表名,如果不指定的话,默认是类的名字。

    • @PrimaryKey:每一个表都需要一个主键,这点需要注意,Room就是根据主键是否相同来判断是否是同一个对象。

    • @ColumnInfo:指定类的属性在表中列的名字,如果不指定,默认就是属性名。

    • 注意,存储在数据库中的类属性可见性必须是public的。

    创建DAO(data access object)

    DAO必须是接口或者抽象类,Room使用注解帮我们生成访问数据库的代码,感觉和Retrofit有类似之处。接下来我们创建一个DAO类,具有简单的增删改查的功能。

    
    @Dao //Database access object 数据库访问接口 所有增删改查等操作都在此声明
    
    public interface UserDao {
    
        // long 表示插入数据后返回的id
    
        @Insert(onConflict =OnConflictStrategy.REPLACE)
    
        void insertUser(User... user);
    
    // int 影响的行数
    
        @Update
    
        int updateUser(User... user);
    
    @Delete
    
        int deleteUser(User... user);
    
    @Query("DELETE FROM USER")
    
        void deleteUser();
    
    @Query("SELECT * FROM USER ORDER BY ID DESC")
    
        List<User> getAllUser();
    
    @Query("SELECT * FROM USER ORDER BY ID DESC")
    
        LiveData<List<User>> getAllUserLive();
    
    }
    
    

    添加Room数据库

    
    //exportSchema = false 是不会导出 schemas json 结构
    
    @Database(entities ={User.class}, version =2, exportSchema =true)
    
    public abstract class UserDatabase extends RoomDatabase {
    
        public abstract UserDao getUserDao();
    
    private static UserDatabase userDatabase;
    
    synchronized public static UserDatabase getUserDatabase(Context context) {
    
            if (null ==userDatabase) {
    
                userDatabase =Room.databaseBuilder(context.getApplicationContext(),UserDatabase.class,"android_room_dev.db")
    
                        .allowMainThreadQueries()
    
                        .addMigrations(migration) //保留原有数据
    
                        .build();
    
    }
    
            return userDatabase;
    
    }
    
        static final Migration migration =new Migration(1,2) {
    
            @Override
    
            public void migrate(@NonNull SupportSQLiteDatabase database) {
    
                database.execSQL("ALTER TABLE user ADD COLUMN type INTEGER NOT NULL DEFAULT 1");
    
    //sqlLet没有删除字段语句,只能创建新的数据库定义需要的字段,将原有数据库数据复制过去,删除旧数据库后再将新数据库重命名
    
            }
    
        };
    
    }
    
    

    Room数据库必须是一个继承自RoomDatabase的抽象类。通常情况下应用内应该只有一个Room数据库实例。

    在demo中的简单使用

    
    public class MainActivity extends AppCompatActivity {
    
        TextView tvAdd;
    
    TextView tvUpdate;
    
    TextView tvDelete;
    
    TextView tvQuery;
    
    TextView tvQueryAll;
    
    TextView tvContent;
    
    UserDatabase userDatabase;
    
    @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
    userDatabase =UserDatabase.getUserDatabase(this);
    
    setContentView(R.layout.activity_main);
    
    tvAdd = findViewById(R.id.tv_add);
    
    tvUpdate = findViewById(R.id.tv_update);
    
    tvDelete = findViewById(R.id.tv_delete);
    
    tvQuery = findViewById(R.id.tv_query);
    
    tvQueryAll = findViewById(R.id.tv_queryAll);
    
    tvContent = findViewById(R.id.tv_content);
    
    UserDao userDao =userDatabase.getUserDao();
    
    LiveData<List<User>> listLiveData =userDao.getAllUserLive();
    
    listLiveData.observe(this,new Observer<List<User>>() {
    
                @Override
    
                public void onChanged(List<User> users) {
    
                    String s ="";
    
    for (int i =0; i < users.size(); i++) {
    
                        User user = users.get(i);
    
    s +="姓名:" +user.getName() +"性别:" +user.getGender() +"年龄:" +user.getAge() +"类型:" +user.getType() +"\n";
    
    }
    
                    tvContent.setText(s);
    
    }
    
            });
    
    tvAdd.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View view) {
    
                    User user =new User();
    
    user.setName("张三" +new Random().nextInt(100));
    
    user.setAge(new Random().nextInt(100));
    
    user.setGender(new Random().nextInt(1) +"");
    
    user.setType(new Random().nextInt(9));
    
    userDao.insertUser(user);
    
    }
    
            });
    
    tvUpdate.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View view) {
    
                    List<User> users =userDao.getAllUser();
    
    User user =users.get(0);
    
    user.setName("玛丽哈利");
    
    userDao.updateUser(user);
    
    }
    
            });
    
    tvDelete.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View view) {
    
                    List<User> users =userDao.getAllUser();
    
    if(users!=null &&users.size()>0){
    
                        User user =users.get(0);
    
    userDao.deleteUser(user);
    
    }
    
    }
    
            });
    
    tvQuery.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View view) {
    
                    List<User> users =userDao.getAllUser();
    
    String s ="";
    
    for (int i =0; I
    
                        User user =users.get(i);
    
    s +="姓名:" +user.getName() +"性别:" +user.getGender() +"年龄:" +user.getAge() +"类型:" +user.getType() +"\n";
    
    }
    
                    Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
    
    }
    
            });
    
    tvQueryAll.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View view) {
    
    }
    
            });
    
    }
    
    }
    
    ```**概述**
    
    Room持久性库在SQLite的基础上提供了一个抽象层,让用户能够在充分利用SQLite的强大功能的同时,获享更强健的数据库访问机制。
    
    **添加依赖**
    
    在app的build.gradle中添加如下依赖:
    
    

    def room_version ="2.2.6"

    implementation"androidx.room:room-runtime:$room_version"

    annotationProcessor"androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

    // Test helpers

    testImplementation"androidx.room:room-testing:$room_version"

    
    **在app的build.gradle文件中,配置schemaLocation选项为app/schemas,方便我们查看数据库架构信息。**
    
    

    defaultConfig{

    ...

    //指定room.schemaLocation生成的文件路径
    
    javaCompileOptions{
    
        annotationProcessorOptions{
    
            arguments =["room.schemaLocation":"$projectDir/schemas".toString()]
    

    }

    }

    }

    
    等我们创建好表和数据库等信息的时候,编译一下,会在app/schemas目录下生成这样的Json文件。
    
    【 ! + [图片名称] + (https://img.haomeiwen.com/i7182690/7cae1e445eb5801c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1200) 】
    
    **创建一个实体类,对应数据库中的一张表**
    
    

    @Entity(tableName ="User" ,indices ={@Index(value ={"user_name"}, unique =true)})//数据库实体

    public class User {

    @PrimaryKey(autoGenerate =true)
    
    private long id;
    

    @ColumnInfo(name ="user_name")

    private String name;
    

    @ColumnInfo(name ="user_gender")

    private String gender;
    

    private int age;

    private int type;

    public User() {

    }

    public User(long id,String name,String gender,int age,int type) {
    
        this.id = id;
    

    this.name = name;

    this.gender = gender;

    this.age = age;

    this.type = type;

    }

    public User(String name,String gender,int age,int type) {
    
        this.name = name;
    

    this.gender = gender;

    this.age = age;

    this.type = type;

    }

    
    +  @Entity:注解的类对应数据库中的一张表,我们可以指定表名,如果不指定的话,默认是类的名字。
    
    +  @PrimaryKey:每一个表都需要一个主键,这点需要注意,Room就是根据主键是否相同来判断是否是同一个对象。
    
    +  @ColumnInfo:指定类的属性在表中列的名字,如果不指定,默认就是属性名。
    
    +  注意,存储在数据库中的类属性可见性必须是public的。
    
    **创建DAO(data access object)**
    
    DAO必须是接口或者抽象类,Room使用注解帮我们生成访问数据库的代码,感觉和Retrofit有类似之处。接下来我们创建一个DAO类,具有简单的增删改查的功能。
    
    

    @Dao //Database access object 数据库访问接口 所有增删改查等操作都在此声明

    public interface UserDao {

    // long 表示插入数据后返回的id
    
    @Insert(onConflict =OnConflictStrategy.REPLACE)
    
    void insertUser(User... user);
    

    // int 影响的行数

    @Update
    
    int updateUser(User... user);
    

    @Delete

    int deleteUser(User... user);
    

    @Query("DELETE FROM USER")

    void deleteUser();
    

    @Query("SELECT * FROM USER ORDER BY ID DESC")

    List<User> getAllUser();
    

    @Query("SELECT * FROM USER ORDER BY ID DESC")

    LiveData<List<User>> getAllUserLive();
    

    }

    
    **添加Room数据库**
    
    

    //exportSchema = false 是不会导出 schemas json 结构

    @Database(entities ={User.class}, version =2, exportSchema =true)

    public abstract class UserDatabase extends RoomDatabase {

    public abstract UserDao getUserDao();
    

    private static UserDatabase userDatabase;

    synchronized public static UserDatabase getUserDatabase(Context context) {

        if (null ==userDatabase) {
    
            userDatabase =Room.databaseBuilder(context.getApplicationContext(),UserDatabase.class,"android_room_dev.db")
    
                    .allowMainThreadQueries()
    
                    .addMigrations(migration) //保留原有数据
    
                    .build();
    

    }

        return userDatabase;
    

    }

    static final Migration migration =new Migration(1,2) {
    
        @Override
    
        public void migrate(@NonNull SupportSQLiteDatabase database) {
    
            database.execSQL("ALTER TABLE user ADD COLUMN type INTEGER NOT NULL DEFAULT 1");
    

    //sqlLet没有删除字段语句,只能创建新的数据库定义需要的字段,将原有数据库数据复制过去,删除旧数据库后再将新数据库重命名

        }
    
    };
    

    }

    
    Room数据库必须是一个继承自RoomDatabase的抽象类。通常情况下应用内应该只有一个Room数据库实例。
    
    **在demo中的简单使用**
    
    

    public class MainActivity extends AppCompatActivity {

    TextView tvAdd;
    

    TextView tvUpdate;

    TextView tvDelete;

    TextView tvQuery;

    TextView tvQueryAll;

    TextView tvContent;

    UserDatabase userDatabase;

    @Override

    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
    

    userDatabase =UserDatabase.getUserDatabase(this);

    setContentView(R.layout.activity_main);

    tvAdd = findViewById(R.id.tv_add);

    tvUpdate = findViewById(R.id.tv_update);

    tvDelete = findViewById(R.id.tv_delete);

    tvQuery = findViewById(R.id.tv_query);

    tvQueryAll = findViewById(R.id.tv_queryAll);

    tvContent = findViewById(R.id.tv_content);

    UserDao userDao =userDatabase.getUserDao();

    LiveData<List<User>> listLiveData =userDao.getAllUserLive();

    listLiveData.observe(this,new Observer<List<User>>() {

            @Override
    
            public void onChanged(List<User> users) {
    
                String s ="";
    

    for (int i =0; i < users.size(); i++) {

                    User user = users.get(i);
    

    s +="姓名:" +user.getName() +"性别:" +user.getGender() +"年龄:" +user.getAge() +"类型:" +user.getType() +"\n";

    }

                tvContent.setText(s);
    

    }

        });
    

    tvAdd.setOnClickListener(new View.OnClickListener() {

            @Override
    
            public void onClick(View view) {
    
                User user =new User();
    

    user.setName("张三" +new Random().nextInt(100));

    user.setAge(new Random().nextInt(100));

    user.setGender(new Random().nextInt(1) +"");

    user.setType(new Random().nextInt(9));

    userDao.insertUser(user);

    }

        });
    

    tvUpdate.setOnClickListener(new View.OnClickListener() {

            @Override
    
            public void onClick(View view) {
    
                List<User> users =userDao.getAllUser();
    

    User user =users.get(0);

    user.setName("玛丽哈利");

    userDao.updateUser(user);

    }

        });
    

    tvDelete.setOnClickListener(new View.OnClickListener() {

            @Override
    
            public void onClick(View view) {
    
                List<User> users =userDao.getAllUser();
    

    if(users!=null &&users.size()>0){

                    User user =users.get(0);
    

    userDao.deleteUser(user);

    }

    }

        });
    

    tvQuery.setOnClickListener(new View.OnClickListener() {

            @Override
    
            public void onClick(View view) {
    
                List<User> users =userDao.getAllUser();
    

    String s ="";

    for (int i =0; I

                    User user =users.get(i);
    

    s +="姓名:" +user.getName() +"性别:" +user.getGender() +"年龄:" +user.getAge() +"类型:" +user.getType() +"\n";

    }

                Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
    

    }

        });
    

    tvQueryAll.setOnClickListener(new View.OnClickListener() {

            @Override
    
            public void onClick(View view) {
    

    }

        });
    

    }

    }

    相关文章

      网友评论

          本文标题:Jetpack下的Room简单使用

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