`
zeallf
  • 浏览: 32609 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Scala 各种数据库访问框架简介

阅读更多
目前有关 Scala libraries 和框架相当多

有一些非ORM的数据库库,也有ORM的,下面列出一些:

ScalaQuery

The first one is ScalaQuery. It is the most mature one, and it tries to make queries use the same for-comprehension as Scala collections do. As an example of syntax style (which might be slightly out of date):
在试用了一下后,发现对MS SERVER 支持地不太好

import java.lang.Integer
import com.novocode.squery._
import com.novocode.squery.Implicit._
import com.novocode.squery.session._
import com.novocode.squery.session.SessionFactory._

// Define table:
object Users extends Table[(Integer, String, String)]("users") {
  def id = intColumn("id", O.AutoInc, O.NotNull)
  def first = stringColumn("first")
  def last = stringColumn("last")
  def * = id ~ first ~ last
}

// Basic usage
val sf = new DriverManagerSessionFactory("org.h2.Driver", "jdbc:h2:mem:test1")
sf withSession {
  // Prepare a simple query
  val q1 = for(u <- Users) yield u

  // Print SQL statement to be executed:
  println(q1.selectStatement)  // displays SELECT t1.id,t1.first,t1.last FROM users t1

  // Print query result:
  for(t <- q1) println("User tuple: "+t)

  // Query statements can also be used with updates:
  val q = for(u <- Users if u.id is 42) yield u.first ~ u.last
  q.update("foo", "bar")
}



Querulous

The second one is Querulous, which is a open source project from Twitter. This one gives you direct access to SQL, while dealing with a bunch of jdbc annoyances. Here's a simple example:

import com.twitter.querulous.evaluator.QueryEvaluator
val queryEvaluator = QueryEvaluator("host", "username", "password")
val users = queryEvaluator.select("SELECT * FROM users WHERE id IN (?) OR name = ?", List(1,2,3), "Jacques") { row =>
  new User(row.getInt("id"), row.getString("name"))
}
queryEvaluator.execute("INSERT INTO users VALUES (?, ?)", 1, "Jacques")
queryEvaluator.transaction { transaction =>
  transaction.select("SELECT ... FOR UPDATE", ...)
  transaction.execute("INSERT INTO users VALUES (?, ?)", 1, "Jacques")
  transaction.execute("INSERT INTO users VALUES (?, ?)", 2, "Luc")
}



Squeryl

The third one is Squeryl. Style-wise, it sits midway between ScalaQuery -- which hides SQL behind Scala comprehensions as much as possible -- and Querulous -- which uses SQL strings directly.

Squeryl provides a SQL-like DSL, which gives you type safety and give you a strong likelyhood that the statements won't fail at run-time if they compile at all. Again, a simple example:

// Defining tables and a schema:
import org.squeryl.PrimitiveTypeMode._

class Author(var id: Long, 
             var firstName: String, 
             var lastName: String)

class Book(var id: Long, 
           var title: String,
           @Column("AUTHOR_ID") // the default 'exact match' policy can be overriden
           var authorId: Long,
           var coAuthorId: Option[Long]) {
  def this() = this(0,"",0,Some(0L))
}

object Library extends Schema {
  //When the table name doesn't match the class name, it is specified here :
  val authors = table[Author]("AUTHORS")
  val books = table[Book]
}

// Basic usage
Class.forName("org.postgresql.Driver"); 
val session = Session.create( 
  java.sql.DriverManager.getConnection("jdbc:postgresql://localhost:5432/squeryl", "squeryl", "squeryl"), 
  new PostgreSqlAdapter 
) 

//Squeryl database interaction must be done with a using block :  
import Library._
using(session) { 
  books.insert(new Author(1, "Michel","Folco"))            
  val a = from(authors)(a=> where(a.lastName === "Folco") select(a)) 
}


O/R Broker
http://code.google.com/p/orbroker/

The fourth is O/R Broker, which, despite the name, is not an ORM. Classes can be designed in any way desired. No interfaces/traits to implement, no conventions to uphold, no annotations needed.
可以快速开发,灵活性较高

case class Song(id: Option[Long], title: String, seconds: Short)
case class Album(id: Option[Long], title: String, year: Short, songs: IndexedSeq[Song])
case class Artist(id: Option[Long], name: String, albums: Set[Album])
Extractors are declarative, written in Scala. Can be reused in other queries that fit the expectation of the extractor.

object SongExtractor extends JoinExtractor[Song] {
  val key = Set("SONG_ID")

  def extract(row: Row, join: Join) = {
    new Song(
          row.bigInt("SONG_ID"), 
          row.string("TITLE").get, 
          row.smallInt("DURATION_SECONDS").get
        )
  }
}

object AlbumExtractor extends JoinExtractor[Album] {
  val key = Set("ALBUM_ID")

  def extract(row: Row, join: Join) = {
    new Album(
          row.bigInt("ALBUM_ID"),
          row.string("TITLE").get,
          row.smallInt("YEAR_ISSUED").get,
          join.extractSeq(SongExtractor, Map("TITLE"->"SONG_TITLE"))
        )  
  }
}

object ArtistExtractor extends JoinExtractor[Artist] {
  val key = Set("ARTIST_ID")

  def extract(row: Row, join: Join) = {
    new Artist(
          row.bigInt("ARTIST_ID"),
          row.string("NAME"),
          join.extractSeq(AlbumExtractor)
        )
  }
}
One could then use that like this:

val ds: javax.sql.DataSource = ...
val builder = new SQLFileBuilder(ds, new java.io.File("sql/"))
val broker = builder.build()

// Print all artists with their albums (if any)
val artists = broker.readOnly() { session =>
  session.selectAll[Artist]('selectArtist) // ' I wish they could fix the Scala Symbol formatting
}
for (ar <- artists) {
  println(a.name)
      if (ar.albums.isEmpty)
        println("\t<No albums>")
      else for (al <- ar.albums) {
        println("\t" + al.title)
        for (s <- al.songs) {
          println("\t\t" + (al.songs.indexOf(s)+1) + ". " + s.title)
        }
      }
}




Anorm
来自于Play框架,it ditches mappings and DSL completely, giving you direct access to SQL. 实例:

// Create an SQL query
val selectCountries = SQL("Select * from Country")

// Transform the resulting Stream[Row] as a List[(String,String)]
val countries = selectCountries().map(row => 
    row[String]("code") -> row[String]("name")
).toList
It also supports pattern matching for row extraction:

val countries = SQL("Select name,population from Country")().collect {
    case Row("France", _) => France()
    case Row(name:String, pop:Int) if(pop > 1000000) => BigCountry(name)
    case Row(name:String, _) => SmallCountry(name)      
}
Binding variables in queries uses this syntax:

SQL(
    """
        select * from Country c 
        join CountryLanguage l on l.CountryCode = c.Code 
        where c.code = {countryCode};
    """
).on("countryCode" -> "FRA")



And it also has support for use of parse combinators to translate queries or even table schemas into data structures. You can either define the parser yourself, or use some default conventions (like a case class mapping field names to column names) and let it do the work for you.

Circumflex ORM
网站上有例子如下:

class Category extends Record[Category] {
  val id = field(Category.id)
  val name = field(Category.name)
  val books = oneToMany(Book.category)    // allows navigating between associations transparently
}

object Category extends Table[Category] with LongIdPK[Category] {
  val name = stringColumn("name")         // creates a column
      .notNull                            // creates NOT NULL constraint
      .unique                             // creates UNIQUE constraint
      .validateNotEmpty                   // adds NotEmpty validation
      .validatePattern("^[a-zA-Z]{1,8}$") // adds Pattern validation
}

class Book extends Record[Book] {
  val id = field(Book.id)
  val title = field(Book.title)
  val category = manyToOne(Book.category)
}

object Book extends Table[Book] with LongIdPK[Book] {
  val title = stringColumn("title")
      .notNull
      .validateNotEmpty
  val category = longColumn("category_id")
      .references(Category)     // creates an association with Category
      .onDeleteSetNull          // specifies a foreign-key action
      .onUpdateCascade
}

new DDLExport(Category, Book).create   // creates database schema

// find category by id
val c = Category.get(2l)
// find all books
val allBooks = Book.all
// find books for category
val cBooks = c.get.books
// find books by title
Book.criteria.add("title" like "a%").list

select()
      .from(Category as "c" join (Book as "b"), Category as "c1")
      .where("c1.name" like "a%")
      .addOrder(asc("c.name"))
      .list

select(count("b.id"), "c.name").from(Category as "c" join (Book as "b")).list


以上资料摘至
http://stackoverflow.com/questions/1362748/wanted-good-examples-of-scala-database-persistence
分享到:
评论

相关推荐

    scala + mybatis 数据库查询

    MyBatis则是一款流行的Java持久层框架,主要用于简化数据库操作。在本项目中,"scala + mybatis 数据库查询",我们将探讨如何将Scala与MyBatis结合,实现高效的数据库查询功能。 1. **Scala与MyBatis的集成** - ...

    domala:Scala的面向域的数据库映射框架

    Domala是Scala的数据库访问库。 这包装了 。 Domala使用生成代码并在编译时验证sql映射。 Select语句由您自己编写。 它被自动映射到Option[ Entity ] , Seq[ Entity ] , Stream[ Entity ] , Seq[Map[String, ...

    Scala数据库百度云04.txt

    根据提供的文件信息:“Scala数据库百度云04.txt”,我们无法直接获取到具体的内容来生成相关的知识点。但从文件的标题、描述以及部分可见内容来看,我们可以推测这份文档可能涉及Scala编程语言与数据库操作的相关...

    jdbi-scala_2.9.1-0.2.0.zip

    Jdbi,源自Java Database Bridge,是Java领域的一款轻量级数据库访问框架。它弥补了JDBC(Java Database Connectivity)在处理数据库操作时的繁琐和易错性,通过提供一种更简洁、更安全的方式来执行SQL语句,包括...

    JAVA各种系统框架图简介

    在Java开发领域,框架是构建...文档"JAVA各种系统框架图简介.doc"可能包含了这些框架的详细图解,帮助进一步理解它们的工作原理和使用方式。在实际开发中,理解并熟练运用这些框架,可以极大地提高开发效率和软件质量。

    SpringBoot + SpringData Jpa + Scala + Mysql(java+Scala混编)

    综上所述,这个项目结合了SpringBoot的便捷性,SpringData JPA的数据库访问能力,Scala的编程灵活性,以及MySQL的数据库服务。通过pom.xml配置文件,项目能够自动管理所有依赖,而src目录下的源代码组织则体现了Java...

    Spring 整合 Scala 编程【转】

    6. **Spring Data与Scala**:Spring Data项目简化了数据库访问,提供了对多种数据存储的支持。Scala开发者可以利用Spring Data的Repository抽象,结合Scala的函数式风格处理数据操作。 7. **ScalaTest与Spring测试*...

    scala jdbc 库,需要 spring-jdbc

    在Java或Scala环境中,Spring JDBC通常作为更方便、更易用的数据库访问方式。 首先,了解Scala JDBC库。Scala JDBC库提供了一种面向对象的方式来操作SQL,使得在Scala中执行数据库查询变得更加简洁和直观。它封装了...

    基于Java和Scala的DAF4J设计源码:数据访问简化与统一接口实现

    该项目是一款名为DAF4J的Java与Scala混合编写的开源数据访问框架源码,旨在简化并统一Java的数据访问层结构。该框架提供了一套简洁易读的领域特定语言(DSL),以实现数据访问的统一接口。项目总文件量为135个,其中...

    play2+scala+mongodb demo示例

    6. **数据库访问**: 可能使用Play的MongoDB驱动,如`play.api.db.evolutions.MongoEvolution`,来进行数据操作。 这个demo项目将帮助你学习如何在Scala中使用Play Framework创建Web应用,并与MongoDB进行交互,从而...

    Scala.in.Action

    - **生态系统**:Scala有着成熟的生态系统,包括各种库和框架,如Akka、Play Framework等,适用于构建高性能的并发应用和服务端应用。 2. **快速入门** - **环境搭建**:介绍了如何安装Scala环境,包括设置Sbt...

    awesome-scala:由社区驱动的有用的Scala库,框架和软件列表

    目录人工智能名称描述GitHub活动类型安全,纯功能的计算智能CIlib社区驱动的教程数据库Scala中的数据库访问库。 名称描述GitHub活动 akka-persistence-gcp-datastore是日记和快照存储插件,用于在数据存储模式下使用...

    王治:用Scala构建19楼社区

    - 从Discuz向Scala的迁移:19楼社区从使用Discuz作为论坛基础,逐步迁移到Scala框架,这个过程中包括了对前端展现层的改造、数据访问层的剥离和分库分表等策略。 - 架构的优化:面对热门板块数据量巨大的问题,...

    Play for Scala

    《Play for Scala》是一本详细介绍Play框架2.x版本的书籍,作者包括Peter Hilton、Erik Bakker和Francisco Canedo。这本书适合想要深入了解并实践Play框架的Scala开发者,它不仅仅涉及基本的框架使用,还包括核心...

    机器学习前端,没有hbase数据库结构和scala的算法jar包,慎用

    Spark,一个由Scala编写的开源大数据处理框架,充分利用了Scala的特性,提供高效的数据处理和分析能力。在机器学习场景中,Scala的jar包通常包含了预训练的算法或者自定义的模型实现,可以直接在Spark上运行。如果...

    userdao:一个带有自动生成的流畅代码、数据库访问层和使用 scalatest 测试的流畅应用程序

    "userdao"项目,正如其标题所言,是一个致力于提供流畅代码体验的框架,它包含了一个自动生成的数据库访问层,并且充分利用了ScalaTest进行严谨的测试。这个项目特别关注于提升开发者的生产力,使得处理用户数据变得...

    基于scala的小型超市管理系统的设计与实现

    3. **数据访问层**:使用Scala的Slick库,我们可以方便地与数据库进行交互,实现ORM(对象关系映射)。Slick允许我们用Scala代码直接操作数据库,降低了SQL的编写难度,提高了代码的可读性和可维护性。 4. **业务...

    scala-2.11.2.tgz

    10. **社区和工具**:Scala拥有活跃的开发者社区,提供众多框架和库,如Play Framework用于Web开发,Spark用于大数据处理,Slick用于数据库访问。此外,IDE支持如IntelliJ IDEA和Scala IDE为开发提供了强大的工具。 ...

Global site tag (gtag.js) - Google Analytics