博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
slick对超过22个属性的表进行映射的两种办法
阅读量:7239 次
发布时间:2019-06-29

本文共 5596 字,大约阅读时间需要 18 分钟。

版权声明:本文为博主原创文章,未经博主允许不得转载

slick是scala的一个FRM(Functional Relational Mapper)框架,即函数式的关系数据库编程工具库。使用slick不同于使用java的hibernate或者是mybatis,对其进行迭代开发非常方便,因为其对表的映射基于函数式的编程方式。

使用slick对数据库表映射比较方便。

比如有一个表

CREATE TABLE Persons(id int,LastName varchar(255),FirstName varchar(255),Address varchar(255),City varchar(255))

那么slick可以有两种方式进行映射,一种是使用scala的数据结构Tuple,一种是使用csse class,先看第一种

//使用Tupleclass TagsTree(tag: Tag) extends Table[(Int, String, String, String,String)](tag, "Persons") {    def id= column[Int]("id")     def LastName= column[String]("LastName")    def FirstName= column[String]("FirstName")    def Address= column[String]("Address")    def City= column[String]("City")    def * = (id,LastName,FirstName,Address,City);  }

再看第二种case class的方式:

case class Person(id:Int,lastName:String,firstName:String,Address:String,city:String);
class TagsTree(tag: Tag) extends Table[Person](tag, "Persons") {    def id= column[Int]("id")     def LastName= column[String]("LastName")    def FirstName= column[String]("FirstName")    def Address= column[String]("Address")    def City= column[String]("City") def * = (id,LastName,FirstName,Address,City) <> (Person.tupled(), Person.unapply()) ); }

这里要说明一下,<>操作符可以看作某种映射,tupled()会将接受case class本身同样的参数然后生成一个Tuple。unapply是scala的一个语法糖,会返回一个Option[Int,String....]。这便是使用case class的方法了。

但当遇到表中的字段超过22个的时候就有问题了,因为scala规定构造参数不能超过22个,那这个时候怎么办呢,有两个办法,一个是使用slick提供的HList。

使用HList

import slick.collection.heterogeneous.{ HList, HCons, HNil }   type hList =    String :: String :: Option[String] :: Option[String] :: Option[String] :: Option[String] ::      String :: String :: String :: String :: String ::   Int :: Int :: String :: String :: String ::      Int :: Int :: Int ::  Int :: Int :: Int ::   Int :: Int :: Int ::      HNil;  //需要以HNil结尾  class Table(tag: Tag) extends Table[hList](tag, "myTableName") {    def name1 = column[String]("name1")    def name2 = column[String]("name2")    def name3 = column[Option[String]]("name3")    def name4 = column[Option[String]]("name4")    def name5 = column[Option[String]]("name5")    def name6 = column[Option[String]]("name6")    def name7 = column[String]("name7")    def name8 = column[String]("name8")    def name9 = column[String]("name9")    def name10 = column[String]("name10")    def name11 = column[String]("name11")    def name12 = column[Int]("name12")    def name13 = column[Int]("name13")    def name14 = column[String]("name14")    def name15 = column[String]("name15")    def name16 = column[String]("name16")    def name17 = column[Int]("name17")    def name18= column[Int]("name18")    def name19 = column[Int]("name19")    def name20 = column[Int]("name20")    def name21 = column[Int]("name21")    def name22 = column[Int]("name22")    def name23 = column[Int]("name23")    def name24 = column[Int]("name24")    def name25 = column[Int]("name25")    def * =   name1 :: name2 :: name3 :: name4 :: name5 :: name6 ::      name7 :: name8 ::   name8 :: name9 :: name10 ::      name11 :: name12 :: name13 :: name14 :: name15 ::      name16 ::  name17 :: name18 ::   name19 :: name20 :: name21 ::      name22 :: name23 ::    name24 ::  name25 ::       HNil//需要以HNil结尾  }

 不过这种有个缺点,那就是当表中某些属性可能为空,这时需要使用Option[String]()这种数据类型来存放属性。但HList查询出来的时候只会像一个字符串一样的Some("value")。

另一个方法是思路比较简单,既然一个case class放不下,那就拆呗

//代码出处 https://github.com/slick/slick/blob/2.1.0-RC1/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/JdbcMapperTest.scala#L106def testWideMappedEntity {    case class Part(i1: Int, i2: Int, i3: Int, i4: Int, i5: Int, i6: Int)    case class Whole(id: Int, p1: Part, p2: Part, p3: Part, p4: Part)    class T(tag: Tag) extends Table[Whole](tag, "t_wide") {      def id = column[Int]("id", O.PrimaryKey)      def p1i1 = column[Int]("p1i1")      def p1i2 = column[Int]("p1i2")      def p1i3 = column[Int]("p1i3")      def p1i4 = column[Int]("p1i4")      def p1i5 = column[Int]("p1i5")      def p1i6 = column[Int]("p1i6")      def p2i1 = column[Int]("p2i1")      def p2i2 = column[Int]("p2i2")      def p2i3 = column[Int]("p2i3")      def p2i4 = column[Int]("p2i4")      def p2i5 = column[Int]("p2i5")      def p2i6 = column[Int]("p2i6")      def p3i1 = column[Int]("p3i1")      def p3i2 = column[Int]("p3i2")      def p3i3 = column[Int]("p3i3")      def p3i4 = column[Int]("p3i4")      def p3i5 = column[Int]("p3i5")      def p3i6 = column[Int]("p3i6")      def p4i1 = column[Int]("p4i1")      def p4i2 = column[Int]("p4i2")      def p4i3 = column[Int]("p4i3")      def p4i4 = column[Int]("p4i4")      def p4i5 = column[Int]("p4i5")      def p4i6 = column[Int]("p4i6")      def * = (        id,        (p1i1, p1i2, p1i3, p1i4, p1i5, p1i6),        (p2i1, p2i2, p2i3, p2i4, p2i5, p2i6),        (p3i1, p3i2, p3i3, p3i4, p3i5, p3i6),        (p4i1, p4i2, p4i3, p4i4, p4i5, p4i6)      ).shaped <> ({ case (id, p1, p2, p3, p4) =>        // We could do this without .shaped but then we'd have to write a type annotation for the parameters        Whole(id, Part.tupled.apply(p1), Part.tupled.apply(p2), Part.tupled.apply(p3), Part.tupled.apply(p4))      }, { w: Whole =>        def f(p: Part) = Part.unapply(p).get        Some((w.id, f(w.p1), f(w.p2), f(w.p3), f(w.p4)))      })    }    val ts = TableQuery[T]    val oData = Whole(0,      Part(11, 12, 13, 14, 15, 16),      Part(21, 22, 23, 24, 25, 26),      Part(31, 32, 33, 34, 35, 36),      Part(41, 42, 43, 44, 45, 46)    )    ts.ddl.create    ts.insert(oData)    assertEquals(oData, ts.first)  }

 这里再那个.shaped是可以省略的,<>操作符后面看似很复杂,其实同样它后面有两个参数,一个Tuple和一个unapply方法,仅此而已。同时这里将映射写在一个方法里,这也是为什么slick称之为FRM。

 

转载于:https://www.cnblogs.com/listenfwind/p/8412825.html

你可能感兴趣的文章
IE浏览器9.0与王码五笔不兼容的问题
查看>>
理解 pkg-config 工具
查看>>
sphinx全文搜索Php方面的简单处理
查看>>
关于的运维平台化和价值化的思考
查看>>
jQuery1.6从使用到源码教程-get()
查看>>
ssh登录慢的解决办法
查看>>
我的友情链接
查看>>
shell分析nginx日志
查看>>
Centos中文字体支持
查看>>
Linux文件权限
查看>>
druid配置db2参考记录
查看>>
快速排序
查看>>
KindEditor编辑器在j2ee项目中的运用及常用问题回顾
查看>>
vue使用的经验总结
查看>>
Win7系统优化十大技巧
查看>>
uio浅析
查看>>
PHP中$_FILES的使用及注意事项
查看>>
Linux命令之which
查看>>
蓦然回头看JAVA线程变量 ThreadLocal
查看>>
Centos 6.5 装机后安装设置,含脚本
查看>>