SlideShare une entreprise Scribd logo
1  sur  128
Persistens i Scala
         JavaZone
X
    Trond
Marius
Øvstetun




           ©
Mesan
AS
Agenda

•   Sette
fokus
på
persistens‐laget
•   Det
finnes
mange
alternativer!
•   En
liten
introduksjon




                            ©
Mesan
AS
Agenda

•   Sette
fokus
på
persistens‐laget
•   Det
finnes
mange
alternativer!
•   En
liten
introduksjon


•   Tenke
seg
om
i
de
valgene
man
gjør




                            ©
Mesan
AS
Trond Marius Øvstetun
•   Seniorkonsulent
og

    fagleder
i
Mesan

•   Lidenskapelig
utvikler,

    arkitekt,
teamleder
++

•   Java,
Scala,
HTML/js

•   Alltid
på
jakt
etter
bedre,

    enklere
måter


                             ©
Mesan
AS
Mesan
            ...
når
standardsystemer
ikke
er
nok


•   Systemutvikling
–
skreddersøm
•   Løsningsfokus
•   “Store”
systemer
•   Transaksjonssystemer




                           ©
Mesan
AS
Mesan
             ...
når
standardsystemer
ikke
er
nok


•   Systemutvikling
–
skreddersøm
•   Løsningsfokus
•   “Store”
systemer
•   Transaksjonssystemer
•   Lang
levetid
–
langsiktighet



                           ©
Mesan
AS
Levetid


  ©
Mesan
AS
Systemer i endring

     V1   V2     V3    V4   V5   V6




                DB




               ©
Mesan
AS
Systemer i endring

               Forretningsprosesser



     V1   V2        V3     V4         V5   V6




                  DB




                 ©
Mesan
AS
Systemer i endring

               Forretningsprosesser




    V1    V2    V3     V4      V5     V6   V7




         T1    T2     T3      T4      T5   T6




                      DB




                ©
Mesan
AS
Systemer i endring

                         Forretningsprosesser




              V1    V2    V3      V4     V5     V6   V7




                   T1    T2      T3     T4      T5   T6
  Teknologi




                                 DB




                    ©
Mesan
AS
Systemer i endring
                             Forretningsprosesser




   V1        V2         V3        V4        V5    V6   V7   V8    V9




        F1         F2         F3        F4        F5   F6    F7




                  T1         T2        T3        T4    T5   T6




                                       DB




                              ©
Mesan
AS
Java -> Scala
            Teknologien
driver
oss

Hva
man
sitter
igjen
med
etter
introduksjonen...




                    ©
Mesan
AS
•   De
fleste
som
prøver
Scala
har
bakgrunn
fra
Java
•   Innarbeidede
rutiner,
forventninger,
perferanser,

    tankesett,
rammeverk
etc
    •   Objektorientert?
    •   Transaksjonsskript?




                              ©
Mesan
AS
Person
             firstname : String
             lastname : String
             birthDate : Date
             gender : Gender




©
Mesan
AS
public class Person {
    private String firstname;
    private String lastname;
    private Date birthDate;
    private Gender gender;

    public Person(String firstname, String lastname, Gender gender, Date birthDate) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.gender = gender;
        this.birthDate = birthDate;
    }

    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public Date getBirthDate() {                                                         Person
        return birthDate;
    }                                                                              firstname : String
    public void setBirthDate(Date birthDate) {
                                                                                   lastname : String
        this.birthDate = birthDate;
    }                                                                              birthDate : Date
                                                                                   gender : Gender
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
}
                                                            ©
Mesan
AS
public class Person {
    private String firstname;
    private String lastname;
    private Date birthDate;
    private Gender gender;

    public Person(String firstname, String lastname, Gender gender, Date birthDate) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.gender = gender;
        this.birthDate = birthDate;
    }

    public String getFirstname() {
        return firstname;
    }
                                                             class Person(var firstname:String, var lastname:String,
    public void setFirstname(String firstname) {
        this.firstname = firstname;                                       var gender:Gender, var birthdate:Date)
    }

    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public Date getBirthDate() {                                                         Person
        return birthDate;
    }                                                                              firstname : String
    public void setBirthDate(Date birthDate) {
                                                                                   lastname : String
        this.birthDate = birthDate;
    }                                                                              birthDate : Date
                                                                                   gender : Gender
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
}
                                                            ©
Mesan
AS
null? Nei takk
•   Option[T]
    •   Some
–
innhold
    •   None




                         ©
Mesan
AS
null? Nei takk
•   Option[T]
    •   Some
–
innhold   class Person(var firstname:String, var lastname:String,
                                      var gender:Gender, var birthdate:Option[Date] = None)



    •   None




                           ©
Mesan
AS
null? Nei takk
      •   Option[T]
          •   Some
–
innhold                   class Person(var firstname:String, var lastname:String,
                                                            var gender:Gender, var birthdate:Option[Date] = None)



          •   None
interface PersonRepository {
    /**
     * @return A person if found, <code>null</code> otherwise.
     */
    Person findById(int id);
}

PersonRepository repo;
Person person = repo.findById(1);
if (person != null) {
    person.updateThySelf();
}

PersonRepository repo;
Person person = repo.findById(1);
if (person != null) {
    return person.firstname + " " + person.lastname;
} else {
    return "John Doe"
}
                                                 ©
Mesan
AS
null? Nei takk
      •   Option[T]
          •   Some
–
innhold                   class Person(var firstname:String, var lastname:String,
                                                            var gender:Gender, var birthdate:Option[Date] = None)



          •   None
interface PersonRepository {
    /**
     * @return A person if found, <code>null</code> otherwise.
                                                                 trait PersonRepository {
     */
                                                                   def findById(id:Int) : Option[Person]
    Person findById(int id);
                                                                 }
}

PersonRepository repo;
Person person = repo.findById(1);                                val repo:PersonRepository
if (person != null) {                                            val p = repo.findById(1)
    person.updateThySelf();                                      for (person <- p) {
}                                                                  person.updateThySelf()
                                                                 }
PersonRepository repo;
Person person = repo.findById(1);                                val repo:PersonRepository
if (person != null) {
                                                                 val p = repo.findById(1)
    return person.firstname + " " + person.lastname;             p.map(person =>
} else {
                                                                   person.firstname + " " + person.lastname)
    return "John Doe"                                              .getOrElse("John Doe")
}
                                                 ©
Mesan
AS
Statisk, men “dynamisk”
•   Scala
er
utvidbart
                                       "(d)*".r => Regex
                                       "123".toInt => Int(123)
    •   “Pimp
My
Library”              "hello %s".format("world") => String("hello world")
                                       "hello".capitalize => "Hello"


•   Utvider
vanlige
klasser

    med
metoder                                  1 to 10 => Range(1, 10)
                                                 1 until 10 => Range(1, 9)


•   Mye
i
vanlige
bibliotek




                               ©
Mesan
AS
Statisk, men “dynamisk”
•   Scala
er
utvidbart
                                       "(d)*".r => Regex
                                       "123".toInt => Int(123)
    •   “Pimp
My
Library”              "hello %s".format("world") => String("hello world")
                                       "hello".capitalize => "Hello"


•   Utvider
vanlige
klasser

    med
metoder                                  1 to 10 => Range(1, 10)
                                                 1 until 10 => Range(1, 9)


•   Mye
i
vanlige
bibliotek

                                        implicit def strToFoo(in:String) : Foo = new Foo(in)
                                        class Foo(f:String) {
                                          def bar = f + "bar"
•   Roll
your
own!                      }

                                        "foo".bar => "foobar"




                               ©
Mesan
AS
Avanserte strukturer
        val persons = List(Person("Per"), Person("Pål"), Person("Espen"))
        val (lucky, unlucky) = persons.partition(_.name == "Espen")

        val fullnames = persons.map(_.name + " Askeladd")
        for (n <- fullnames) {
          println(n)
        }




         ©
Mesan
AS
Avanserte strukturer
                            val persons = List(Person("Per"), Person("Pål"), Person("Espen"))
                            val (lucky, unlucky) = persons.partition(_.name == "Espen")
•   Scala
collections
er
   val fullnames = persons.map(_.name + " Askeladd")

    kraftig
kost            for (n <- fullnames) {
                              println(n)
                            }




                             ©
Mesan
AS
Avanserte strukturer
                            val persons = List(Person("Per"), Person("Pål"), Person("Espen"))
                            val (lucky, unlucky) = persons.partition(_.name == "Espen")
•   Scala
collections
er
   val fullnames = persons.map(_.name + " Askeladd")

    kraftig
kost            for (n <- fullnames) {
                              println(n)
                            }




•   Tuppler                 val navn = ("Trond Marius", "Øvstetun")




                             ©
Mesan
AS
Avanserte strukturer
                            val persons = List(Person("Per"), Person("Pål"), Person("Espen"))
                            val (lucky, unlucky) = persons.partition(_.name == "Espen")
•   Scala
collections
er
   val fullnames = persons.map(_.name + " Askeladd")

    kraftig
kost            for (n <- fullnames) {
                              println(n)
                            }




•   Tuppler                 val navn = ("Trond Marius", "Øvstetun")




                            case class MyVal(s:String)
                            def myMatch(n:Any) : String = {
                              n match {

•   Pattern
matching
           case 1 => "ONE"
                                case n:Int if n < 10 => "low..."

    ruler!                      case n:Int if n > 10 => "high!"
                                case p:Person => "a person: " + p.firstname
                                case MyVal(s) => s
                              }
                            }



                             ©
Mesan
AS
Objekter? Funksjoner?
•   Høyereordens
funksjoner
–
gjenbruk
og
abstraksjon
•   Immutable
datastrukturer
–
sikkerhet
•   case
class
‐>
copy(...)
•   Minimalisere
API
og
API‐bruk,
spesialisere
tjenester


•   Klar
og
konsistent
kode




                              ©
Mesan
AS
The selling point
 “Slapp
av
–
Alle
java‐biblioteker
og
APIer
           fungerer
med
Scala!”




                  ©
Mesan
AS
The selling point
 “Slapp
av
–
Alle
java‐biblioteker
og
APIer
           fungerer
med
Scala!”

          Men
er
det
så
enkelt?



                  ©
Mesan
AS
En typisk applikasjon
        Brukergrensesnitt




         Visningslogikk




        Forretningslogikk




          Data aksess




               DB




         ©
Mesan
AS
En typisk applikasjon
                 Brukergrensesnitt




                  Visningslogikk




     Domene      Forretningslogikk




                   Data aksess




                  DB




              ©
Mesan
AS
En typisk java-
               HTML / Javascript




                 Spring MVC
                 @Controller




  @Entity
   JPA               Spring
                    @Service




                 Spring / JPA
                 @Repository




               DB




            ©
Mesan
AS
En enkel datamodell
    «enumeration»
                           Artist
      Genre                                               Album
                    name : String
 Rock                                      1
                    biography : Text               name : String
 Pop                                           *
 Classic            mainGenre : Genre              release : Date
 Blues              founded : Date                 rating : Option[Int]
 Rap                split : Option[Date]
                                                                 1
 HipHop
 Alternative                     *



                                                             *


                             *                             Song
                                                   name : String
                          Person                   duration : Int
                    firstname : String              trackNumber : Int
                    lastname : String
                    biography : Text




                             ©
Mesan
AS
JPA


   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                         ©
Mesan
AS
Vi mapper en sang




   «enumeration»
                          Artist
     Genre

                                                                                                    Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                             name : String
                                                                                             duration : Int
                                                            *


                            *                             Song


                                                                                             trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                ©
Mesan
AS
Vi mapper en sang
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)




   «enumeration»
                          Artist
     Genre

                                                                                                                                      Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                               name : String
                                                                                                                               duration : Int
                                                            *


                            *                             Song


                                                                                                                               trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                     ©
Mesan
AS
Vi mapper en sang
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)


                                                   @Entity
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)




   «enumeration»
                          Artist
     Genre

                                                                                                                                      Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                               name : String
                                                                                                                               duration : Int
                                                            *


                            *                             Song


                                                                                                                               trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                     ©
Mesan
AS
Vi mapper en sang
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)


                                                   @Entity
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)



                                                   @Entity
                                                   class Song(@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id:Int,
                                                              var name:String, var duration:Int, var tracknumber:Int)




   «enumeration»
                          Artist
     Genre

                                                                                                                                      Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                               name : String
                                                                                                                               duration : Int
                                                            *


                            *                             Song


                                                                                                                               trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                     ©
Mesan
AS
Vi mapper en sang
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)


                                                   @Entity
                                                   class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int)



                                                   @Entity
                                                   class Song(@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id:Int,
                                                              var name:String, var duration:Int, var tracknumber:Int)



                                                                          @Entity
                                                                          class Song {
                                                                            @Id
                                                                            @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                            var id : Int = _
                                                                            var name : String = _
                                                                            var duration : Int = _
                                                                            var tracknumber : Int = _
                                                                          }
   «enumeration»
                          Artist
     Genre

                                                                                                                                         Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                                  name : String
                                                                                                                                  duration : Int
                                                            *


                            *                             Song


                                                                                                                                  trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                               ©
Mesan
AS
Et album
                                                                         @Entity
                                                                         class Album {

                                                                             @Id
                                                                             @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                             var id : Int = _
                                                                             var name : String = _
                                                                             @Temporal(value = TemporalType.DATE)
                                                                             var release : Date = _
                                                                             var rating : Int = _
                                                                         }


                                                                                                                                          Album
                                                                                                                                   name : String
                                                                                                                                   release : Date
                                                                                                                                   rating : Option[Int]

                                                                                                                                                 1




                                                                                                                                             *
   «enumeration»
                          Artist
     Genre

                                                                                                                                           Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                                   name : String
                                                                                                                                   duration : Int
                                                            *


                            *                             Song


                                                                                                                                   trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                                ©
Mesan
AS
Et album
                                                                         @Entity
                                                                         class Album {

                                                                             @Id
                                                                             @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                             var id : Int = _
                                                                             var name : String = _
                                                                             @Temporal(value = TemporalType.DATE)
                                                                             var release : Date = _
                                                                             var rating : Int = _
                                                                         }


                                                                                                                                          Album

                                                                               – med sanger                                        name : String
                                                                                                                                   release : Date
                                                                                                                                   rating : Option[Int]

                                                                                                                                                 1
                                                                                     import java.util.{List => jList}

                                                                                     @OneToMany(orphanRemoval = true)
                                                                                     @JoinColumn(name = "album_id")
                                                                                     @OrderBy("tracknumber")                                 *
   «enumeration»
     Genre
                          Artist                                                     var songs : jList[Song] = _
                                                                                                                                           Song
                                                         Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *
                                                                                                                                   name : String
                                                                                                                                   duration : Int
                                                            *


                            *                             Song


                                                                                                                                   trackNumber : Int
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                                ©
Mesan
AS
Artister

                                                                         @Entity
                                                                         class Artist {

                                                                             @Id
                                                                             @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                             var id : Int = _
                                                                             var name : String = _
                                                                             var biography : String = _
                                                                             @Temporal(value = TemporalType.DATE)
                                                                             var founded : Date = _
                                                                         }




   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                                ©
Mesan
AS
@Entity
                                                                             Artister
class Artist {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _
    var name : String = _
    var biography : String = _
    @Temporal(value = TemporalType.DATE)
    var founded : Date = _
}




                                                                             @OneToMany(orphanRemoval = true,
                                                                                        cascade = Array(CascadeType.ALL))
                                                                             @JoinColumn(name = "artist_id")
                                                                             var albums : jList[Album] = _




       «enumeration»
                              Artist
         Genre                                               Album
                       name : String
    Rock                                      1
                       biography : Text               name : String
    Pop                                           *
    Classic            mainGenre : Genre              release : Date
    Blues              founded : Date                 rating : Option[Int]
    Rap                split : Option[Date]
                                                                    1
    HipHop
    Alternative                     *



                                                                *


                                *                             Song
                                                      name : String
                             Person                   duration : Int
                       firstname : String              trackNumber : Int
                       lastname : String
                       biography : Text




                                                                                   ©
Mesan
AS
@Entity
                                                                                  Artister
class Artist {
                                                                                                                   «enumeration»
    @Id                                                                                                              Genre
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _                                                                                            Rock
    var name : String = _                                                                                       Pop
    var biography : String = _                                                                                  Classic
    @Temporal(value = TemporalType.DATE)                                                                        Blues
    var founded : Date = _                                                                                      Rap
}
                                                                                                                HipHop
                                                                                                                Alternative
                       @OneToMany(orphanRemoval = true,
                                  cascade = Array(CascadeType.ALL))
                       @JoinColumn(name = "artist_id")
                       var albums : jList[Album] = _

                                                                                                 object Genre extends Enumeration {
                                                                                                   type Genre = Value

                                                                                                     val   Rock = Value(1)
                                                                                                     val   Pop = Value(2)
                                                                                                     val   Classic = Value(3)
                                                                                                     val   Blues = Value(4)
                                                                                                     val   Rap = Value(5)
                                                                                                     val   HipHop = Value(6)
                                                                                                     val   Alternative = Value(7)
                                                                                                 }




       «enumeration»
                                   Artist
         Genre                                                    Album
                            name : String
    Rock                                           1
                            biography : Text               name : String
    Pop                                                *
    Classic                 mainGenre : Genre              release : Date
    Blues                   founded : Date                 rating : Option[Int]
    Rap                     split : Option[Date]
                                                                         1
    HipHop
    Alternative                          *



                                                                     *


                                     *                             Song
                                                           name : String
                                  Person                   duration : Int
                            firstname : String              trackNumber : Int
                            lastname : String
                            biography : Text




                                                                                    ©
Mesan
AS
@Entity
                                                                                  Artister
class Artist {
                                                                                                                                         «enumeration»
    @Id                                                                                                                                    Genre
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _                                                                                                                  Rock
    var name : String = _                                                                                                             Pop
    var biography : String = _                                                                                                        Classic
    @Temporal(value = TemporalType.DATE)                                                                                              Blues
    var founded : Date = _                                                                                                            Rap
}
                                                                                                                                      HipHop
                                                                                                                                      Alternative
                       @OneToMany(orphanRemoval = true,
                                  cascade = Array(CascadeType.ALL))
                       @JoinColumn(name = "artist_id")
                       var albums : jList[Album] = _

                                                                                                                       object Genre extends Enumeration {
                                                                                                                         type Genre = Value
                                                                                  @Enumerated
                                                                                  var maingenre : Genre = Genre.Rock       val   Rock = Value(1)
                                                                                                                           val   Pop = Value(2)
                                                                                                                           val   Classic = Value(3)
                                                                                                                           val   Blues = Value(4)
                                                                                                                           val   Rap = Value(5)
                                                                                                                           val   HipHop = Value(6)
                                                                                                                           val   Alternative = Value(7)
                                                                                                                       }




       «enumeration»
                                   Artist
         Genre                                                    Album
                            name : String
    Rock                                           1
                            biography : Text               name : String
    Pop                                                *
    Classic                 mainGenre : Genre              release : Date
    Blues                   founded : Date                 rating : Option[Int]
    Rap                     split : Option[Date]
                                                                         1
    HipHop
    Alternative                          *



                                                                     *


                                     *                             Song
                                                           name : String
                                  Person                   duration : Int
                            firstname : String              trackNumber : Int
                            lastname : String
                            biography : Text




                                                                                         ©
Mesan
AS
@Entity
                                                                                             Artister
class Artist {
                                                                                                                                                           «enumeration»
    @Id                                                                                                                                                      Genre
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _                                                                                                                                    Rock
    var name : String = _                                                                                                                               Pop
    var biography : String = _                                                                                                                          Classic
    @Temporal(value = TemporalType.DATE)                                                                                                                Blues
    var founded : Date = _                                                                                                                              Rap
}
                                                                                                                                                        HipHop
                                                                                                                                                        Alternative
                       @OneToMany(orphanRemoval = true,
                                  cascade = Array(CascadeType.ALL))
                       @JoinColumn(name = "artist_id")
                       var albums : jList[Album] = _

                                                                                                                                         object Genre extends Enumeration {
                                                                                  @Converter(name = "GenreConverter",                      type Genre = Value
                                                                                             converterClass = classOf[GenreConverter])
                                                                                  @Convert("GenreConverter")                                 val   Rock = Value(1)
                                                                                  var maingenre : Genre = Genre.Rock                         val   Pop = Value(2)
                                                                                                                                             val   Classic = Value(3)
                                                                                                                                             val   Blues = Value(4)
                                                                                                                                             val   Rap = Value(5)
                                                                                                                                             val   HipHop = Value(6)
                                                                                                                                             val   Alternative = Value(7)
                                                                                                                                         }




       «enumeration»
                                   Artist
         Genre                                                    Album
                            name : String
    Rock                                           1
                            biography : Text               name : String
    Pop                                                *
    Classic                 mainGenre : Genre              release : Date
    Blues                   founded : Date                 rating : Option[Int]
    Rap                     split : Option[Date]
                                                                         1
    HipHop
    Alternative                          *



                                                                     *


                                     *                             Song
                                                           name : String
                                  Person                   duration : Int
                            firstname : String              trackNumber : Int
                            lastname : String
                            biography : Text




                                                                                                       ©
Mesan
AS
Artister med personer


                                                                         @Entity
                                                                         class Person {
                                                                           @Id
                                                                           @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                           var id : Int = _
                                                                           var firstname : String = _
                                                                           var lastname : String = _
                                                                         }




   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                       ©
Mesan
AS
Artister med personer
@Entity
class Artist {
                                                                                                                                @Entity
    @Id                                                                                                                         class Person {
                                                                                                                                  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                                                                                  @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _
                                                                                                                                  var id : Int = _
    var name : String = _
                                                                                                                                  var firstname : String = _
    var biography : String = _
                                                                                                                                  var lastname : String = _
    @Temporal(value = TemporalType.DATE)
                                                                                                                                }
    var founded : Date = _
}




                                                                                    Artist
                                                                                                                       Person
                                                                             name : String
                                                                                                     *
                                                                             biography : Text                    firstname : String
                                                                                                            *
       «enumeration»
         Genre
                              Artist
                       name : String
                                                             Album           mainGenre : Genre                   lastname : String
    Rock                                      1
    Pop
    Classic
                       biography : Text
                       mainGenre : Genre
                       founded : Date
                                                  *
                                                      name : String
                                                      release : Date
                                                      rating : Option[Int]
                                                                             founded : Date                      biography : Text
    Blues
    Rap
    HipHop
    Alternative
                       split : Option[Date]

                                    *
                                                                    1        split : Option[Date]
                                                                *


                                *                             Song
                                                      name : String
                             Person                   duration : Int
                       firstname : String              trackNumber : Int
                       lastname : String
                       biography : Text




                                                                                                    ©
Mesan
AS
Artister med personer
@Entity
class Artist {
                                                                                                                                @Entity
    @Id                                                                                                                         class Person {
                                                                                                                                  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                                                                                  @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _
                                                                                                                                  var id : Int = _
    var name : String = _
                                                                                                                                  var firstname : String = _
    var biography : String = _
                                                                                                                                  var lastname : String = _
    @Temporal(value = TemporalType.DATE)
                                                                                                                                }
    var founded : Date = _
}




            @ManyToMany
            @JoinTable(name = "person_artist",
              joinColumns = Array(new JoinColumn(name = "artist_id")),
              inverseJoinColumns = Array(new JoinColumn(name = "person_id")))
            var persons : jList[Person] = _




                                                                                    Artist
                                                                                                                       Person
                                                                             name : String
                                                                                                     *
                                                                             biography : Text                    firstname : String
                                                                                                            *
       «enumeration»
         Genre
                              Artist
                       name : String
                                                             Album           mainGenre : Genre                   lastname : String
    Rock                                      1
    Pop
    Classic
                       biography : Text
                       mainGenre : Genre
                       founded : Date
                                                  *
                                                      name : String
                                                      release : Date
                                                      rating : Option[Int]
                                                                             founded : Date                      biography : Text
    Blues
    Rap
    HipHop
    Alternative
                       split : Option[Date]

                                    *
                                                                    1        split : Option[Date]
                                                                *


                                *                             Song
                                                      name : String
                             Person                   duration : Int
                       firstname : String              trackNumber : Int
                       lastname : String
                       biography : Text




                                                                                                    ©
Mesan
AS
Artister med personer
@Entity
class Artist {
                                                                                                                                @Entity
    @Id                                                                                                                         class Person {
                                                                                                                                  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                                                                                  @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id : Int = _
                                                                                                                                  var id : Int = _
    var name : String = _
                                                                                                                                  var firstname : String = _
    var biography : String = _
                                                                                                                                  var lastname : String = _
    @Temporal(value = TemporalType.DATE)
                                                                                                                                }
    var founded : Date = _
}




            @ManyToMany
            @JoinTable(name = "person_artist",
                                                                                                                           @ManyToMany(mappedBy = "persons")
              joinColumns = Array(new JoinColumn(name = "artist_id")),
              inverseJoinColumns = Array(new JoinColumn(name = "person_id")))                                              var artists : jList[Artist] = _
            var persons : jList[Person] = _




                                                                                    Artist
                                                                                                                       Person
                                                                             name : String
                                                                                                     *
                                                                             biography : Text                    firstname : String
                                                                                                            *
       «enumeration»
         Genre
                              Artist
                       name : String
                                                             Album           mainGenre : Genre                   lastname : String
    Rock                                      1
    Pop
    Classic
                       biography : Text
                       mainGenre : Genre
                       founded : Date
                                                  *
                                                      name : String
                                                      release : Date
                                                      rating : Option[Int]
                                                                             founded : Date                      biography : Text
    Blues
    Rap
    HipHop
    Alternative
                       split : Option[Date]

                                    *
                                                                    1        split : Option[Date]
                                                                *


                                *                             Song
                                                      name : String
                             Person                   duration : Int
                       firstname : String              trackNumber : Int
                       lastname : String
                       biography : Text




                                                                                                    ©
Mesan
AS
Opplevelsen så langt
•   java
collections
•   ikkeno
Option‐støtte
•   Plagsom
Enum
•   Mer
klønete
bruk
av
annoteringer




                           ©
Mesan
AS
Opplevelsen så langt
•   java
collections
•   ikkeno
Option‐støtte
•   Plagsom
Enum
•   Mer
klønete
bruk
av
annoteringer


•   Føles
ikke
veldig
“Scalash”




                           ©
Mesan
AS
Opplevelsen så langt
•   java
collections
•   ikkeno
Option‐støtte
•   Plagsom
Enum
•   Mer
klønete
bruk
av
annoteringer


•   Føles
ikke
veldig
“Scalash”
•   Javel,
men
vi
prøver
videre
og
bruker
entitetene...



                            ©
Mesan
AS
Insert


def createArtist(em:EntityManager) {
  val a = new Artist
  a.name = "Pink Floyd"
  a.biography = "bla bla bla"
  a.founded = "1965-01-20"
  a.maingenre = Genre.Alternative

    em.persist(a)
}




                                       ©
Mesan
AS
Insert


                                               def createAlbum(em:EntityManager) {
def createArtist(em:EntityManager) {
                                                 val tool = em.find(classOf[Artist], 1001)
  val a = new Artist
  a.name = "Pink Floyd"
                                                    val album = new Album
  a.biography = "bla bla bla"
                                                    album.name = "New one"
  a.founded = "1965-01-20"
                                                    album.release = new Date()
  a.maingenre = Genre.Alternative
                                                    album.rating = 5

    em.persist(a)
                                                    tool.albums.add(album)
}
                                               }




                                       ©
Mesan
AS
Selects
def findArtist(em:EntityManager) = {
  val tool:Artist = em.find(classOf[Artist], 1001)
  tool
}


def findArtistByName(em:EntityManager) = {
  val q = em.createQuery("SELECT a FROM Artist a WHERE a.name = :name", classOf[Artist])
  q.setParameter("name", "Tool")

    val artist = q.getSingleResult
    artist
}


def countArtists(em:EntityManager) = {
  val q = em.createQuery("SELECT COUNT(a) FROM Artist a", classOf[Long])
  val artistCount = q.getSingleResult
  artistCount
}


def findArtists(em:EntityManager) = {
  val q = em.createQuery("SELECT a FROM Artist a WHERE size(a.albums) > 4", classOf[Artist])
  q.getResultList
}




                                              ©
Mesan
AS
Update

                                                 def updateRating(em:EntityManager) {
                                                   val tool = em.find(classOf[Artist], 1001)
def updateArtist(em:EntityManager) {
                                                   for (i <- 0 until tool.albums.size) {
  val tool = em.find(classOf[Artist], 1001)
                                                     val album = tool.albums.get(0)
  tool.name = "Updated..."
                                                     album.rating = 5
}
                                                   }
                                                 }




                                                 def updateRatingByQuery(em:EntityManager) {
                                                   val q = em.createQuery("""
                                                     UPDATE Album a SET rating = 5 WHERE a.id in
                                                     (SELECT album.id FROM Artist art JOIN art.albums album
                                                      WHERE art.id = :id)
                                                     """)
                                                   q.setParameter("id", 1001)
                                                   val up = q.executeUpdate() // up => 4
                                                 }




                                              ©
Mesan
AS
Hva kan vi forbedre?




   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                         ©
Mesan
AS
Hva kan vi forbedre?
                                                                          trait WithID {

                   •         Traits
FTW!                                    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                            var id : Int = _
                                                                          }

                                                                          @Entity
                                                                          class Song extends WithID {
                                                                            var name : String = _
                                                                            var duration : Int = _
                                                                            var tracknumber : Int = _
                                                                          }




   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                         ©
Mesan
AS
Hva kan vi forbedre?
                                                                          trait WithID {

                   •         Traits
FTW!                                    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
                                                                            var id : Int = _
                                                                          }

                                                                          @Entity
                                                                          class Song extends WithID {
                                                                            var name : String = _
                                                                            var duration : Int = _
                                                                            var tracknumber : Int = _
                                                                          }




                                                                         class Album extends WithID {
                                                                           var songs : jList[Song] = _
                   •         Scala
Collections                             def duration : Int = {
                                                                             import scala.collection.JavaConversions._
                                                                             songs.foldLeft(0)(_ + _.duration)
                                                                           }
                                                                         }




   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                         ©
Mesan
AS
ScalaEntityManager
•   Wrapper
rundt
EntityManager
•   I
samme
stil
som
RichInt,
StringOps
etc




                           ©
Mesan
AS
ScalaEntityManager
         •   Wrapper
rundt
EntityManager
         •   I
samme
stil
som
RichInt,
StringOps
etc


public interface EntityManager {
  public <T> T find(Class<T> entityClass, Object primaryKey);
  public Query createQuery(String qlString);                    trait ScalaEntityManager {
  public <T> TypedQuery<T> createQuery(String qlString,           def find[A](clazz: Class[A], id: Any) : Option[A]
                               Class<T> resultClass);             def def createQuery[A](queryString: String) : ScalaQuery[A]
}                                                               }

public interface Query {                                        class   ScalaQuery[A] {
  public List getResultList();                                    def   findAll : Seq[A]
  Object getSingleResult();                                       def   getResultList() : Seq[A]
  Query setParameter(String name, Object value);                  def   findOne : Option[A]
}                                                                 def   setParams(params : Pair[String,Any]*)
public interface TypedQuery<X> extends Query {                  }
  X getSingleResult();
  java.util.List<X> getResultList();
}




                                                        ©
Mesan
AS
Deler av veien, men...




         ©
Mesan
AS
Deler av veien, men...

•   Føler
at
noe
ikke
stemmer
her




                          ©
Mesan
AS
Deler av veien, men...

•   Føler
at
noe
ikke
stemmer
her


•   Får
ikke
utnyttet
mulighetene
i
språket




                           ©
Mesan
AS
Deler av veien, men...

•   Føler
at
noe
ikke
stemmer
her


•   Får
ikke
utnyttet
mulighetene
i
språket


•   Hvorfor
bruke
Scala
i
det
hele
tatt?




                            ©
Mesan
AS
Uklarheter
•   Tung
mental
modell
                                                                                 Id   Name                Location



    •   Object
Relational
Impedence
Mismatch
                                                                                 1    Mesan               Oslo

                                                                                 2    NTNU                Trondheim
                                                                                 3    NITH                Oslo
                                                    Company
                                                name : String                    4    NFR                 Oslo
                                                location : String
                                                                                 5    Sintef              Trondheim




•   Transaksjoner                                        *
                                                     Person
                                                firstname : String
                                                lastname : String
                                                                    Id

                                                                    1
                                                                         Firstname

                                                                         John
                                                                                               Lastname

                                                                                               Doe
                                                                                                             Company

                                                                                                             1

                                                                    2    Jane                  Doe           1
                                                                    3    Peter                 Peterson      2




    •   Hva
endres?
Når
skrives
det
til
base?
                                                                    4    Marky                 Mark          3

                                                                    5    John                  Johnson       2




•   Database‐struktur
styrt
av
JPA?
•   Skjønner
man
datamodellen?
Eller
må
man
lese
JPA‐
    koden
for
å
henge
med?
•   Velge
“eiende”
side
i
relasjoner

                             ©
Mesan
AS
•   Trainwrecks
/
lasting
av
“hele”
basen
•   Traversering
av
objektmodell
    



vs                                                                                            Forretningsprosesser



•   Uthenting
av
små
datasett                                               V1        V2         V3        V4        V5    V6   V7   V8    V9




                                                                                 F1         F2         F3        F4        F5   F6    F7

                Artist
                                               Album
         name : String
                                1
         biography : Text               name : String
         mainGenre : Genre
                                    *
                                        release : Date                                     T1         T2        T3        T4    T5   T6
         founded : Date                 rating : Option[Int]
         split : Option[Date]
                                                      1
                      *



                                                  *


                  *                             Song
                                                                                                                DB
                                        name : String
               Person                   duration : Int
         firstname : String              trackNumber : Int
         lastname : String
         biography : Text


                                                               ©
Mesan
AS
Alternativer




    ©
Mesan
AS
JDBC
                                                                                Rykk
tilbake
til
start!

                                                                         Ingen
hindringer,
ingen
begrensinger
                                                                                       All
makt
   «enumeration»
                          Artist
     Genre                                               Album
                   name : String
Rock                                      1
                   biography : Text               name : String
Pop                                           *
Classic            mainGenre : Genre              release : Date
Blues              founded : Date                 rating : Option[Int]
Rap                split : Option[Date]
                                                                1
HipHop
Alternative                     *



                                                            *


                            *                             Song
                                                  name : String
                         Person                   duration : Int
                   firstname : String              trackNumber : Int
                   lastname : String
                   biography : Text




                                                                                       ©
Mesan
AS
JDBC
•   Direkte
integrasjon
mot
databasen
•   Ingen
avhengigheter,
fundamentalt
i
Java
SE
•   Grunnlaget
for
alle
abstraksjoner




                           ©
Mesan
AS
Modell
                    •          Frie
tøyler!

                   import Genre._

                   class Artist(val name: String, val biography: String,
                                val founded: Date, val split: Option[Date],
                                val mainGenre: Genre, val albums: List[Album] = Nil, val persons: List[Person] = Nil)

                   class Album(val name: String, val release: Date, val rating: Int,
                               val songs: List[Song] = Nil)

                   class Song(val name: String, val duration: Int, val tracknumber: Int)

                   class Person(val firstname: String, val lastname: String,
                                val biography: String)




   «enumeration»
                            Artist
     Genre                                                 Album
                     name : String
Rock                                        1
                     biography : Text               name : String
Pop                                             *
Classic              mainGenre : Genre              release : Date
Blues                founded : Date                 rating : Option[Int]
Rap                  split : Option[Date]
                                                                  1
HipHop
Alternative                       *



                                                              *


                              *                             Song
                                                    name : String
                           Person                   duration : Int
                     firstname : String              trackNumber : Int
                     lastname : String
                     biography : Text




                                                                            ©
Mesan
AS
Insert
def con: Connection
def insertArtist {
  val in = "INSERT INTO ARTISTS(name, biography, founded, maingenre) VALUES (?,?,?,?)"
  val ps = con.prepareStatement(in)
  ps.setString(1, "Tool")
  ps.setString(2, "bla bla bla...")
  ps.setDate(3, Date.valueOf("1990-01-02"))
  ps.setInt(4, Genre.Rock.id)

    ps.executeUpdate()
}




                                                                                         Artist
                                                                                name : String
                                                                                biography : Text
                                                                                mainGenre : Genre
                                                                                founded : Date
                                                                                split : Option[Date]




                                      ©
Mesan
AS
Insert
def con: Connection
def insertArtist {
  val in = "INSERT INTO ARTISTS(name, biography, founded, maingenre) VALUES (?,?,?,?)"
  val ps = con.prepareStatement(in)
  ps.setString(1, "Tool")
  ps.setString(2, "bla bla bla...")
  ps.setDate(3, Date.valueOf("1990-01-02"))
  ps.setInt(4, Genre.Rock.id)

    ps.executeUpdate()
}




def insertAlbum {
  val in = "INSERT INTO ALBUMS(name, release, rating, artist_id) VALUES (?,?,?,?)"
  val ps = con.prepareStatement(in)
  ps.setString(1, "New one")
  ps.setDate(2, Date.valueOf("2011-09-07"))
  ps.setInt(3, 3)
  ps.setInt(4, 1001)
                                                                                         Artist
    ps.executeUpdate()                                                          name : String
}                                                                               biography : Text
                                                                                mainGenre : Genre
                                                                                founded : Date
                                                                                split : Option[Date]




                                      ©
Mesan
AS
Update

def updateArtist {
  val ps = con.prepareStatement("UPDATE ARTISTS SET name = ? WHERE id = ?")
  ps.setString(1, "updated...")
  ps.setInt(2, 1001)
  ps.executeUpdate()
}




                                                                                     Artist
                                                                              name : String
                                                                              biography : Text
                                                                              mainGenre : Genre
                                                                              founded : Date
                                                                              split : Option[Date]




                                          ©
Mesan
AS
Update

def updateArtist {
  val ps = con.prepareStatement("UPDATE ARTISTS SET name = ? WHERE id = ?")
  ps.setString(1, "updated...")
  ps.setInt(2, 1001)
  ps.executeUpdate()
}




def updateAlbums {
  val ps = con.prepareStatement("UPDATE ALBUMS SET rating = ? WHERE artist_id = ?")
  ps.setInt(1, 5)
  ps.setInt(2, 1001)
  ps.executeUpdate()
}

                                                                                             Artist
                                                                                      name : String
                                                                                      biography : Text
                                                                                      mainGenre : Genre
                                                                                      founded : Date
                                                                                      split : Option[Date]




                                          ©
Mesan
AS
Finn én (eller ingen)
def findArtist : Option[Artist] = {
  st = conn.prepareStatement(
    "SELECT id, name, biography, founded, split, maingenre FROM ARTISTS WHERE id=?")

    st.setInt(1, 1001)
    rs = st.executeQuery()
    if (rs.next()) {
      val id = rs.getInt(1)
      val name = rs.getString(2)
      val bio = rs.getString(3)
      val founded = rs.getDate(4)
      val split = rs.getDate(5)
      val splitO = if (split != null) Some(split) else None
      val gen = Genre(rs.getInt(6))

      Some(new Artist(name, bio, founded, splitO, gen))
    } else {
      None
    }
}




                                       ©
Mesan
AS
Finn mange
def findAllArtists : List[Artist] = {
  var res = List[Artist]()

    val st = con.prepareStatement(
      "SELECT id, name, biography, founded, split, maingenre FROM ARTISTS")
    val rs = st.executeQuery()
    while (rs.next()) {
      val name = rs.getString(2)
      val bio = rs.getString(3)
      val founded = rs.getDate(4)
      val split = rs.getDate(5)
      val splitO = if (split != null) Some(split) else None
      val gen = Genre(rs.getInt(6))

     val a = new Artist(name, bio, founded, splitO, gen)
     res ::= a
    }
    res.reverse
}




                                 ©
Mesan
AS
Finn album med sanger
def findAlbum() = {
  val q =
    "
    SELECT a.id, a.name, a.release, a.rating, s.name, s.duration, s.tracknumber
    FROM Albums a JOIN Songs s ON s.album_id = a.id
    WHERE a.id = ?
    ORDER BY s.tracknumber ASC
    "
  val ps = con.prepareStatement(q)
  ps.setInt(1, 1001)
  val rs = ps.executeQuery()
  while (rs.next) {
    // extract song, add to list
    val s = new Song(name, duration, tracknumber)
    songs ::= a
  }
  // extract album from last row, add songs to artist
  new Album(name, release, rating, songs)
}




                                  ©
Mesan
AS
Oppsiden
•   Full
kontroll
på
all
SQL
    •   Hvilken
SQL
som
kjøres
    •   Når
den
kjøres
•   Full
valgfrihet
i
modellering
av
data
    •   class,
case
class,
Option[]
etc
    •   Tilgang
til
alt
vi
ønsker
oss




                               ©
Mesan
AS
What´s the catch?




       ©
Mesan
AS
What´s the catch?
•   boilerplate




                  ©
Mesan
AS
What´s the catch?
                                                    var conn : Connection = null
•   boilerplate                                     var st : PreparedStatement = null
                                                    try {
                                                      conn = con
                                                      st = conn.prepareStatement("SQL here")
                                                      // do something SQLy
                                                    } finally {
                                                      st.close()
                                                      conn.close()
         if (rs.next()) {
                                                    }
           // do something with resultset
         }                                                              st.setInt(1, 1)
         while (rs.next()) {                                            st.setXXX
           // do something with resultset
         }                                                              rs.getInt(1)
                                                                        rs.getString(2)
                                                                        rs.getXxx(3)




                                       ©
Mesan
AS
What´s the catch?
                                                     var conn : Connection = null
•   boilerplate                                      var st : PreparedStatement = null
                                                     try {
                                                       conn = con
                                                       st = conn.prepareStatement("SQL here")
                                                       // do something SQLy
                                                     } finally {
                                                       st.close()
                                                       conn.close()
          if (rs.next()) {
                                                     }
            // do something with resultset
          }                                                              st.setInt(1, 1)
          while (rs.next()) {                                            st.setXXX
            // do something with resultset
          }                                                              rs.getInt(1)
                                                                         rs.getString(2)
                                                                         rs.getXxx(3)




•   Lock‐in
mot
database‐leverandør
•   Lav‐nivå
API
å
forholde
seg
til
•   Håndkoding
av
all
SQL

                                        ©
Mesan
AS
RichSQL
 Kan
det
fikses?

 Klart
det
kan!




    ©
Mesan
AS
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala
Persistens i scala

Contenu connexe

En vedette

7 Google Similar Pages
7 Google Similar Pages7 Google Similar Pages
7 Google Similar Pagesaptwano
 
5 Google Maps
5 Google Maps5 Google Maps
5 Google Mapsaptwano
 
7 Google Similar Pages
7 Google Similar Pages7 Google Similar Pages
7 Google Similar Pagesaptwano
 
1 Comprehension Skills
1 Comprehension Skills1 Comprehension Skills
1 Comprehension Skillsaptwano
 
014 Common Errors
014 Common Errors014 Common Errors
014 Common Errorsaptwano
 
Expiration Guidelines
Expiration GuidelinesExpiration Guidelines
Expiration Guidelinesaptwano
 
En nybegynners introduksjon til scalaz
En nybegynners introduksjon til scalazEn nybegynners introduksjon til scalaz
En nybegynners introduksjon til scalazTrond Marius Øvstetun
 
010 Verbals
010 Verbals010 Verbals
010 Verbalsaptwano
 
Digital Out Of Home: The state of the industry today and tomorrow
Digital Out Of Home: The state of the industry today and tomorrowDigital Out Of Home: The state of the industry today and tomorrow
Digital Out Of Home: The state of the industry today and tomorrowDigital Signage Today
 
李普曼:公众舆论
李普曼:公众舆论李普曼:公众舆论
李普曼:公众舆论guesta57064b
 
Gdg using docker to streamline development
Gdg using docker to streamline developmentGdg using docker to streamline development
Gdg using docker to streamline developmentTrond Marius Øvstetun
 
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...Priscila de Oliveira
 
5e Sticker 60,6 cm x 25,6 cm met tekentjes
5e Sticker 60,6 cm x 25,6 cm met tekentjes5e Sticker 60,6 cm x 25,6 cm met tekentjes
5e Sticker 60,6 cm x 25,6 cm met tekentjesLaila Kühnen
 
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...Priscila de Oliveira
 
Investieren in der Region Quebec
Investieren in der Region QuebecInvestieren in der Region Quebec
Investieren in der Region QuebecUniversité Laval
 

En vedette (20)

7 Google Similar Pages
7 Google Similar Pages7 Google Similar Pages
7 Google Similar Pages
 
5 Google Maps
5 Google Maps5 Google Maps
5 Google Maps
 
7 Google Similar Pages
7 Google Similar Pages7 Google Similar Pages
7 Google Similar Pages
 
1 Comprehension Skills
1 Comprehension Skills1 Comprehension Skills
1 Comprehension Skills
 
014 Common Errors
014 Common Errors014 Common Errors
014 Common Errors
 
Expiration Guidelines
Expiration GuidelinesExpiration Guidelines
Expiration Guidelines
 
En nybegynners introduksjon til scalaz
En nybegynners introduksjon til scalazEn nybegynners introduksjon til scalaz
En nybegynners introduksjon til scalaz
 
Italia
ItaliaItalia
Italia
 
010 Verbals
010 Verbals010 Verbals
010 Verbals
 
Digital Out Of Home: The state of the industry today and tomorrow
Digital Out Of Home: The state of the industry today and tomorrowDigital Out Of Home: The state of the industry today and tomorrow
Digital Out Of Home: The state of the industry today and tomorrow
 
李普曼:公众舆论
李普曼:公众舆论李普曼:公众舆论
李普曼:公众舆论
 
Gdg using docker to streamline development
Gdg using docker to streamline developmentGdg using docker to streamline development
Gdg using docker to streamline development
 
Verjaardagskaart
VerjaardagskaartVerjaardagskaart
Verjaardagskaart
 
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...
TEOR DE FENÓLICOS E ATIVIDADE ANTIOXIDANTE DE TORTILHAS PRODUZIDAS A PARTIR D...
 
Máy bắt vít dùng pin btd147 z introduction manual
Máy bắt vít dùng pin btd147 z   introduction manualMáy bắt vít dùng pin btd147 z   introduction manual
Máy bắt vít dùng pin btd147 z introduction manual
 
Cuadros de cartografia y constelaciones
Cuadros de cartografia y constelacionesCuadros de cartografia y constelaciones
Cuadros de cartografia y constelaciones
 
5e Sticker 60,6 cm x 25,6 cm met tekentjes
5e Sticker 60,6 cm x 25,6 cm met tekentjes5e Sticker 60,6 cm x 25,6 cm met tekentjes
5e Sticker 60,6 cm x 25,6 cm met tekentjes
 
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...
ALFA-TOCOFEROL E BETA-CAROTENO EM VOLUMOSOS E LEITE EM REBANHOS LEITEIROS ORG...
 
Máy bắt vít dùng pin dtd137 rfe introduction manual
Máy bắt vít dùng pin dtd137 rfe introduction manualMáy bắt vít dùng pin dtd137 rfe introduction manual
Máy bắt vít dùng pin dtd137 rfe introduction manual
 
Investieren in der Region Quebec
Investieren in der Region QuebecInvestieren in der Region Quebec
Investieren in der Region Quebec
 

Similaire à Persistens i scala

CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodecamp Romania
 
public class Person { private String name; private int age;.pdf
public class Person { private String name; private int age;.pdfpublic class Person { private String name; private int age;.pdf
public class Person { private String name; private int age;.pdfarjuncp10
 
Coffee Scriptでenchant.js
Coffee Scriptでenchant.jsCoffee Scriptでenchant.js
Coffee Scriptでenchant.jsNaoyuki Totani
 

Similaire à Persistens i scala (10)

CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
 
The Groovy Way
The Groovy WayThe Groovy Way
The Groovy Way
 
F# for C# Programmers
F# for C# ProgrammersF# for C# Programmers
F# for C# Programmers
 
C# 6.0
C# 6.0C# 6.0
C# 6.0
 
public class Person { private String name; private int age;.pdf
public class Person { private String name; private int age;.pdfpublic class Person { private String name; private int age;.pdf
public class Person { private String name; private int age;.pdf
 
Coffee Scriptでenchant.js
Coffee Scriptでenchant.jsCoffee Scriptでenchant.js
Coffee Scriptでenchant.js
 
Java 8 Examples
Java 8 ExamplesJava 8 Examples
Java 8 Examples
 
Kick Start Jpa
Kick Start JpaKick Start Jpa
Kick Start Jpa
 
Class 3 2ciclo
Class 3 2cicloClass 3 2ciclo
Class 3 2ciclo
 
Class 3 2ciclo
Class 3 2cicloClass 3 2ciclo
Class 3 2ciclo
 

Dernier

A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 

Dernier (20)

A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

Persistens i scala

  • 1. Persistens i Scala JavaZone
X Trond
Marius
Øvstetun ©
Mesan
AS
  • 2. Agenda • Sette
fokus
på
persistens‐laget • Det
finnes
mange
alternativer! • En
liten
introduksjon ©
Mesan
AS
  • 3. Agenda • Sette
fokus
på
persistens‐laget • Det
finnes
mange
alternativer! • En
liten
introduksjon • Tenke
seg
om
i
de
valgene
man
gjør ©
Mesan
AS
  • 4. Trond Marius Øvstetun • Seniorkonsulent
og
 fagleder
i
Mesan • Lidenskapelig
utvikler,
 arkitekt,
teamleder
++ • Java,
Scala,
HTML/js • Alltid
på
jakt
etter
bedre,
 enklere
måter ©
Mesan
AS
  • 5. Mesan ...
når
standardsystemer
ikke
er
nok • Systemutvikling
–
skreddersøm • Løsningsfokus • “Store”
systemer • Transaksjonssystemer ©
Mesan
AS
  • 6. Mesan ...
når
standardsystemer
ikke
er
nok • Systemutvikling
–
skreddersøm • Løsningsfokus • “Store”
systemer • Transaksjonssystemer • Lang
levetid
–
langsiktighet ©
Mesan
AS
  • 8. Systemer i endring V1 V2 V3 V4 V5 V6 DB ©
Mesan
AS
  • 9. Systemer i endring Forretningsprosesser V1 V2 V3 V4 V5 V6 DB ©
Mesan
AS
  • 10. Systemer i endring Forretningsprosesser V1 V2 V3 V4 V5 V6 V7 T1 T2 T3 T4 T5 T6 DB ©
Mesan
AS
  • 11. Systemer i endring Forretningsprosesser V1 V2 V3 V4 V5 V6 V7 T1 T2 T3 T4 T5 T6 Teknologi DB ©
Mesan
AS
  • 12. Systemer i endring Forretningsprosesser V1 V2 V3 V4 V5 V6 V7 V8 V9 F1 F2 F3 F4 F5 F6 F7 T1 T2 T3 T4 T5 T6 DB ©
Mesan
AS
  • 13. Java -> Scala Teknologien
driver
oss Hva
man
sitter
igjen
med
etter
introduksjonen... ©
Mesan
AS
  • 14. De
fleste
som
prøver
Scala
har
bakgrunn
fra
Java • Innarbeidede
rutiner,
forventninger,
perferanser,
 tankesett,
rammeverk
etc • Objektorientert? • Transaksjonsskript? ©
Mesan
AS
  • 15. Person firstname : String lastname : String birthDate : Date gender : Gender ©
Mesan
AS
  • 16. public class Person { private String firstname; private String lastname; private Date birthDate; private Gender gender; public Person(String firstname, String lastname, Gender gender, Date birthDate) { this.firstname = firstname; this.lastname = lastname; this.gender = gender; this.birthDate = birthDate; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public Date getBirthDate() { Person return birthDate; } firstname : String public void setBirthDate(Date birthDate) { lastname : String this.birthDate = birthDate; } birthDate : Date gender : Gender public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } } ©
Mesan
AS
  • 17. public class Person { private String firstname; private String lastname; private Date birthDate; private Gender gender; public Person(String firstname, String lastname, Gender gender, Date birthDate) { this.firstname = firstname; this.lastname = lastname; this.gender = gender; this.birthDate = birthDate; } public String getFirstname() { return firstname; } class Person(var firstname:String, var lastname:String, public void setFirstname(String firstname) { this.firstname = firstname; var gender:Gender, var birthdate:Date) } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public Date getBirthDate() { Person return birthDate; } firstname : String public void setBirthDate(Date birthDate) { lastname : String this.birthDate = birthDate; } birthDate : Date gender : Gender public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } } ©
Mesan
AS
  • 18. null? Nei takk • Option[T] • Some
–
innhold • None ©
Mesan
AS
  • 19. null? Nei takk • Option[T] • Some
–
innhold class Person(var firstname:String, var lastname:String, var gender:Gender, var birthdate:Option[Date] = None) • None ©
Mesan
AS
  • 20. null? Nei takk • Option[T] • Some
–
innhold class Person(var firstname:String, var lastname:String, var gender:Gender, var birthdate:Option[Date] = None) • None interface PersonRepository { /** * @return A person if found, <code>null</code> otherwise. */ Person findById(int id); } PersonRepository repo; Person person = repo.findById(1); if (person != null) { person.updateThySelf(); } PersonRepository repo; Person person = repo.findById(1); if (person != null) { return person.firstname + " " + person.lastname; } else { return "John Doe" } ©
Mesan
AS
  • 21. null? Nei takk • Option[T] • Some
–
innhold class Person(var firstname:String, var lastname:String, var gender:Gender, var birthdate:Option[Date] = None) • None interface PersonRepository { /** * @return A person if found, <code>null</code> otherwise. trait PersonRepository { */ def findById(id:Int) : Option[Person] Person findById(int id); } } PersonRepository repo; Person person = repo.findById(1); val repo:PersonRepository if (person != null) { val p = repo.findById(1) person.updateThySelf(); for (person <- p) { } person.updateThySelf() } PersonRepository repo; Person person = repo.findById(1); val repo:PersonRepository if (person != null) { val p = repo.findById(1) return person.firstname + " " + person.lastname; p.map(person => } else { person.firstname + " " + person.lastname) return "John Doe" .getOrElse("John Doe") } ©
Mesan
AS
  • 22. Statisk, men “dynamisk” • Scala
er
utvidbart "(d)*".r => Regex "123".toInt => Int(123) • “Pimp
My
Library” "hello %s".format("world") => String("hello world") "hello".capitalize => "Hello" • Utvider
vanlige
klasser
 med
metoder 1 to 10 => Range(1, 10) 1 until 10 => Range(1, 9) • Mye
i
vanlige
bibliotek ©
Mesan
AS
  • 23. Statisk, men “dynamisk” • Scala
er
utvidbart "(d)*".r => Regex "123".toInt => Int(123) • “Pimp
My
Library” "hello %s".format("world") => String("hello world") "hello".capitalize => "Hello" • Utvider
vanlige
klasser
 med
metoder 1 to 10 => Range(1, 10) 1 until 10 => Range(1, 9) • Mye
i
vanlige
bibliotek implicit def strToFoo(in:String) : Foo = new Foo(in) class Foo(f:String) { def bar = f + "bar" • Roll
your
own! } "foo".bar => "foobar" ©
Mesan
AS
  • 24. Avanserte strukturer val persons = List(Person("Per"), Person("Pål"), Person("Espen")) val (lucky, unlucky) = persons.partition(_.name == "Espen") val fullnames = persons.map(_.name + " Askeladd") for (n <- fullnames) { println(n) } ©
Mesan
AS
  • 25. Avanserte strukturer val persons = List(Person("Per"), Person("Pål"), Person("Espen")) val (lucky, unlucky) = persons.partition(_.name == "Espen") • Scala
collections
er
 val fullnames = persons.map(_.name + " Askeladd") kraftig
kost for (n <- fullnames) { println(n) } ©
Mesan
AS
  • 26. Avanserte strukturer val persons = List(Person("Per"), Person("Pål"), Person("Espen")) val (lucky, unlucky) = persons.partition(_.name == "Espen") • Scala
collections
er
 val fullnames = persons.map(_.name + " Askeladd") kraftig
kost for (n <- fullnames) { println(n) } • Tuppler val navn = ("Trond Marius", "Øvstetun") ©
Mesan
AS
  • 27. Avanserte strukturer val persons = List(Person("Per"), Person("Pål"), Person("Espen")) val (lucky, unlucky) = persons.partition(_.name == "Espen") • Scala
collections
er
 val fullnames = persons.map(_.name + " Askeladd") kraftig
kost for (n <- fullnames) { println(n) } • Tuppler val navn = ("Trond Marius", "Øvstetun") case class MyVal(s:String) def myMatch(n:Any) : String = { n match { • Pattern
matching
 case 1 => "ONE" case n:Int if n < 10 => "low..." ruler! case n:Int if n > 10 => "high!" case p:Person => "a person: " + p.firstname case MyVal(s) => s } } ©
Mesan
AS
  • 28. Objekter? Funksjoner? • Høyereordens
funksjoner
–
gjenbruk
og
abstraksjon • Immutable
datastrukturer
–
sikkerhet • case
class
‐>
copy(...) • Minimalisere
API
og
API‐bruk,
spesialisere
tjenester • Klar
og
konsistent
kode ©
Mesan
AS
  • 29. The selling point “Slapp
av
–
Alle
java‐biblioteker
og
APIer fungerer
med
Scala!” ©
Mesan
AS
  • 30. The selling point “Slapp
av
–
Alle
java‐biblioteker
og
APIer fungerer
med
Scala!” Men
er
det
så
enkelt? ©
Mesan
AS
  • 31. En typisk applikasjon Brukergrensesnitt Visningslogikk Forretningslogikk Data aksess DB ©
Mesan
AS
  • 32. En typisk applikasjon Brukergrensesnitt Visningslogikk Domene Forretningslogikk Data aksess DB ©
Mesan
AS
  • 33. En typisk java- HTML / Javascript Spring MVC @Controller @Entity JPA Spring @Service Spring / JPA @Repository DB ©
Mesan
AS
  • 34. En enkel datamodell «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 35. JPA «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 36. Vi mapper en sang «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 37. Vi mapper en sang class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 38. Vi mapper en sang class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 39. Vi mapper en sang class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song(@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id:Int, var name:String, var duration:Int, var tracknumber:Int) «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 40. Vi mapper en sang class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song(var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song(@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id:Int, var name:String, var duration:Int, var tracknumber:Int) @Entity class Song { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var name : String = _ var duration : Int = _ var tracknumber : Int = _ } «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 41. Et album @Entity class Album { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var name : String = _ @Temporal(value = TemporalType.DATE) var release : Date = _ var rating : Int = _ } Album name : String release : Date rating : Option[Int] 1 * «enumeration» Artist Genre Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 42. Et album @Entity class Album { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var name : String = _ @Temporal(value = TemporalType.DATE) var release : Date = _ var rating : Int = _ } Album – med sanger name : String release : Date rating : Option[Int] 1 import java.util.{List => jList} @OneToMany(orphanRemoval = true) @JoinColumn(name = "album_id") @OrderBy("tracknumber") * «enumeration» Genre Artist var songs : jList[Song] = _ Song Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * name : String duration : Int * * Song trackNumber : Int name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 43. Artister @Entity class Artist { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var name : String = _ var biography : String = _ @Temporal(value = TemporalType.DATE) var founded : Date = _ } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 44. @Entity Artister class Artist { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var name : String = _ var biography : String = _ @Temporal(value = TemporalType.DATE) var founded : Date = _ } @OneToMany(orphanRemoval = true, cascade = Array(CascadeType.ALL)) @JoinColumn(name = "artist_id") var albums : jList[Album] = _ «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 45. @Entity Artister class Artist { «enumeration» @Id Genre @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ Rock var name : String = _ Pop var biography : String = _ Classic @Temporal(value = TemporalType.DATE) Blues var founded : Date = _ Rap } HipHop Alternative @OneToMany(orphanRemoval = true, cascade = Array(CascadeType.ALL)) @JoinColumn(name = "artist_id") var albums : jList[Album] = _ object Genre extends Enumeration { type Genre = Value val Rock = Value(1) val Pop = Value(2) val Classic = Value(3) val Blues = Value(4) val Rap = Value(5) val HipHop = Value(6) val Alternative = Value(7) } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 46. @Entity Artister class Artist { «enumeration» @Id Genre @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ Rock var name : String = _ Pop var biography : String = _ Classic @Temporal(value = TemporalType.DATE) Blues var founded : Date = _ Rap } HipHop Alternative @OneToMany(orphanRemoval = true, cascade = Array(CascadeType.ALL)) @JoinColumn(name = "artist_id") var albums : jList[Album] = _ object Genre extends Enumeration { type Genre = Value @Enumerated var maingenre : Genre = Genre.Rock val Rock = Value(1) val Pop = Value(2) val Classic = Value(3) val Blues = Value(4) val Rap = Value(5) val HipHop = Value(6) val Alternative = Value(7) } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 47. @Entity Artister class Artist { «enumeration» @Id Genre @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ Rock var name : String = _ Pop var biography : String = _ Classic @Temporal(value = TemporalType.DATE) Blues var founded : Date = _ Rap } HipHop Alternative @OneToMany(orphanRemoval = true, cascade = Array(CascadeType.ALL)) @JoinColumn(name = "artist_id") var albums : jList[Album] = _ object Genre extends Enumeration { @Converter(name = "GenreConverter", type Genre = Value converterClass = classOf[GenreConverter]) @Convert("GenreConverter") val Rock = Value(1) var maingenre : Genre = Genre.Rock val Pop = Value(2) val Classic = Value(3) val Blues = Value(4) val Rap = Value(5) val HipHop = Value(6) val Alternative = Value(7) } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 48. Artister med personer @Entity class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var firstname : String = _ var lastname : String = _ } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 49. Artister med personer @Entity class Artist { @Entity @Id class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var id : Int = _ var name : String = _ var firstname : String = _ var biography : String = _ var lastname : String = _ @Temporal(value = TemporalType.DATE) } var founded : Date = _ } Artist Person name : String * biography : Text firstname : String * «enumeration» Genre Artist name : String Album mainGenre : Genre lastname : String Rock 1 Pop Classic biography : Text mainGenre : Genre founded : Date * name : String release : Date rating : Option[Int] founded : Date biography : Text Blues Rap HipHop Alternative split : Option[Date] * 1 split : Option[Date] * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 50. Artister med personer @Entity class Artist { @Entity @Id class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var id : Int = _ var name : String = _ var firstname : String = _ var biography : String = _ var lastname : String = _ @Temporal(value = TemporalType.DATE) } var founded : Date = _ } @ManyToMany @JoinTable(name = "person_artist", joinColumns = Array(new JoinColumn(name = "artist_id")), inverseJoinColumns = Array(new JoinColumn(name = "person_id"))) var persons : jList[Person] = _ Artist Person name : String * biography : Text firstname : String * «enumeration» Genre Artist name : String Album mainGenre : Genre lastname : String Rock 1 Pop Classic biography : Text mainGenre : Genre founded : Date * name : String release : Date rating : Option[Int] founded : Date biography : Text Blues Rap HipHop Alternative split : Option[Date] * 1 split : Option[Date] * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 51. Artister med personer @Entity class Artist { @Entity @Id class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ var id : Int = _ var name : String = _ var firstname : String = _ var biography : String = _ var lastname : String = _ @Temporal(value = TemporalType.DATE) } var founded : Date = _ } @ManyToMany @JoinTable(name = "person_artist", @ManyToMany(mappedBy = "persons") joinColumns = Array(new JoinColumn(name = "artist_id")), inverseJoinColumns = Array(new JoinColumn(name = "person_id"))) var artists : jList[Artist] = _ var persons : jList[Person] = _ Artist Person name : String * biography : Text firstname : String * «enumeration» Genre Artist name : String Album mainGenre : Genre lastname : String Rock 1 Pop Classic biography : Text mainGenre : Genre founded : Date * name : String release : Date rating : Option[Int] founded : Date biography : Text Blues Rap HipHop Alternative split : Option[Date] * 1 split : Option[Date] * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 52. Opplevelsen så langt • java
collections • ikkeno
Option‐støtte • Plagsom
Enum • Mer
klønete
bruk
av
annoteringer ©
Mesan
AS
  • 53. Opplevelsen så langt • java
collections • ikkeno
Option‐støtte • Plagsom
Enum • Mer
klønete
bruk
av
annoteringer • Føles
ikke
veldig
“Scalash” ©
Mesan
AS
  • 54. Opplevelsen så langt • java
collections • ikkeno
Option‐støtte • Plagsom
Enum • Mer
klønete
bruk
av
annoteringer • Føles
ikke
veldig
“Scalash” • Javel,
men
vi
prøver
videre
og
bruker
entitetene... ©
Mesan
AS
  • 55. Insert def createArtist(em:EntityManager) { val a = new Artist a.name = "Pink Floyd" a.biography = "bla bla bla" a.founded = "1965-01-20" a.maingenre = Genre.Alternative em.persist(a) } ©
Mesan
AS
  • 56. Insert def createAlbum(em:EntityManager) { def createArtist(em:EntityManager) { val tool = em.find(classOf[Artist], 1001) val a = new Artist a.name = "Pink Floyd" val album = new Album a.biography = "bla bla bla" album.name = "New one" a.founded = "1965-01-20" album.release = new Date() a.maingenre = Genre.Alternative album.rating = 5 em.persist(a) tool.albums.add(album) } } ©
Mesan
AS
  • 57. Selects def findArtist(em:EntityManager) = { val tool:Artist = em.find(classOf[Artist], 1001) tool } def findArtistByName(em:EntityManager) = { val q = em.createQuery("SELECT a FROM Artist a WHERE a.name = :name", classOf[Artist]) q.setParameter("name", "Tool") val artist = q.getSingleResult artist } def countArtists(em:EntityManager) = { val q = em.createQuery("SELECT COUNT(a) FROM Artist a", classOf[Long]) val artistCount = q.getSingleResult artistCount } def findArtists(em:EntityManager) = { val q = em.createQuery("SELECT a FROM Artist a WHERE size(a.albums) > 4", classOf[Artist]) q.getResultList } ©
Mesan
AS
  • 58. Update def updateRating(em:EntityManager) { val tool = em.find(classOf[Artist], 1001) def updateArtist(em:EntityManager) { for (i <- 0 until tool.albums.size) { val tool = em.find(classOf[Artist], 1001) val album = tool.albums.get(0) tool.name = "Updated..." album.rating = 5 } } } def updateRatingByQuery(em:EntityManager) { val q = em.createQuery(""" UPDATE Album a SET rating = 5 WHERE a.id in (SELECT album.id FROM Artist art JOIN art.albums album WHERE art.id = :id) """) q.setParameter("id", 1001) val up = q.executeUpdate() // up => 4 } ©
Mesan
AS
  • 59. Hva kan vi forbedre? «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 60. Hva kan vi forbedre? trait WithID { • Traits
FTW! @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ } @Entity class Song extends WithID { var name : String = _ var duration : Int = _ var tracknumber : Int = _ } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 61. Hva kan vi forbedre? trait WithID { • Traits
FTW! @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id : Int = _ } @Entity class Song extends WithID { var name : String = _ var duration : Int = _ var tracknumber : Int = _ } class Album extends WithID { var songs : jList[Song] = _ • Scala
Collections def duration : Int = { import scala.collection.JavaConversions._ songs.foldLeft(0)(_ + _.duration) } } «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 62. ScalaEntityManager • Wrapper
rundt
EntityManager • I
samme
stil
som
RichInt,
StringOps
etc ©
Mesan
AS
  • 63. ScalaEntityManager • Wrapper
rundt
EntityManager • I
samme
stil
som
RichInt,
StringOps
etc public interface EntityManager { public <T> T find(Class<T> entityClass, Object primaryKey); public Query createQuery(String qlString); trait ScalaEntityManager { public <T> TypedQuery<T> createQuery(String qlString, def find[A](clazz: Class[A], id: Any) : Option[A] Class<T> resultClass); def def createQuery[A](queryString: String) : ScalaQuery[A] } } public interface Query { class ScalaQuery[A] { public List getResultList(); def findAll : Seq[A] Object getSingleResult(); def getResultList() : Seq[A] Query setParameter(String name, Object value); def findOne : Option[A] } def setParams(params : Pair[String,Any]*) public interface TypedQuery<X> extends Query { } X getSingleResult(); java.util.List<X> getResultList(); } ©
Mesan
AS
  • 64. Deler av veien, men... ©
Mesan
AS
  • 65. Deler av veien, men... • Føler
at
noe
ikke
stemmer
her ©
Mesan
AS
  • 66. Deler av veien, men... • Føler
at
noe
ikke
stemmer
her • Får
ikke
utnyttet
mulighetene
i
språket ©
Mesan
AS
  • 67. Deler av veien, men... • Føler
at
noe
ikke
stemmer
her • Får
ikke
utnyttet
mulighetene
i
språket • Hvorfor
bruke
Scala
i
det
hele
tatt? ©
Mesan
AS
  • 68. Uklarheter • Tung
mental
modell Id Name Location • Object
Relational
Impedence
Mismatch 1 Mesan Oslo 2 NTNU Trondheim 3 NITH Oslo Company name : String 4 NFR Oslo location : String 5 Sintef Trondheim • Transaksjoner * Person firstname : String lastname : String Id 1 Firstname John Lastname Doe Company 1 2 Jane Doe 1 3 Peter Peterson 2 • Hva
endres?
Når
skrives
det
til
base? 4 Marky Mark 3 5 John Johnson 2 • Database‐struktur
styrt
av
JPA? • Skjønner
man
datamodellen?
Eller
må
man
lese
JPA‐ koden
for
å
henge
med? • Velge
“eiende”
side
i
relasjoner ©
Mesan
AS
  • 69. Trainwrecks
/
lasting
av
“hele”
basen • Traversering
av
objektmodell 



vs Forretningsprosesser • Uthenting
av
små
datasett V1 V2 V3 V4 V5 V6 V7 V8 V9 F1 F2 F3 F4 F5 F6 F7 Artist Album name : String 1 biography : Text name : String mainGenre : Genre * release : Date T1 T2 T3 T4 T5 T6 founded : Date rating : Option[Int] split : Option[Date] 1 * * * Song DB name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 70. Alternativer ©
Mesan
AS
  • 71. JDBC Rykk
tilbake
til
start! Ingen
hindringer,
ingen
begrensinger All
makt «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 72. JDBC • Direkte
integrasjon
mot
databasen • Ingen
avhengigheter,
fundamentalt
i
Java
SE • Grunnlaget
for
alle
abstraksjoner ©
Mesan
AS
  • 73. Modell • Frie
tøyler! import Genre._ class Artist(val name: String, val biography: String, val founded: Date, val split: Option[Date], val mainGenre: Genre, val albums: List[Album] = Nil, val persons: List[Person] = Nil) class Album(val name: String, val release: Date, val rating: Int, val songs: List[Song] = Nil) class Song(val name: String, val duration: Int, val tracknumber: Int) class Person(val firstname: String, val lastname: String, val biography: String) «enumeration» Artist Genre Album name : String Rock 1 biography : Text name : String Pop * Classic mainGenre : Genre release : Date Blues founded : Date rating : Option[Int] Rap split : Option[Date] 1 HipHop Alternative * * * Song name : String Person duration : Int firstname : String trackNumber : Int lastname : String biography : Text ©
Mesan
AS
  • 74. Insert def con: Connection def insertArtist { val in = "INSERT INTO ARTISTS(name, biography, founded, maingenre) VALUES (?,?,?,?)" val ps = con.prepareStatement(in) ps.setString(1, "Tool") ps.setString(2, "bla bla bla...") ps.setDate(3, Date.valueOf("1990-01-02")) ps.setInt(4, Genre.Rock.id) ps.executeUpdate() } Artist name : String biography : Text mainGenre : Genre founded : Date split : Option[Date] ©
Mesan
AS
  • 75. Insert def con: Connection def insertArtist { val in = "INSERT INTO ARTISTS(name, biography, founded, maingenre) VALUES (?,?,?,?)" val ps = con.prepareStatement(in) ps.setString(1, "Tool") ps.setString(2, "bla bla bla...") ps.setDate(3, Date.valueOf("1990-01-02")) ps.setInt(4, Genre.Rock.id) ps.executeUpdate() } def insertAlbum { val in = "INSERT INTO ALBUMS(name, release, rating, artist_id) VALUES (?,?,?,?)" val ps = con.prepareStatement(in) ps.setString(1, "New one") ps.setDate(2, Date.valueOf("2011-09-07")) ps.setInt(3, 3) ps.setInt(4, 1001) Artist ps.executeUpdate() name : String } biography : Text mainGenre : Genre founded : Date split : Option[Date] ©
Mesan
AS
  • 76. Update def updateArtist { val ps = con.prepareStatement("UPDATE ARTISTS SET name = ? WHERE id = ?") ps.setString(1, "updated...") ps.setInt(2, 1001) ps.executeUpdate() } Artist name : String biography : Text mainGenre : Genre founded : Date split : Option[Date] ©
Mesan
AS
  • 77. Update def updateArtist { val ps = con.prepareStatement("UPDATE ARTISTS SET name = ? WHERE id = ?") ps.setString(1, "updated...") ps.setInt(2, 1001) ps.executeUpdate() } def updateAlbums { val ps = con.prepareStatement("UPDATE ALBUMS SET rating = ? WHERE artist_id = ?") ps.setInt(1, 5) ps.setInt(2, 1001) ps.executeUpdate() } Artist name : String biography : Text mainGenre : Genre founded : Date split : Option[Date] ©
Mesan
AS
  • 78. Finn én (eller ingen) def findArtist : Option[Artist] = { st = conn.prepareStatement( "SELECT id, name, biography, founded, split, maingenre FROM ARTISTS WHERE id=?") st.setInt(1, 1001) rs = st.executeQuery() if (rs.next()) { val id = rs.getInt(1) val name = rs.getString(2) val bio = rs.getString(3) val founded = rs.getDate(4) val split = rs.getDate(5) val splitO = if (split != null) Some(split) else None val gen = Genre(rs.getInt(6)) Some(new Artist(name, bio, founded, splitO, gen)) } else { None } } ©
Mesan
AS
  • 79. Finn mange def findAllArtists : List[Artist] = { var res = List[Artist]() val st = con.prepareStatement( "SELECT id, name, biography, founded, split, maingenre FROM ARTISTS") val rs = st.executeQuery() while (rs.next()) { val name = rs.getString(2) val bio = rs.getString(3) val founded = rs.getDate(4) val split = rs.getDate(5) val splitO = if (split != null) Some(split) else None val gen = Genre(rs.getInt(6)) val a = new Artist(name, bio, founded, splitO, gen) res ::= a } res.reverse } ©
Mesan
AS
  • 80. Finn album med sanger def findAlbum() = { val q = " SELECT a.id, a.name, a.release, a.rating, s.name, s.duration, s.tracknumber FROM Albums a JOIN Songs s ON s.album_id = a.id WHERE a.id = ? ORDER BY s.tracknumber ASC " val ps = con.prepareStatement(q) ps.setInt(1, 1001) val rs = ps.executeQuery() while (rs.next) { // extract song, add to list val s = new Song(name, duration, tracknumber) songs ::= a } // extract album from last row, add songs to artist new Album(name, release, rating, songs) } ©
Mesan
AS
  • 81. Oppsiden • Full
kontroll
på
all
SQL • Hvilken
SQL
som
kjøres • Når
den
kjøres • Full
valgfrihet
i
modellering
av
data • class,
case
class,
Option[]
etc • Tilgang
til
alt
vi
ønsker
oss ©
Mesan
AS
  • 82. What´s the catch? ©
Mesan
AS
  • 83. What´s the catch? • boilerplate ©
Mesan
AS
  • 84. What´s the catch? var conn : Connection = null • boilerplate var st : PreparedStatement = null try { conn = con st = conn.prepareStatement("SQL here") // do something SQLy } finally { st.close() conn.close() if (rs.next()) { } // do something with resultset } st.setInt(1, 1) while (rs.next()) { st.setXXX // do something with resultset } rs.getInt(1) rs.getString(2) rs.getXxx(3) ©
Mesan
AS
  • 85. What´s the catch? var conn : Connection = null • boilerplate var st : PreparedStatement = null try { conn = con st = conn.prepareStatement("SQL here") // do something SQLy } finally { st.close() conn.close() if (rs.next()) { } // do something with resultset } st.setInt(1, 1) while (rs.next()) { st.setXXX // do something with resultset } rs.getInt(1) rs.getString(2) rs.getXxx(3) • Lock‐in
mot
database‐leverandør • Lav‐nivå
API
å
forholde
seg
til • Håndkoding
av
all
SQL ©
Mesan
AS

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. av og til er data bare data uten oppf&amp;#xF8;rsel\n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. enum Genre\nDuration - int-wrapper\n\n
  155. enum Genre\nDuration - int-wrapper\n\n
  156. enum Genre\nDuration - int-wrapper\n\n
  157. enum Genre\nDuration - int-wrapper\n\n
  158. enum Genre\nDuration - int-wrapper\n\n
  159. enum Genre\nDuration - int-wrapper\n\n
  160. enum Genre\nDuration - int-wrapper\n\n
  161. enum Genre\nDuration - int-wrapper\n\n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. Genre - enum mappes automatisk :)\ntabeller defineres som verdier/objekter/singletons i schema\nkunne brukt case-klasser\nKeyedEntity[Int] - bare convenience, ikke et krav, men om man bruker genererte n&amp;#xF8;kler s&amp;#xE5; f&amp;#xE5;r man ekstra\n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n