MySQLデータベースに依存するScalaコマンドラインアプリケーションを作成しようとしています。ORMを探していましたが、うまく機能するものを見つけるのに苦労しています。
Lift ORM は見栄えが良いですが、LiftWebフレームワーク全体から切り離すことができるかどうかはわかりません。 ActiveObjectsも問題ないように見えますが、作者はScalaではうまく機能しない可能性があると述べています。
私はJavaからScalaに来ていないので、すべてのオプションがわかりません。ScalaでORMを使用した人はいますか?作業?
JPA指向のフレームワーク(Hibernateなど)が慣用的なScalaアプリケーションにエレガントに適合しない理由はいくつかあります:
@JoinTable
-> @JoinColumn
);PersistentCollections
など)を実装せずにアソシエーションに。他にも理由があると思います。そのため、 Circumflex ORMプロジェクト を開始しました。この純粋なScalaORMは、古典的なJava ORMの悪夢を排除するのが最善です。具体的には、古典的なDDLステートメントでこれを行うのとほぼ同じ方法でエンティティを定義します。
class User extends Record[User] {
val name = "name".TEXT.NOT_NULL
val admin = "admin".BOOLEAN.NOT_NULL.DEFAULT('false')
}
object User extends Table[User] {
def byName(n: String): Seq[User] = criteria.add(this.name LIKE n).list
}
// example with foreign keys:
class Account extends Record[Account] {
val accountNumber = "acc_number".BIGINT.NOT_NULL
val user = "user_id".REFERENCES(User).ON_DELETE(CASCADE)
val amount = "amount".NUMERIC(10,2).NOT_NULL
}
object Account extends Table[Account]
ご覧のとおり、これらの宣言は、従来のJPAPOJOよりも少し冗長です。しかし実際には、一緒に組み立てられるいくつかの概念があります。
CircumflexORMに欠けているのは次のとおりです。
P.S.この投稿が広告と見なされないことを願っています。そうではありません。私はできるだけ客観的になるように努めていました。
EclipseLink JPA で実験しましたが、基本的な操作は問題なく機能しました。 JPAはJava標準であり、他にも機能する可能性のある実装があります( OpenJPA など)。 ScalaのJPAクラスがどのように見えるかの例を次に示します。
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity { val name = "Users" }
class User {
@Id
@GeneratedValue
var userid:Long = _
var login:String = _
var password:String = _
var firstName:String = _
var lastName:String = _
}
Scala用の新しいORMライブラリの最初のリリースを発表できることをうれしく思います。 MapperDaoは、ドメインクラスをデータベーステーブルにマップします。現在、mysql、postgresql(Oracleドライバーは間もなく利用可能)、1対1、多対1、1対多、多対多の関係、自動生成されたキー、トランザクションをサポートし、オプションでSpringとうまく統合します。フレームワーク。これにより、永続性の詳細に影響されないドメインクラスの設計に自由が与えられ、不変性が促進され、タイプセーフになります。ライブラリはリフレクションに基づいているのではなく、優れたScala設計原則に基づいており、selectクエリによく似たデータをクエリするDSLが含まれています。equals()やhashCode()の実装は必要ありません。 )永続化されたエンティティにとって問題となる可能性のあるメソッド。マッピングは、タイプセーフScalaコードを使用して行われます。
詳細と使用方法については、mapperdaoのサイトをご覧ください。
http://code.google.com/p/mapperdao/
ライブラリは、上記のサイトからダウンロードでき、Mavenの依存関係としても入手できます(ドキュメントには、Mavenを介してライブラリを使用する方法の詳細が含まれています)
例は次の場所にあります。
https://code.google.com/p/mapperdao-examples/
コードサンプルによるライブラリの非常に簡単な紹介:
class Product(val name: String, val attributes: Set[Attribute])
class Attribute(val name: String, val value: String)
...
val product = new Product("blue jean", Set(new Attribute("colour", "blue"), new Attribute("size", "medium")))
val inserted = mapperDao.insert(ProductEntity, product)
// the persisted entity has an id property:
println("%d : %s".format(inserted.id,inserted))
クエリは非常によく知られています。
val o=OrderEntity
import Query._
val orders = query(select from o where o.totalAmount >= 20.0 and o.totalAmount <= 30.0)
println(orders) // a list of orders
ライブラリを使用してフィードバックを提供することをお勧めします。ドキュメントは現在非常に広範囲で、セットアップと使用方法の説明があります。 googlemail dotcomのkostasdot kougiosにコメントして、私に連絡してください。
ありがとう、
コスタンティノスコウギオス
これは基本的に@Columnアノテーションを使用した同じ例です。
/*
Corresponding table:
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`admin` tinyint(1) default '0',
PRIMARY KEY (`id`)
)
*/
import _root_.javax.persistence._
@Entity
@Table{val name="users"}
class User {
@Id
@Column{val name="id"}
var id: Long = _
@Column{val name="name"}
var name: String = _
@Column{val name="admin"}
var isAdmin: Boolean = _
override def toString = "UserId: " + id + " isAdmin: " + isAdmin + " Name: " + name
}
Slick は機能的な世界にぴったりです。従来のORMはScalaに完全には適合しません。 Slickはうまく構成され、Scalaコレクションクラスを模倣し、理解するためにDSLを使用します。
もちろん、任意のJavaデータベースアクセスフレームワークはScalaでも機能し、コレクションの変換など、通常発生する可能性のある問題があります。jOOQたとえば、Scalaでうまく機能することが観察されています。ScalaのjOOQコードの例は、マニュアルに記載されています。
object Test {
def main(args: Array[String]): Unit = {
val c = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
val f = new Factory(c, SQLDialect.H2);
val x = T_AUTHOR as "x"
for (r <- f
select (
T_BOOK.ID * T_BOOK.AUTHOR_ID,
T_BOOK.ID + T_BOOK.AUTHOR_ID * 3 + 4,
T_BOOK.TITLE || " abc" || " xy"
)
from T_BOOK
leftOuterJoin (
f select (x.ID, x.YEAR_OF_BIRTH)
from x
limit 1
asTable x.getName()
)
on T_BOOK.AUTHOR_ID === x.ID
where (T_BOOK.ID <> 2)
or (T_BOOK.TITLE in ("O Alquimista", "Brida"))
fetch
) {
println(r)
}
}
}
http://www.jooq.org/doc/2.6/manual/getting-started/jooq-and-scala/ から取得