41 votes

Quels ORM fonctionnent bien avec Scala?

Je suis en train d'écrire un Scala application de ligne de commande qui s'appuie sur une base de données MySQL. J'ai été en regardant autour d'Orm, et éprouve de la difficulté à en trouver un qui fonctionne bien.

L' Ascenseur de l'ORM a l'air sympa, mais je ne suis pas sûr que ça peut être dissociée de l'ensemble de l'Ascenseur framework web. ActiveObjects aussi semble OK, mais l'auteur dit qu'il pourrait ne pas bien fonctionner avec Scala.

Je ne suis pas venue à la Scala de Java, de sorte que je ne connais pas toutes les options. Quelqu'un a utilisé un ORM avec Scala, et si oui, qu'avez-vous utilisé et comment il fonctionne?

34voto

incarnate Points 997

Il y a plusieurs raisons pourquoi JPA orientée vers des frameworks (Hibernate, par exemple) qui ne rentre pas dans idiomatiques Scala applications élégamment:

  • il n'y a pas imbriquée annotations en tant que membres de la Scala 2.8 Aperçu - ce qui signifie que vous ne pouvez pas utiliser les annotations que la mise en correspondance des métadonnées pour des applications complexes (même les plus simples utilisent souvent @JoinTable -> @JoinColumn);
  • les incohérences entre Scala et Java collections des développeurs de convertir des collections; il y a aussi des cas où il est impossible de carte Scala collections à des associations sans la mise en œuvre des interfaces complexes de l'infrastructure sous-jacente (Hibernate PersistentCollections, par exemple);
  • certains très caractéristiques communes, telles que le domaine de validation de modèle, besoin JavaBeans conventions sur les classes persistantes, ces choses n'est pas tout à fait "Scala façon" de faire les choses;
  • bien sûr, l'interopérabilité des problèmes (comme Raw ou de Types de proxys) introduire un tout nouveau niveau de questions qui ne peuvent être promené facilement.

Il y a plus de raisons, j'en suis sûr. C'est pourquoi nous avons commencé l' accent Circonflexe ORM projet. Ce pur-Scala ORM tente, il est préférable d'éliminer les cauchemars de classique Java Orm. Plus précisément, vous définissez vos entités en assez bien la façon dont vous voulez faire cela avec classique DDL déclarations:

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]

Comme vous pouvez le voir, ces déclarations sont un peu plus verbeux, que classique JPA Pojo. Mais en fait il y a plusieurs concepts qui sont assemblés entre eux:

  • le précis DDL pour génération de schéma (vous pouvez facilement ajouter des index, des clés étrangères et d'autres trucs dans le même DSL-comme la mode);
  • toutes les requêtes peuvent être assemblés à l'intérieur que "l'objet de la table" au lieu d'être éparpillés dans les DAO; les requêtes elles-mêmes sont très flexibles, vous pouvez stocker des objets de requête, des prédicats, des projections, des sous-requêtes et les relations d'alias dans les variables de sorte que vous pouvez les réutiliser et même faire des lots opérations de mise à jour à partir de requêtes existantes (insertion-sélectionnez par exemple);
  • transparente, la navigation entre les associations un-à-un, plusieurs-à-un, un-à-plusieurs et plusieurs-à-plusieurs-par-l'intermédiaire-relation) peut être obtenue soit par paresse ou par désireux d'aller chercher des stratégies; dans les deux cas, les associations sont en grande partie sur les clés étrangères de sous-jacents des relations;
  • la validation est la partie de cadre;
  • il y a aussi un Maven2 plugin qui permet de générer un schéma et de l'importation initiale des données à partir des fichiers au format XML pratique.

Les seules choses Circonflexe ORM manques sont:

  • multi-colonnes de clés primaires (bien qu'il est possible de créer plusieurs colonnes de clés étrangères soutenu par multi-colonne unique contraintes, mais c'est seulement pour l'intégrité des données);
  • à part entière de la documentation (bien que nous travaillons activement sur elle);
  • les histoires de réussite de dix milliards de dollars systèmes de production qui ont un accent Circonflexe ORM comme c'est la technologie de base.

P. S. j'espère que ce post ne sera pas considéré comme une publicité. Il n'en est rien, vraiment, j'ai essayé d'être aussi objectif que possible.

9voto

dkaylor Points 436

J'ai testé EclipseLink JPA et les opérations de base ont bien fonctionné pour moi. JPA est un standard Java et d’autres implémentations peuvent également fonctionner ( OpenJPA , etc.). Voici un exemple de classe JPA à Scala:

 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 = _
}
 

4voto

Je suis heureux de vous annoncer la 1ère sortie d'un nouvel ORM bibliothèque pour Scala. MapperDao cartes de classes du domaine de tables de base de données. Il prend actuellement en charge mysql, postgresql, oracle pilote sera bientôt disponible), un-à-un, plusieurs-à-un, un-à-plusieurs, plusieurs-à-plusieurs relations, générée automatiquement les clés, les transactions et éventuellement s'intègre bien avec le framework spring. Il permet une liberté dans la conception des classes du domaine qui ne sont pas affectés par la persistance de détails, encourage l'immutabilité et de l'est de type sécurisé. La bibliothèque n'est pas basé sur la réflexion, mais plutôt sur la bonne Scala principes de conception et contient un DSL pour les données de la requête, qui ressemble étroitement à des requêtes select. Il ne nécessite pas la mise en œuvre de equals() ou hashCode() sont des méthodes qui peuvent être problématiques pour les entités persistantes. La cartographie est réalisée à l'aide de type coffre-fort Scala code.

Les détails et les instructions d'utilisation peuvent être trouvés à l'mapperdao du site:

http://code.google.com/p/mapperdao/

La bibliothèque est disponible pour téléchargement sur le site ci-dessus et aussi comme une dépendance maven (documentation contient des détails sur la façon de l'utiliser via maven)

Des exemples peuvent être trouvés à:

https://code.google.com/p/mapperdao-examples/

Très brève introduction de la bibliothèque via le code de l'échantillon:

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))

L'interrogation est très familier:

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

J'encourage tout le monde à utiliser la bibliothèque et donner de la rétroaction. La documentation est actuellement assez vaste, avec le programme d'installation et les instructions d'utilisation. N'hésitez pas à commenter et à entrer en contact avec moi à kostas dot kougios à googlemail dot com.

Merci,

Kostantinos Kougios

2voto

Ikai Lan Points 1574

Voici fondamentalement le même exemple avec l'annotation @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

}
 

2voto

JacobusR Points 5865

Slick est un match parfait pour un monde fonctionnel. Les ORM traditionnels ne conviennent pas parfaitement à Scala. Slick compose bien et utilise un DSL qui imite les classes de collection Scala et les compréhensions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X