Saya ingin tahu apakah saya dapat beralih dari Jawa ke Scala di proyek Spring + Hibernate untuk memanfaatkan beberapa fitur Scala seperti pencocokan pola, Opsi, dan apa yang menurut saya sintaks yang lebih bersih secara umum. Saya telah mencari ORM secara default di ekosistem Scala dan saya menemukan berpikir seperti Aktifkan (tapi kebanyakan saya mencoba mencari apakah Hibernate dapat digunakan dengan Scala). Mencari ini, saya sudah membaca ini di dokumentasi Play tentang JPA + Scala.
Tetapi poin yang paling penting adalah: apakah Anda benar-benar membutuhkan Relationnal to Objects mapper ketika Anda memiliki kekuatan bahasa fungsional? Mungkin tidak. JPA adalah cara yang mudah untuk mengabstraksi kurangnya kekuatan Jawa dalam transformasi data, tetapi rasanya benar-benar salah ketika Anda mulai menggunakannya dari Scala.
Saya tidak memiliki pemahaman yang mendalam tentang bagaimana menggunakan pemrograman fungsional untuk membuat aplikasi lengkap (itu sebabnya saya bermaksud untuk menggunakan Scala sehingga saya dapat memahami ini secara bertahap, karena menggabungkan OO + Fungsional), jadi saya tidak tahu mengapa saya tidak memerlukan ORM dengan bahasa fungsional dan apa yang akan menjadi pendekatan fungsional untuk mengatasi ketekunan model domain.
Pendekatan DDD untuk logika bisnis masih masuk akal dengan Scala, bukan?
sumber
Jawaban:
Nah, satu hal yang penting untuk dilakukan setiap kali kita berdiskusi seperti ini adalah dengan jelas membedakan antara obyek pemetaan relasional ("ORM") dan lapisan abstraksi basis data . ORM adalah sejenis lapisan abstraksi basis data, tetapi tidak semua lapisan abstraksi basis data adalah ORM. Salah satu alat yang baik untuk belajar memahami hal ini adalah pustaka SQLAlchemy populer Python , yang menyebut dirinya sebagai "toolkit SQL dan Object Relational Mapper" (huruf tebal saya), dengan gagasan bahwa ini adalah hal yang berbeda. Ketika mereka meletakkannya di halaman fitur utama mereka :
Halaman depan menggambarkan ORM seperti ini:
Gagasan kunci ORM adalah mencoba dan menjembatani ketidakcocokan impedansi objek-relasional yang terkenal . Ini berarti mendefinisikan hubungan antara kelas yang ditentukan pengguna ke tabel dalam skema database dan menyediakan operasi "simpan" dan "muat" otomatis untuk kelas aplikasi Anda.
Sebaliknya, lapisan abstraksi database non-ORM cenderung lebih berkomitmen pada model data relasional dan SQL, dan sama sekali tidak berorientasi objek. Jadi alih-alih menampilkan "pemetaan" antara tabel dan kelas dan menyembunyikan skema database dari programmer, mereka cenderung mengekspos database ke programmer tetapi dengan API dan abstraksi yang lebih baik. Misalnya, pembangun kueri SQL memungkinkan Anda untuk menghasilkan kueri SQL kompleks secara terprogram, tanpa manipulasi string, seperti ini ( contoh dari perpustakaan jOOQ untuk Java ):
Sekarang, kerangka bermain tampaknya tidak 100% sesuai dengan apa yang saya jelaskan , tetapi argumen mereka tampaknya berada di ruang umum ini: bekerja dengan model relasional secara langsung alih-alih menerjemahkannya ke kelas dan kembali dari mereka.
The jOOQ perpustakaan bernilai belajar sebagai tandingan ke ORMs. Mereka juga memiliki beberapa entri blog yang relevan yang patut dibaca:
sumber
Agak sulit untuk dijelaskan sampai Anda telah melakukan banyak pemrograman fungsional. Dalam pemrograman berorientasi objek, data Anda terjebak di satu objek dan tetap di sana. Objek itu akan diedarkan sedikit, dan dimodifikasi sedikit, tetapi Anda biasanya bekerja secara fundamental dengan "identitas" yang sama selama masa pakai data itu.
ORM umumnya dirancang berdasarkan paradigma itu. Anda mengambil beberapa data dari database, memasukkannya ke dalam objek, berpotensi memodifikasinya banyak, dan ketika Anda selesai, Anda masih memiliki objek yang sama yang dapat Anda tulis kembali ke database.
Pemrograman fungsional berfungsi secara berbeda. Data Anda tidak mempertahankan satu identitas selama masa pakainya. Itu akan terpecah, disalin, dibagikan, dan diubah. Ini semacam mengalir melalui banyak fungsi, kemudian akhirnya akan dipasang kembali ke bentuk output yang Anda butuhkan. Agar API basis data apa pun terasa alami dalam bahasa fungsional, ia harus memperhitungkannya, dan JPA tidak.
sumber
Dalam scala masih berguna untuk memetakan tabel database ke objek, dan ada beberapa cara untuk melakukannya.
Salah satu kerangka kerja populer di dunia Scala adalah apik . Ini bukan ORM, karena ia lebih sedikit (yaitu, ia tidak menjemput hubungan tanpa disuruh bergabung secara eksplisit).
Jadi, Anda masih memetakan objek ke baris basis data, tetapi objek Anda tidak berubah, (karenanya tidak ada pembilasan negara) dan Anda secara eksplisit menjalankan kueri menggunakan DSL monadik. Hasilnya adalah Anda mendapatkan banyak bagian "baik" dari ORM tanpa masalah seputar mutabilitas, dan masalah N + 1 yang tidak dapat diprediksi.
Orang harus mencatat bahwa orang-orang mendapatkan sukses besar menggunakan banyak perpustakaan yang lebih tipis, seperti anorm atau JDBC lurus, menggunakan teknik fungsional untuk menjaga kode tetap indah.
Satu pustaka fantastis yang menerapkan teknik fungsional di atas JDBC juga doobie .
Jadi Anda memiliki banyak pilihan untuk akses database, tetapi Hibernate (yang tampaknya merupakan ORM de-facto) bukan salah satu yang terbaik, karena bias terhadap kemampuan berubah-ubah.
sumber
Anda tidak memerlukan ORM bahkan dalam bahasa berorientasi objek.
Pertama, siapa yang mengatakan bahwa data Anda harus disalin secara fisik dari penyimpanan gigih Anda ke objek Anda? Alan Kay , seorang pria di belakang Smalltalk, ingin benda - benda untuk menyingkirkan data . Dia menyarankan bahwa suatu objek hanya dapat memiliki referensi ke beberapa area di mana datanya disimpan.
Kedua - apa cara terbaik untuk mencapainya? Saya sarankan mengidentifikasi objek Anda dengan tanggung jawab mereka , dan tidak memikirkan data yang mereka miliki. Jika Anda pernah mendengar tentang pendekatan kartu CRC, itu digunakan tepat untuk itu.
Dan, akhirnya, kalau-kalau Anda akan kembali ke OO-field, berikut adalah cara untuk mengimplementasikannya .
sumber