当前位置:网站首页 > Java教程 > 正文

iboxdb教程 java



  之前用的 sqlite3 作为本地数据库, 可是它不能作为内存数据库, 是基于文件的, 在某些情况下没有读写权限就直接挂壁了, 比如 WebGL 中会报错 dlopen(), 然后给了一个链接, 看过去太复杂了没有懂, 或者安卓里面 StreamingAssets 是压缩包文件, 也是没法直接使用的......

  而且 sqlite3 用起来很麻烦, dll 需要同时引用 Mono.Data 和 System.Data, 在Unity2017中需要手动扔一个 System.Data 进去, 要不然缺失引用, 而在 Unity2019中又不能扔进去, 会编译冲突......

  然后找到这个, 很简单一个dll完事 :

  

  它的读取可以通过 path, byte[], Stream 等来实现, 能够实现很多种需求了.

  不过有点奇葩的是它的文件命名方式, 比如我想要创建一个 abc.db 文件, 这是不行的, 只能传给它数字, 然后它自己生成 db{N}.box 这样的 db 文件, 或者传给它一个文件夹路径, 它会自动生成文件夹下 db1.box 文件, 实在够奇怪的, 不过生成出来的文件, 可以通过改名, 然后读取 bytes 的方式读取......

  反正是很神奇的脑回路, 我搞了半天才明白什么回事, 它也没有文档, 导致后面出现了一系列事故.

  先来说说怎样生成数据库, 比如从 Excel 或是啥来源的数据, 要把它生成数据库的流程很简单, 就是先获取 Table 的 Key, 然后每行作为对应的数据录入数据库就行了, 可是插入数据在 iboxDB 里面是个很奇葩的操作 :

  AutoBox 是数据操作的入口, 它的插入只有泛型的 Insert<V> 来实现, 它的 API 设计是基于已存在的类型的, 比如一个数据库你要保存一个类 :

  对于已经存在的类型, 它就很简单 :

  可是对于一个刚从 Excel 来的数据, 我们是没有类型的, 那么怎样才能创建一个类型给它?

  这时候只能使用 Emit 了, 没有类型就创建类型, 然后它没有非泛型方法, 创建类型之后还需要从 Type 获取泛型 Insert<V> 方法, 非常麻烦 :

  通过创建类型, 传入 { "Id", "Name", "age" }可以创建出一个跟 Record 一样的拥有这些变量的类型, 然后需要根据它获取 AutoBox 实例的 Insert<V> 泛型方法 :

  这两个大招还是之前测试 Lua 泛型的时候搞的, 没想到会用到这里来, 然后就是依靠

  来创建实例保存数据了, 它的设计基于简单易用, 可是在这里就变得很复杂, 好在有 Emit 大法......

  然后就能走通流程了, 读取数据, 转换数据, 保存数据到数据库 :

  

  PS : 意外发现它的 Key 可以支持中文, C# 变量也支持中文, 这样中文就不用转换了

  PS : 突然想到从数据库中获取数据的时候, 其实类型是可以任意的, 比如

  那么泛型获取其实就跟写了一个过滤逻辑一样只获取对应的数据 :

  如果使用元组来写的话, 是不是会简单一点? 不用另外定义了, 不过坑的就是它的 API对类型做了限定 :

  元组不能通过 class 限定, 来测试一下 :

  这是可行的 :

  然而当限定了 class 之后是不行的 :

  好吧, 元组就是个结构体......

  不过这都不是问题, 通过我反射大师的计算, 还是可以通过上面的运行时创建类型来实现的, 首先看看最终效果 :

  

  结果是能够使用元组来替代指定类型的, 使用起来会非常方便. 代码也是沿用了创建运行时类型的方法, 不过这使用到了 Emit, 在必须进行 IL2CPP 的平台是无法编译的......比如各种主机平台.

  中间的转换获取代码 :

  在这里发现匿名元组还是跟老版本一样很不好用, 就算在外部定义好了变量 : <(string name, string x, string z)> 这些变量 name, x, z 也是无法通过反射获取到的, 它的 field 仍然是 Item1, Item2, Item3... 所以才会需要手动传入 keys 来告诉反射给新的类创建哪些变量......非常多此一举. 并且因为没有名称的一一对应, 所以元组的变量顺序必须跟 keys 传入的顺序一致才行......

  如果可以省略

  这一段就完美了.

  补充个元组小知识, 如果是硬编译的元组, 是可以在运行时获取元组的变量的, 比如下面这样 :

  它是在编译时自动给函数添加了一个属性 [TupleElementNames] , 在运行时可以获取到, 至于上面的泛型怎样才能获取到我就不知道了, 因为泛型限定元组好像不存在.

(2021.03.05)

  回头看了一下, 硬编译的元组这里, 获取方法的方式也可以通过表达式树大法来获取, 看起来更优雅一些 :

-----------------

(2021.03.25)

  之前一直没有把数据库替换成 iboxDB, 是因为使用 sqlite3 的时候获取的数据是 string 类型的, 然后直接转换成了我的 DataTable 类型 :

  这样数据的类型转换就省去了, 非常方便. 可是 iboxDB 的反序列化对象是强类型的, 不能直接转换为 DataTable, 不像 LitJson 或者 Xml 这样提供了自定义转换, 所以需要进行二次转换 :

  过程就成了 [iboxDB] -> Data_iboxDB -> Data, 然后就没有去继续测试了, 然而今天进行了测试, 发现效率上天差地别, 至少在全表数据获取的时候 iboxDB 比 sqlite 快了很多, 如下 :

  Sqlite3 用了46秒, iboxDB 用了2秒, 都是获取一个10012个数据的全表数据......

  找到一个说法 :

  好家伙. 刚好我就是用列名去获取数据了 :

  我改改代码, 看看使用 index 的方式会怎样 :

  好家伙, 0.8秒 VS 46秒, 总算回归正确的地位了......

  然后把 iboxDB 的中间转换去掉, 直接获取 Data_iboxDB 的情况下, 仍然需要1.9秒, 果然反射式的永远比不了数据式的啊, 虽然用起来很方便的说.

  • 上一篇: 图腾农场java教程
  • 下一篇: java教程网
  • 版权声明


    相关文章:

  • 图腾农场java教程2024-12-25 21:10:04
  • 区块链教程 java2024-12-25 21:10:04
  • java真人教程2024-12-25 21:10:04
  • java mysql使用教程2024-12-25 21:10:04
  • java磨刀教程2024-12-25 21:10:04
  • java教程网2024-12-25 21:10:04
  • 谁的java教程视频好2024-12-25 21:10:04
  • java教程412024-12-25 21:10:04
  • java大学教程 中文2024-12-25 21:10:04
  • java教程yyds2024-12-25 21:10:04