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

网站建设加入购买按钮英国公司注册

网站建设加入购买按钮,英国公司注册,做漫画的网站有哪些,qq免费建网站如何小步安全地升级数据库框架 Hi#xff0c;我是阿昌#xff0c;今天学习记录的是关于如何小步安全地升级数据库框架的内容。 当消息组件的数据存储都是采用 SQL 拼写的方式来操作#xff0c;这样不便于后续的扩展及维护。除此之外#xff0c;相比前面的其他重构#x…如何小步安全地升级数据库框架 Hi我是阿昌今天学习记录的是关于如何小步安全地升级数据库框架的内容。 当消息组件的数据存储都是采用 SQL 拼写的方式来操作这样不便于后续的扩展及维护。除此之外相比前面的其他重构升级数据框架需要考虑的场景会更多例如升级框架以后用户的重要数据不能丢失。 以 Sharing 项目为例把项目中原先采用 SQL 拼写的方式替换为使用 Room 框架来统一管理缓存数据。在这个过程中你分享如何小步安全重构分阶段完成数据库框架的升级。为了确保重构完的代码不会破坏原有功能还有用户的关键数据不丢失并如何给数据操作相关功能做自动化测试覆盖以及如何实现更安全的数据迁移。 一、代码分析 消息组件中创建数据库表的相关操作核心代码是后面这样。 //数据库表的创建 class DataBaseHelper(context: Context?) : SQLiteOpenHelper(context, message.db, null, 1) {override fun onCreate(db: SQLiteDatabase) {createTable(db)}override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}fun createTable(db: SQLiteDatabase) {val createTableSql CREATE TABLE IF NOT EXISTS $message_info($id INTEGER PRIMARY KEY AUTOINCREMENT,$content VARCHAR(1024) ,$fileName VARCHAR(1024) ,$date LONG )try {db.execSQL(createTableSql)} catch (e: Exception) {Log.d(Task:Sql, e.message!!)}}companion object {var message_info message_infovar id idvar content contentvar fileName fileNamevar date date} }上述核心代码可以看出 Sharing 项目主要通过 SQLite 提供的 SQLiteDatabase 以及 SQLiteOpenHelper 来创建数据表。 目前 Sharing 项目仅有一个表以及简单的几个字段通过 SQL 拼写的方式看起来也还好维护但是如果现在面临的是几十个表以及几百个字段那么管理和维护这些拼写的 SQL 字符串就会非常困难当有修改的时候也非常容易出错。 来看数据的缓存以及读取操作。 //进行信息缓存以及读取的代码 class LocalDataSource constructor( private var mContext: Context) : IDataSource {override fun getMessageListFromCache(): MutableListMessage {val messageList: MutableListMessage ArrayList()val dataBaseHelper DataBaseHelper(mContext)val c dataBaseHelper.writableDatabase.query(DataBaseHelper.Companion.message_info, null,null, null, null, null,null)if (c.moveToFirst()) { for (i in 0 until c.count) {c.move(i) //移动到指定记录val id c.getInt(c.getColumnIndex(DataBaseHelper.Companion.id))val content c.getString(c.getColumnIndex(DataBaseHelper.Companion.content))val fileName c.getString(c.getColumnIndex(DataBaseHelper.Companion.fileName))val date c.getLong(c.getColumnIndex(DataBaseHelper.Companion.date))messageList.add(Message(id, content, fileName, date))}}return messageList}override fun saveMessageToCache(messageList: ListMessage) {val dataBaseHelper DataBaseHelper(mContext)if (messageList.isNotEmpty()) {dataBaseHelper.writableDatabase.delete(DataBaseHelper.Companion.message_info, null,null)for (message in messageList) {val cv ContentValues()cv.put(DataBaseHelper.Companion.id, message.id)cv.put(DataBaseHelper.Companion.content, message.content)cv.put(DataBaseHelper.Companion.date, message.date)cv.put(DataBaseHelper.Companion.fileName, message.fileName)dataBaseHelper.writableDatabase.insert(DataBaseHelper.Companion.message_info,null,cv)}}} }通过上述代码可以看到减少虽然 SQLite 提供了 query 以及 delete 等操作方法可以减少编写 SQL 字符串但是仍然需要去编写大量的对象转换代码。其实这些代码都是前面提到的非业务的模板代码这会大大增加我们维护代码的成本。 为了解决这些问题官方也提供了新的数据库框架 Room。官方文档强烈建议使用 Room而不是直接使用 SQLite API。 二、补充自动化守护测试 首先第一步还是需要先做基本的自动化测试覆盖作为后续重构的安全守护网。 这里主要针对 LocalDataSource 类来做测试保证基本的数据缓存以及读取功能是正确的。用例设计是这样的。 测试用例 1当 message 数据表没有缓存数据时获取的缓存数据为空。测试用例 2当 message 数据表中有缓存数据时能够成功获取缓存数据。读取的缓存数据内容需要与保持的缓存数据内容一致。 现在需要将测试用例转换成自动化测试用例。 class LocalDataSourceTest {//用例1Testfun should get message list is empty when database has not data() runBlocking {//givenval localDataSource LocalDataSource(ApplicationProvider.getApplicationContext())//whenval messageListFromCache localDataSource.getMessageListFromCache()//thenassert(messageListFromCache.isEmpty())}//用例2Testfun should get message list success when database has data() runBlocking {//givenval localDataSource LocalDataSource(ApplicationProvider.getApplicationContext())localDataSource.saveMessageToCache(getMockData())//whenval messageListFromCache localDataSource.getMessageListFromCache()//thenval messageOne messageListFromCache[0]Truth.assertThat(messageOne.id).isEqualTo(1)Truth.assertThat(messageOne.content).isEqualTo(张三共享文件到消息中...)Truth.assertThat(messageOne.fileName).isEqualTo(大型Android遗留系统重构.pdf)Truth.assertThat(messageOne.formatDate).isEqualTo(2021-03-17 14:47:55)val messageTwo messageListFromCache[1]Truth.assertThat(messageTwo.id).isEqualTo(2)Truth.assertThat(messageTwo.content).isEqualTo(李四共享视频到消息中……)Truth.assertThat(messageTwo.fileName).isEqualTo(修改代码的艺术.pdf)Truth.assertThat(messageTwo.formatDate).isEqualTo(2021-03-17 14:48:08)} }后面是执行测试用例的结果。 三、小步安全重构 在过程中每当完成一步重构后都可以频繁运行测试来验证是否有破坏原有的逻辑。 拆分重构过程的要求是每一小步的重构都不能破坏之前的功能而且全部步骤都完成之后即可完成整体的重构。这里我们结合 Room 框架的设计把整个重构分成下面这 5 个步骤。 第一步是使用 Room 注解更新实体。第二步是使用 Room 的 SupportSQLiteOpenHelper 进行 SQL 操作。这 2 个步骤完成后不会修改原有的查询及删除操作代码。第三步进阶使用 Room 的 Dao 注解方式来管理数据的增删改查替换掉原有的查询及删除代码。第四步是优化操作使用协程来优化 IO 的异步操作。最后是第五步迁移旧数据。 1、使用 Room 注解更新实体 来看第一步这一步相对比较简单使用 Room 的注解标记新的实体代码就可以了。 Entity(tableName message_info) class Message(PrimaryKey ColumnInfo(name id) var id: Int,ColumnInfo(name content) var content: String,ColumnInfo(name fileName) var fileName: String,ColumnInfo(name date) var date: Long ) {Ignoreval formatDate DateUtil.getDateToString(date)Ignoreval downloadCount ARouter.getInstance().navigation(IFileStatistics::class.java)?.getDownloadCount(id.toString()) }2、使用 Room 的 SupportSQLiteOpenHelper 进行 SQL 操作 Room 提供了 SupportSQLiteOpenHelper 类可以用它替换 SQLite 中的 SQLiteOpenHelper将原本使用 SQLiteOpenHelper 的地方替换为使用 Room 的 SupportSQLiteOpenHelper。 Database(entities [Message::class], version 1) abstract class AppDatabase : RoomDatabase() { }class LocalDataSource constructor(private var mContext: Context ) : IDataSource {val db Room.databaseBuilder(mContext,AppDatabase::class.java, message.db).build()override fun getMessageListFromCache(): MutableListMessage {val messageList: MutableListMessage ArrayList()val dataBaseHelper db.openHelper//... ...return messageList}override fun saveMessageToCache(messageList: ListMessage) {val dataBaseHelper db.openHelper//... ...} }3、使用 Dao 注解方式来管理数据的增删改查 选择将 query 及 delete 等的操作使用 Room 的 Dao 注解做替换。 Dao interface MessageDao {Query(SELECT * FROM message_info)suspend fun getAll(): ListMessageInsertsuspend fun insertAll(vararg message: Message)Query(DELETE FROM message_info)suspend fun deleteAll() }完成后就可以将 LocalDataSource 的实现替换为使用 MessageDao 进行操作了。 class LocalDataSource constructor(private var mContext: Context ) : IDataSource {val db Room.databaseBuilder(mContext,AppDatabase::class.java, message.db).build()override suspend fun getMessageListFromCache(): MutableListMessage {return db.messageDao().getAll().toMutableList()}override suspend fun saveMessageToCache(messageList: ListMessage) {messageList.let {db.messageDao().deleteAll()db.messageDao().insertAll(*it.toTypedArray())}} }至此完成了 Room 框架的升级可以对比一下 LocalDataSource 改造前后的代码使用 Room 框架大大帮我们减少了模板代码的编写代码更加容易维护。 4、数据迁移 如果升级数据库框架时调整过表结构的话这时就可以用 Room 提供的 Migration 机制升级数据。 例如 Sharing 项目在升级 Room 框架时新增了一个 count 字段用于缓存文件的下载数量但是在旧的数据表中并没有这个字段这时就可以使用 Migration 机制来迁移升级数据。 private val MIGRATION_1_2 object : Migration(1, 2) {override fun migrate(database: SupportSQLiteDatabase) {database.execSQL(ALTER TABLE message_info RENAME TO message_info_back_up)database.execSQL(CREATE TABLE message_info ( id INTEGER PRIMARY KEY NOT NULL, content TEXT NOT NULL,date INTEGER NOT NULL, count INTEGER NOT NUL))database.execSQL(INSERT INTO message_info (id, content,date0) SELECT id, content,date FROM message_info_back_up)} } private val db Room.databaseBuilder(mContext,AppDatabase::class.java, message.db ).addMigrations(MIGRATION_1_2).build()在实际的项目中需要根据数据对用户的重要性来决定是否要做数据的迁移。 例如一些缓存数据只是提高用户的体验哪怕这部分数据没有了从网络获取它也很方便就不必迁移数据。但如果对用户来说是关键的数据就必须迁移和做专项的测试。 例如一个短信息的 APP信息只缓存在本地当升级框架后迁移这些短信息就非常重要因为这部分数据丢失的话对用户来说是非常糟糕的体验。 更多迁移数据的方法可以参考官网的说明。 四、集成验收 跟之前的组件内分层架构重构一样完成重构后我们需要完成最后的集成验收。 验收有三个标准 第一是编译通过能够打包出安装包第二是架构守护用例执行通过第三是验收自动化测试执行通过。 改造后相关的自动化测试运行结果。 基本冒烟及架构守护用例自动化测试报告如下 消息组件自动化测试报告如下 至此我们完成了对 Sharing 项目的数据库框架升级重构。 五、总结 改造前 Sharing 项目使用了 SQLite 来管理数据库这个方式主要存在 2 个问题。 第一个是使用拼写 SQL 方式来管理表创建不便于扩展第二个是存在大量的对象转换重复代码不便于维护。 根据官方的建议使用 Room 框架来帮我们完成这些重复的工作让可以更聚焦在业务开发上。 Room 框架的升级可以分 2 个阶段完成。 第一个阶段是先引入 Room 框架将原本使用 SQLiteOpenHelper 操作数据库的方式调整为使用 Room 提供的 SupportSQLiteOpenHelper 来进行管理此时不会修改原有的查询及删除操作代码。第二个阶段可以使用 Room 提供的 Dao 注解方式替换掉原来的 insert、query 等方法完成后可以减少大量的增删改查模板代码。此时就可以充分感受到使用框架带来的收益。同样完成一个功能可以少写很多模板的代码。 特别需要注意的是如果在改造过程中如果数据表结构有变化需要采用 Room 框架提供的 Migration 机制来迁移数据。
http://www.dnsts.com.cn/news/103614.html

相关文章:

  • 网站开发制作流程如何在凡科建设网站
  • 震泽做网站企业免费网站建设模板下载
  • 网站开发发展趋势2018自贡建设网站
  • 如何查询网站的空间商潍坊淘宝网站建设
  • 谁需要做网站的嘉兴做高仿包的能做网站吗
  • 哪个网站可以做付邮免费送活动如何建设微商网站
  • 个人建网站步骤个人可以备案网站
  • 自行建网站 所需费用有网站源码去哪里做
  • 开淘宝店要自己做网站吗揭阳新闻最新消息
  • 河北建设厅身份认证锁登录网站seo网站推广是什么
  • 蚁百杭州网站seo优化wordpress调用时间
  • 网站建设是什么科目重庆工程建设信息网安全监督
  • 网站正在建设中php网站关键词重复
  • 百度推广网站谁做西安建站模板厂家
  • 北京哪家公司做网站专业有哪些
  • 小程序建站工具提供搜索引擎优化公司
  • 免费网站入口在哪电商网站开发 知乎
  • 一个二手书网站的建设目标wordpress 格子广告
  • 做海报免费素材网站有哪些c 网站开发 书
  • 网站后台html页面wordpress上传图片教程
  • 泉州建站模板搭建网站开发 语言
  • 大型电子商务网站建设成本留学网站 模板
  • 自由策划网站建设it学校培训机构
  • 物流企业网站wordpress社交分享
  • mip 网站公司注销需要多少钱费用?
  • 安徽省住房和城乡建设厅网站6应用软件免费下载
  • 做纸棋的网站衡阳县住房和城乡建设局网站
  • c2c网站网址专注网站建站
  • 自己做的网站如何用手机去查看wordpress sql语句
  • 网站建设难不难app网站开发成功案例