• Scala与Mongodb实践2-----图片、日期的存储读取


    目的:在IDEA中实现图片、日期等相关的类型在mongodb存储读取

    • 主要是Scala和mongodb里面的类型的转换。Scala里面的数据编码类型和mongodb里面的存储的数据类型各个不同。存在类型转换。
    • 而图片和日期的转换如下图所示。

     1、日期的存取

    • 简单借助java.until.Calendar即可。
    val ca=Calendar.getInstance()
    ca.set()
    ca.getTime
    • 有多种具体的格式等,再直接应用mgoDateTime等方法
     //显示各种格式
    type MGODate = java.util.Date
      def mgoDate(yyyy: Int, mm: Int, dd: Int): MGODate = {
        val ca = Calendar.getInstance()
        ca.set(yyyy,mm,dd)
        ca.getTime()
      }
      def mgoDateTime(yyyy: Int, mm: Int, dd: Int, hr: Int, min: Int, sec: Int): MGODate = {
        val ca = Calendar.getInstance()
        ca.set(yyyy,mm,dd,hr,min,sec)
        ca.getTime()
      }
      def mgoDateTimeNow: MGODate = {
        val ca = Calendar.getInstance()
        ca.getTime
      }
      def mgoDateToString(dt: MGODate, formatString: String): String = {
        val fmt= new SimpleDateFormat(formatString)
        fmt.format(dt)
      }
    

      

    2、图片的存取(看图片大小,一般都是如下,大于16M的图片即采用GridFS,分别将图片的属性存储)

    借助Akka的FileStream

    将File(图片)===》Array[Byte]代码格式,图片在mongodb中显示形式binary

    具体代码如下:

    FileStreaming.scala
    package com.company.files
    
    import java.nio.file.Paths
    import java.nio._
    import java.io._
    import akka.stream.{Materializer}
    import akka.stream.scaladsl.{FileIO, StreamConverters}
    
    import scala.concurrent.{Await}
    import akka.util._
    import scala.concurrent.duration._
    
    object FileStreaming {
      def FileToByteBuffer(fileName: String, timeOut: FiniteDuration)(
        implicit mat: Materializer):ByteBuffer = {
        val fut = FileIO.fromPath(Paths.get(fileName)).runFold(ByteString()) { case (hd, bs) =>
          hd ++ bs
        }
        (Await.result(fut, timeOut)).toByteBuffer
      }
    
      def FileToByteArray(fileName: String, timeOut: FiniteDuration)(
        implicit mat: Materializer): Array[Byte] = {
        val fut = FileIO.fromPath(Paths.get(fileName)).runFold(ByteString()) { case (hd, bs) =>
          hd ++ bs
        }
        (Await.result(fut, timeOut)).toArray
      }
    
      def FileToInputStream(fileName: String, timeOut: FiniteDuration)(
        implicit mat: Materializer): InputStream = {
        val fut = FileIO.fromPath(Paths.get(fileName)).runFold(ByteString()) { case (hd, bs) =>
          hd ++ bs
        }
        val buf = (Await.result(fut, timeOut)).toArray
        new ByteArrayInputStream(buf)
      }
    
      def ByteBufferToFile(byteBuf: ByteBuffer, fileName: String)(
        implicit mat: Materializer) = {
        val ba = new Array[Byte](byteBuf.remaining())
        byteBuf.get(ba,0,ba.length)
        val baInput = new ByteArrayInputStream(ba)
        val source = StreamConverters.fromInputStream(() => baInput)  //ByteBufferInputStream(bytes))
        source.runWith(FileIO.toPath(Paths.get(fileName)))
      }
    
      def ByteArrayToFile(bytes: Array[Byte], fileName: String)(
        implicit mat: Materializer) = {
        val bb = ByteBuffer.wrap(bytes)
        val baInput = new ByteArrayInputStream(bytes)
        val source = StreamConverters.fromInputStream(() => baInput) //ByteBufferInputStream(bytes))
        source.runWith(FileIO.toPath(Paths.get(fileName)))
      }
    
      def InputStreamToFile(is: InputStream, fileName: String)(
        implicit mat: Materializer) = {
        val source = StreamConverters.fromInputStream(() => is)
        source.runWith(FileIO.toPath(Paths.get(fileName)))
      }
    }
    
    • Helpers.scala  
    package com.company.lib
    
    import java.util.concurrent.TimeUnit
    
    import scala.concurrent.Await
    import scala.concurrent.duration.Duration
    import java.text.SimpleDateFormat
    import java.util.Calendar
    import org.mongodb.scala._
    
    object Helpers {
    
      implicit class DocumentObservable[C](val observable: Observable[Document]) extends ImplicitObservable[Document] {
        override val converter: (Document) => String = (doc) => doc.toJson
      }
    
      implicit class GenericObservable[C](val observable: Observable[C]) extends ImplicitObservable[C] {
        override val converter: (C) => String = (doc) => doc.toString
      }
    
      trait ImplicitObservable[C] {
        val observable: Observable[C]
        val converter: (C) => String
    
        def results(): Seq[C] = Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
        def headResult() = Await.result(observable.head(), Duration(10, TimeUnit.SECONDS))
        def printResults(initial: String = ""): Unit = {
          if (initial.length > 0) print(initial)
          results().foreach(res => println(converter(res)))
        }
        def printHeadResult(initial: String = ""): Unit = println(s"${initial}${converter(headResult())}")
      }
    
    
      type MGODate = java.util.Date
      def mgoDate(yyyy: Int, mm: Int, dd: Int): MGODate = {
        val ca = Calendar.getInstance()
        ca.set(yyyy,mm,dd)
        ca.getTime()
      }
      def mgoDateTime(yyyy: Int, mm: Int, dd: Int, hr: Int, min: Int, sec: Int): MGODate = {
        val ca = Calendar.getInstance()
        ca.set(yyyy,mm,dd,hr,min,sec)
        ca.getTime()
      }
      def mgoDateTimeNow: MGODate = {
        val ca = Calendar.getInstance()
        ca.getTime
      }
    
    
      def mgoDateToString(dt: MGODate, formatString: String): String = {
        val fmt= new SimpleDateFormat(formatString)
        fmt.format(dt)
      }
    
    }
    
    •  Model.scala

    模型中包含了两个具体的模型Person和Address,二者是包含关系,具体模型内含存取方法

     

                                            

    package com.company.demo
    
    import org.mongodb.scala._
    import bson._
    import java.util.Calendar
    import com.company.files._
    
    import akka.stream.ActorMaterializer
    
    object Models {
    //Model可存在在不同的模型,下面存在一个拥有代表性的模型Person
    
      case class Address(
                        //Scala中的字段类型,且String的默认参数是“”
                        city: String ="",
                        zipcode: String = ""
                        ) {
        def toDocument: Document =
          bson.Document(       
     //bson.Document是bson包里面的Document,其他包内有不同的Document
            "city" -> city,
            "zipcode" -> zipcode
          )
        def fromDocument(doc: Document): Address =
          this.copy(
            city = doc.getString("city"),
            zipcode = doc.getString("zipcode")
          )
      }
        //这是日期的设置
      val ca = Calendar.getInstance()
      ca.set(2001,10,23)
      val defaultDate = ca.getTime
      case class Person (
                        lastName: String = "Doe",
                        firstName: String = "John",
                        age: Int = 1,
                        phones: List[String] = Nil,
                        address: List[Address] = Nil,
                        birthDate: java.util.Date = defaultDate,
                        picture: Array[Byte] = Array()
                        ) { ctx =>
        def toDocument: Document = {
          var doc = bson.Document(
            "lastName" -> ctx.lastName,
            "firstName" -> ctx.firstName,
            "age" -> ctx.age,
            "birthDate" -> ctx.birthDate
          )
          if (ctx.phones != Nil)
            doc = doc + ("phones" -> ctx.phones)
          if (ctx.address != Nil)
            doc = doc + ("address" -> ctx.address.map(addr => addr.toDocument))
          if (!ctx.picture.isEmpty)
            doc = doc + ("picture" -> ctx.picture)
    
          doc
    
        }
        import scala.collection.JavaConverters._
        def fromDocument(doc: Document): Person = {
            //keySet
          val ks = doc.keySet
          ctx.copy(
            lastName = doc.getString("lastName"),
            firstName = doc.getString("firstName"),
            age = doc.getInteger("age"),
            phones = {
                doc.get("phones").asInstanceOf[Option[BsonArray]] match {
                case Some(barr) => barr.getValues.asScala.toList.map(_.toString)
                case None => Nil
              }
            },
            address = {
              if (ks.contains("address")) {
                doc.get("address").asInstanceOf[Option[BsonArray]] match {
                  case Some(barr) => barr.getValues.asScala.toList.map (
                    ad => Address().fromDocument(ad.asDocument())
                  )
                  case None => Nil
                }
              }
              else Nil
            },
            picture = {
              if (ks.contains("picture")) {
                doc.get("picture").asInstanceOf[Option[BsonBinary]] match {
                  case Some(ba) => ba.getData
                  case None => Array()
                }
              }
              else Array()
            }
          )
        }
         //在控制台显示的格式。
        def toSink()(implicit mat: ActorMaterializer) = {
          println(s"LastName: ${ctx.lastName}")
          println(s"firstName: ${ctx.firstName}")
          println(s"age: ${ctx.age}")
          println(s"phones: ${ctx.phones}")
          println(s"address ${ctx.address}")
          if(!ctx.picture.isEmpty) {
            val path = s"/img/${ctx.firstName}.jpg"
            FileStreaming.ByteArrayToFile(ctx.picture,path)
            println(s"picture saved to: ${path}")
          }
        }
    
      }
    
    
    }
    

      

    •  PersonCRUD.scala简单测试
    package com.company.demo
    
    import org.mongodb.scala._
    import bson._
    import java.util.Calendar
    import scala.collection.JavaConverters._
    import com.company.lib.Helpers._
    import com.company.files.FileStreaming._
    import akka.actor._
    import akka.stream._
    import scala.concurrent.duration._
    import scala.util._
    
    object PersonCRUD extends  App {
      import Models._
    
        implicit val system = ActorSystem()
        implicit val ec = system.dispatcher
        implicit val mat = ActorMaterializer()
    
        // or provide custom MongoClientSettings
        val settings: MongoClientSettings = MongoClientSettings.builder()
          .applyToClusterSettings(b => b.hosts(List(new ServerAddress("localhost")).asJava))
          .build()
        val client: MongoClient = MongoClient(settings)
        val mydb = client.getDatabase("mydb")
        val mytable = mydb.getCollection("personal")
    
        val susan = Person(
          lastName = "Wang",
          firstName = "Susan",
          age = 18,
          phones = List("137110998","189343661"),
          address = List(
            Address("Sz","101992"),
            Address(city = "gz", zipcode="231445")
          ),
          birthDate = mgoDate(2001,5,8),
          picture = FileToByteArray("/img/sc.jpg",3 seconds)
        )
    /*
        val futResult = mytable.insertOne(susan.toDocument).toFuture()
    
        futResult.onComplete {
          case Success(value) => println(s"OK! ${value}")
          case Failure(err) => println(s"Boom!!! ${err.getMessage}")
        }
    
        scala.io.StdIn.readLine() */
    mytable.find().toFuture().andThen { case Success(ps) => ps.foreach(Person().fromDocument(_).toSink()) case Failure(err) => println(s"ERROR: ${err.getMessage}") } scala.io.StdIn.readLine() system.terminate() }

      

  • 相关阅读:
    android 网络请求Volley的简单使用
    数据加密,android客户端和服务器端可共用
    非常有用的GitHub链接
    android开发——Android开发中的47个小知识
    EditText禁用系统键盘,光标可以继续使用
    Android Studio 快速开发
    Android系统拍照之后回显并且获取文件路径
    Android为TV端助力 doc里面adb连接出现问题的解决方法
    Android为TV端助力 自定义view中findViewById为空的解决办法
    Android为TV端助力 VelocityTracker 速度追踪器的使用及创建
  • 原文地址:https://www.cnblogs.com/0205gt/p/11126846.html
Copyright © 2020-2023  润新知