前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android-Jetpack笔记-Room

Android-Jetpack笔记-Room

作者头像
Holiday
发布2020-08-10 14:52:19
4920
发布2020-08-10 14:52:19
举报
文章被收录于专栏:哈利迪ei哈利迪ei

Room是一种ORM(对象关系映射)框架,可以用OOP(面向对象)的思路开发数据库,有点像早期的greenDAO,不过Room作为Jetpack的一员,能够返回更多类型的数据,比如能直接返回DataSource.Factory来友好的支持Paging的使用,本文主要总结基础的使用和原理。

Jetpack笔记代码

本文源码基于SDK 29

使用

引入依赖:

代码语言:javascript
复制
def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
//注解处理器,用于编译期根据注解来生成类
annotationProcessor "androidx.room:room-compiler:$room_version"

@Entity表示一个实体,即数据库中表的定义,

代码语言:javascript
复制
//声明一个实体User,表名为t_user
@Entity(tableName = "t_user")
class User {
    @PrimaryKey(autoGenerate = true)  //int型的自增主键
    @ColumnInfo(name = "id")          //表中字段的名字,不填则使用成员变量名
    private int mId;

    @Ignore                           //Ignore注解表示不进行数据库映射,只存在于内存中
    private boolean mSelected;
}

使用@Dao声明数据访问对象,即表的操作,

代码语言:javascript
复制
@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)  //新增数据,发生冲突则替换
    void insertUsers(User... users);

    @Update(onConflict = OnConflictStrategy.REPLACE)  //更新数据,发生冲突则替换
    int updateUsers(User... users);

    @Delete
    void deleteUsers(User... users);  //删除数据

    @Query("SELECT * FROM t_user")    //查询数据
    List<User> queryUsers();
}

定义完表,还需要用@Database定义数据库,

代码语言:javascript
复制
//entities表示这个数据库都有哪些表,version表示数据库版本,用于数据库升级
@Database(entities = {User.class}, version = 1)
abstract class AppDatabase extends RoomDatabase {
    //提供dao对象给业务层使用
    public abstract UserDao userDao();
}

来到activity,进行使用

代码语言:javascript
复制
RoomActivity extends AppCompatActivity {
    void onCreate(Bundle savedInstanceState) {
        //创建数据库对象
        mAppDatabase = Room.databaseBuilder(this, AppDatabase.class, AppDatabase.DB_NAME)
                .allowMainThreadQueries()  //允许主线程操作数据库,不推荐
                .build();
        //获取dao对象
  mUserDao = mAppDatabase.userDao();
        //操作数据库
        mUserDao.insertUsers(user);
    }
}

原理

首先看看数据库的创建,进入AppDatabase类,点击查看他的实现类AppDatabase_Impl

代码语言:javascript
复制
//AppDatabase_Impl.java
SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
    SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate(1) {
        void createAllTables(SupportSQLiteDatabase _db) {
            //创建表
            _db.execSQL("CREATE TABLE IF NOT EXISTS `t_user` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT)");
        }
    };
}

@Override
public UserDao userDao() {
    if (_userDao != null) {
      return _userDao;
    } else {
      synchronized(this) {
        if(_userDao == null) {
          //创建dao对象
          _userDao = new UserDao_Impl(this);
        }
        return _userDao;
      }
    }
}

来到UserDao_Impl

代码语言:javascript
复制
//UserDao_Impl.java
UserDao_Impl(RoomDatabase __db) {
    this.__insertionAdapterOfUser = new EntityInsertionAdapter<User>(__db) {
        @Override
        public String createQuery() {
            //创建sql语句
            return "INSERT OR REPLACE INTO `t_user` (`id`,`name`) VALUES (nullif(?, 0),?)";
        }

        @Override
        public void bind(SupportSQLiteStatement stmt, User value) {
            //将参数绑定到sql语句的指定位置
            stmt.bindLong(1, value.getId());
            if (value.getName() == null) {
                stmt.bindNull(2);
            } else {
                stmt.bindString(2, value.getName());
            }
        }
    };
}

@Override
public void insertUsers(final User... users) {
    __insertionAdapterOfUser.insert(users);
}

insert会来到EntityInsertionAdapter

代码语言:javascript
复制
//EntityInsertionAdapter.java
void insert(T[] entities) {
    final SupportSQLiteStatement stmt = acquire();
    try {
        for (T entity : entities) {
            //根据前边实现的bind方法,绑定参数
            bind(stmt, entity);
            //执行stmt完成数据库操作
            stmt.executeInsert();
        }
    } finally {
        release(stmt);
    }
}

//省略调用链:acquire - getStmt - createNewStatement
SupportSQLiteStatement createNewStatement() {
    //获取前边创建的sql语句
    String query = createQuery();
    //最终去到SQLiteDatabase.compileStatement()里创建SQLiteStatement
    return mDatabase.compileStatement(query);
}

优缺点

  • 优点:
    • 使用简单,能友好的支持Paging(后续介绍)
  • 缺点:
    • 生成的类会增大包体积,当然值不值得就得看ROI了。

性能方面的问题暂不做分析。

参考文章

  • 简书-Android Room 框架学习
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 哈利迪ei 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用
  • 原理
  • 优缺点
  • 参考文章
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档