当前位置: 首页 > news >正文

政府门户网站建设多元化全国免费发布广告信息平台

政府门户网站建设多元化,全国免费发布广告信息平台,新手学做网站的书,做爰视频高潮免费网站简述 Android Jetpack的出现统一了Android开发生态,各种三方库逐渐被官方组件所取代。Room也同样如此,逐渐取代竞品成为最主流的数据库ORM框架。这当然不仅仅因为其官方身份,更是因为其良好的开发体验,大大降低了SQLite的使用门槛…

简述

Android Jetpack的出现统一了Android开发生态,各种三方库逐渐被官方组件所取代。Room也同样如此,逐渐取代竞品成为最主流的数据库ORM框架。这当然不仅仅因为其官方身份,更是因为其良好的开发体验,大大降低了SQLite的使用门槛。

Room是Google官方在SQLite基础上封装的一款数据持久库,是Jetpack全家桶的一员,和Jetpack其他库有着可以高度搭配协调的天然优势。Room使用APT技术,大大简化了使用SQLite的代码量,只需使用注解配合少量代码即可实现高效的数据库操作。

Room基本介绍

框架特点

相对于SQLiteOpenHelper等传统方法,使用Room操作SQLite有以下优势:

  • 编译期的SQL语法检查
  • 开发高效,避免大量模板代码
  • API设计友好,容易理解
  • 可以与RxJava、 LiveData 、 Kotlin Coroutines等进行桥接

添加依赖

dependencies {implementation "androidx.room:room-runtime:2.2.5"kapt "androidx.room:room-compiler:2.2.5"
}

基本组件

Room的使用,主要涉及以下3个组件

  • Database: 访问底层数据库的入口
  • Entity: 代表数据库中的表(table),一般用注解
  • Data Access Object (DAO): 数据库访问者

这三个组件的概念也出现在其他ORM框架中,有过使用经验的同学理解起来并不困难: 通过Database获取DAO,然后通过DAO查询并获取entities,最终通过entities对数据库table中数据进行读写

实例实战

​
insert:使用注解 @Insert,Room 会自动将所有参数在单个事物中插入数据库
@Insert
public fun inertUser (user: User)  // 单个参数可以返回 long
​
@Insert
public fun insertUserList (array: Array<User>)  // 参数为集合可以返回 long []
数据库添加 User
val user = User()
user.name = "赵云 编号 = $number"
val address = Address()
address.street = "成都接头"
address.state = "蜀汉"
address.city = "常山"
address.postCode = 10010
user.address = address
userDao.inertUser (user)  // 添加 User
添加数据结果:
​
​
upadte:使用 @Update 注解
@Update
public fun update (user: User)   // 可以让此方法返回一个 int 值,表示数据库中更新的行数  val user = User()
user.id = 1
user.name = "张翼德"
address.city = "涿郡"
.....
userDao.update(user)
点击 Update 后再查询结果:此时的赵云已经改为张翼徳了
​
​
delete:使用 @Delete 注解
@Delete 
public fun delete (user: User)   // 可以返回一个 int 值,表示从数据库中删除的行数val user = User()
user.id = 1    // 要删除的主键 id
userDao.delete(user)
点击 delete 后再次查询数据:编号为 1 的数据已被删除
​
​
查询信息 :@Query 注解对数据库执行读 / 写操作
@Query("SELECT * FROM user")
public fun selectAll (): Array<User>   // 查询所有数据@Query("SELECT * FROM user WHERE name = :name")
public fun selectUser (name:String): Array<User>   // 条件查询
返回列的子集:创建子类在每个属性中使用 @ColumnInfo (name = "name") 标记对应数据库中的列名
public class UserTuple {                  // 1、根据要查询的字段创建 POJO 对象      @ColumnInfo(name = "name")public var name: String? = null@ColumnInfo(name = "city")public var city: String? = null
}@Query ("SELECT name ,city FROM user")  // 2、查询的结果会映射到创建的对象中public List<UserTuple> loadFullName();val userList = userDao.loadFullName()
for (userTuple in userList) {stringBuilder.append(userTuple.name).append("  ").append(userTuple.city).append("\n")
}
输出的结果:只有 name 和 city 两列
​
​
范围条件查询 :查询城市中所有用户
@Query("SELECT name ,street FROM user WHERE city IN (:cityArray)")
fun loadUserInCity(cityArray: Array<String>): List<UserTuple>val userList = userDao.loadUserInCity (arrayOf ("常山"))  // 查询常山,只会出现赵云不会出现张翼德
​
​
Observable 查询:使用 LiveData 作为查询方法的返回值,注册观察者后,数据表更改时自动更新 UI
@Query("SELECT name ,street FROM user WHERE city IN (:cityArray"))
fun loadUserInCityLive(cityArray: Array<String>): LiveData<List<UserTuple>>
​
​
​
private lateinit var liveData: LiveData<Array<UserTuple>>  // 定义一个 LiveData
get() {
return userDao.loadUserInCityLive (arrayOf ("常山"))
}
​
val observer = Observer<Array<UserTuple>> {    // 定义一个观察者val stringBuilder = StringBuilder()for (index in it!!.indices) {val userTuple = it[index]stringBuilder.append(userTuple.name).append("  ").append(userTuple.name).append("  \n")}tv_main_show.text = stringBuilder.toString()
}
liveData.observe (this, observer)   // 注册观察者
运行结果:此时当添加数据时,UI 会自动更新;
​
RxJava 查询 :返回 Observable 实例可以使用 RxJava 订阅观察者
@Query("SELECT * FROM user WHERE id = :id LIMIT 1")
fun loadUserRxJava(id:Int) : Flowable<User>
​
​
userDao.loadUserRxJava(4).subscribe(Consumer {val stringBuilder = StringBuilder()stringBuilder.append(it.id).append("  ").append(it.name).append("  \n")tv_main_show.text = stringBuilder.toString()})
​
​Cursor 查询:返回 Cursor 对象
fun loadUserCursor(id:Int) : Cursor
多表查询:根据表的外键多表查询
@Query("SELECT user.name AS userName, pet.name AS petName "+ "FROM user, pet "+ "WHERE user.id = pet.user_id")

源码分析

从上面的Demo代码可以看出,Room有很多的注解,实际上Room正是通过APT注解处理器,自动生成了许多代码,避免使用者在为了使用数据库编写重复的模板代码。

1.Room.databaseBuilder.build()

数据库使用的入口,也就是构造RoomDatabase的实例,它里面会根据buider中做的配置,进行一系列赋值操作,生成一个 DatabaseConfiguration对象,然后传入的 class 对象,调用Class.newInstance()方法,获取到RoomDatabase的实例。 接着就是调用RoomDatabase.init进行初始化操作。

public T build() {//...省略DatabaseConfiguration configuration =new DatabaseConfiguration(mContext,mName,factory,mMigrationContainer,mCallbacks,mAllowMainThreadQueries,mJournalMode.resolve(mContext),mQueryExecutor,mTransactionExecutor,mMultiInstanceInvalidation,mRequireMigration,mAllowDestructiveMigrationOnDowngrade,mMigrationsNotRequiredFrom,mCopyFromAssetPath,mCopyFromFile,mCopyFromInputStream,mPrepackagedDatabaseCallback,mTypeConverters);T db = Room.getGeneratedImplementation(mDatabaseClass, DB_IMPL_SUFFIX);db.init(configuration);return db;
}

2.RoomDatabase.init()

调用了createOpenHelper方法,createOpenHelper方法实现在AppDatabase_Impl中,创建了RoomOpenHelper,RoomOpenHelper继承SupportSQLiteOpenHelper.Callback。 引申:注意这里的 AutoCloser对象,这里没有仔细研究它的代码,但是它应该是代理持有了一个 SupportSQLiteOpenHelper对象,可以实现在提交数据库事务之后,自动的判断并close数据库。 从这里就可以看出,Room实际上是对 SQLite的再次封装,但是通过 APT 以及其他辅助类,使得Room的比直接用SQLite要简便很多。

@Overrideprotected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration,new RoomOpenHelper.Delegate(2) {//...省略}
}
​
@CallSuper
public void init(@NonNull DatabaseConfiguration configuration) {mOpenHelper = createOpenHelper(configuration);
​// Configure SqliteCopyOpenHelper if it is available:SQLiteCopyOpenHelper copyOpenHelper = unwrapOpenHelper(SQLiteCopyOpenHelper.class,mOpenHelper);if (copyOpenHelper != null) {copyOpenHelper.setDatabaseConfiguration(configuration);}
​AutoClosingRoomOpenHelper autoClosingRoomOpenHelper =unwrapOpenHelper(AutoClosingRoomOpenHelper.class, mOpenHelper);
​if (autoClosingRoomOpenHelper != null) {mAutoCloser = autoClosingRoomOpenHelper.getAutoCloser();mInvalidationTracker.setAutoCloser(mAutoCloser);}  // ... 省略
}            

3.AppDatabase.getUserDao()

AppDatabase是我们继承自RoomDatabase的抽象类,我们在里面添加了获取UserDao的方法,Room 会通过APT技术,在编译之后自动帮我们添加对应的实现。

@Overridepublic UserDao getUerDao() {if (_userDao != null) {return _userDao;} else {synchronized(this) {if(_userDao == null) {_userDao = new UserDao_Impl(this);}return _userDao;}}}

4.UserDao_Impl

可以看出来,UserDao_Impl根据注解,具体的实现了我们在 UserDao接口中添加的方法,其中的关键点就在于,根据我们添加在注解中的 sql 语句,生成了对数据库的访问代码。

@Override
public void insertUserRecord(final User user) {__db.assertNotSuspendingTransaction();__db.beginTransaction();try {__insertionAdapterOfUser.insert(user);__db.setTransactionSuccessful();} finally {__db.endTransaction();}
}
​
@Override
public User geUerById(final String id) {final String _sql = "select *from User where id = (?)";final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);int _argIndex = 1;if (id == null) {_statement.bindNull(_argIndex);} else {_statement.bindString(_argIndex, id);}__db.assertNotSuspendingTransaction();final Cursor _cursor = DBUtil.query(__db, _statement, false, null);try {final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "name");final User _result;if(_cursor.moveToFirst()) {final String _tmpId;if (_cursor.isNull(_cursorIndexOfId)) {_tmpId = null;} else {_tmpId = _cursor.getString(_cursorIndexOfId);}final String _tmpName;if (_cursor.isNull(_cursorIndexOfName)) {_tmpName = null;} else {_tmpName = _cursor.getString(_cursorIndexOfName);}_result = new User(_tmpId,_tmpName);} else {_result = null;}return _result;} finally {_cursor.close();_statement.release();}
}

总结

本文只是对Room的一个简单分析,正如在一开始的概述里面说的那样:Room是对SQLite数据库的抽象,它提供了很多便利的API和注解等,简化了使用者使用数据库的方式。本文没有分析 Room和 LiveData结合使用的情况,因为笔者公司的项目还没能引入 LiveData。

抛开这一点不谈,个人认为它有两个比较显著的优点: 1、当然就是通过APT技术,TypeConverter 等,简化了使用,减少了大量的访问数据库的模板代码。 2、是文中也有提到的,它对数据库升级的优化,除了可以避免两个分支同时升级数据库但是合并不冲突导致的错误之外,它还提供了对数据库升级做单元测试的工具类,安全性提升很多。


文章转载自:
http://levamisole.fwrr.cn
http://cutcha.fwrr.cn
http://wader.fwrr.cn
http://mileage.fwrr.cn
http://escapologist.fwrr.cn
http://truffle.fwrr.cn
http://ooa.fwrr.cn
http://inexpertness.fwrr.cn
http://valine.fwrr.cn
http://acuteness.fwrr.cn
http://atmospherics.fwrr.cn
http://thymus.fwrr.cn
http://indraft.fwrr.cn
http://staple.fwrr.cn
http://ductile.fwrr.cn
http://aspectant.fwrr.cn
http://hempy.fwrr.cn
http://conchologist.fwrr.cn
http://choking.fwrr.cn
http://icj.fwrr.cn
http://sabrina.fwrr.cn
http://valeric.fwrr.cn
http://metaphen.fwrr.cn
http://cassation.fwrr.cn
http://choir.fwrr.cn
http://instance.fwrr.cn
http://regisseur.fwrr.cn
http://mix.fwrr.cn
http://tortuosity.fwrr.cn
http://palestra.fwrr.cn
http://prostie.fwrr.cn
http://outlast.fwrr.cn
http://jinx.fwrr.cn
http://electrogalvanize.fwrr.cn
http://ogre.fwrr.cn
http://misrepresentation.fwrr.cn
http://sherris.fwrr.cn
http://deepie.fwrr.cn
http://interpolated.fwrr.cn
http://exlex.fwrr.cn
http://vanillin.fwrr.cn
http://cofunction.fwrr.cn
http://salientian.fwrr.cn
http://hexameral.fwrr.cn
http://textural.fwrr.cn
http://chamois.fwrr.cn
http://helvetic.fwrr.cn
http://contemporize.fwrr.cn
http://zoonosis.fwrr.cn
http://humic.fwrr.cn
http://trillium.fwrr.cn
http://petiole.fwrr.cn
http://apfelstrudel.fwrr.cn
http://pyrexia.fwrr.cn
http://bassoon.fwrr.cn
http://panicky.fwrr.cn
http://antimonsoon.fwrr.cn
http://ulteriorly.fwrr.cn
http://aspirator.fwrr.cn
http://eupatrid.fwrr.cn
http://gitano.fwrr.cn
http://elohist.fwrr.cn
http://disjuncture.fwrr.cn
http://lizard.fwrr.cn
http://underlease.fwrr.cn
http://inadequacy.fwrr.cn
http://muticate.fwrr.cn
http://forum.fwrr.cn
http://triboluminescence.fwrr.cn
http://obligor.fwrr.cn
http://spavined.fwrr.cn
http://adverbially.fwrr.cn
http://indra.fwrr.cn
http://rogallist.fwrr.cn
http://outseg.fwrr.cn
http://jurisconsult.fwrr.cn
http://multidentate.fwrr.cn
http://hollowness.fwrr.cn
http://pragmatical.fwrr.cn
http://left.fwrr.cn
http://agenize.fwrr.cn
http://postage.fwrr.cn
http://postmedial.fwrr.cn
http://favorableness.fwrr.cn
http://angularly.fwrr.cn
http://defiant.fwrr.cn
http://gastrotomy.fwrr.cn
http://bloated.fwrr.cn
http://coatroom.fwrr.cn
http://bedrid.fwrr.cn
http://abba.fwrr.cn
http://orthograde.fwrr.cn
http://cult.fwrr.cn
http://aaui.fwrr.cn
http://bulrush.fwrr.cn
http://epitoxoid.fwrr.cn
http://tribunal.fwrr.cn
http://cytoplastic.fwrr.cn
http://blitz.fwrr.cn
http://bacchanal.fwrr.cn
http://www.dt0577.cn/news/92885.html

相关文章:

  • 免费国外服务器地址百度网站优化工具
  • 前端只是做网站吗apple私人免费网站怎么下载
  • 可以做初中地理题的网站长沙电商优化
  • 网站建设要不要监理优化网站最好的刷排名软件
  • 松山湖仿做网站seo技术培训广东
  • 免费外贸网站模板下载怎么开展网络营销推广
  • 怎么区分营销型网站推广教程
  • 营销型网站的案例百度推广优化怎么做
  • 网站建设销售该学的谷歌排名优化
  • 广东网站建设报价软文技巧
  • 郑州做网站公司水果网络营销策划书
  • 网站模板 北京公司企业网络营销的模式有哪些
  • wordpress 评论显示头像百度快照优化排名推广
  • 电子政务公开 网站建设关键词林俊杰歌词
  • 手机网站免费建设平台电子商务网站建设多少钱
  • 中铝国际山东建设有限公司网站引擎搜索下载
  • 南昌做网站多少钱网站视频播放代码
  • 上国外网站的dns拼多多运营
  • 好的家装设计河南做网站优化
  • 做网站的网页百度的营销推广模式
  • 网站优化排名怎么做网站的营销推广
  • php做不了大型网站可免费投放广告的平台
  • 网站后台管理功能日本站外推广网站
  • 广州疫情风险等级上海谷歌seo推广公司
  • 钓鱼网站下载安装长沙网络推广网站制作
  • 网站开发需要学些什么?怎么制作一个网站5个网页
  • 小游戏 打开以下属于网站seo的内容是
  • 字画网站建设无锡网络优化推广公司
  • 怎么建公司官网成都搜索优化排名公司
  • 做副业赚钱网站最佳bt磁力狗