Setelah menggunakan Hibernate di sebagian besar proyek saya selama sekitar 8 tahun, saya telah mendarat di sebuah perusahaan yang tidak mendukung penggunaannya dan ingin aplikasi hanya berinteraksi dengan DB melalui prosedur tersimpan.
Setelah melakukan ini selama beberapa minggu, saya belum dapat membuat model domain yang kaya dari aplikasi yang saya mulai buat, dan aplikasi tersebut hanya terlihat seperti skrip transaksional (mengerikan).
Beberapa masalah yang saya temukan adalah:
- Tidak dapat menavigasi grafik objek karena prosedur yang tersimpan hanya memuat jumlah data minimum, yang berarti bahwa kadang-kadang kita memiliki objek serupa dengan bidang yang berbeda. Salah satu contoh adalah: kami memiliki prosedur tersimpan untuk mengambil semua data dari pelanggan, dan yang lain untuk mengambil informasi akun ditambah beberapa bidang dari pelanggan.
- Banyak logika berakhir di kelas pembantu, sehingga kode menjadi lebih terstruktur (dengan entitas yang digunakan sebagai struct C lama).
- Kode perancah yang lebih membosankan, karena tidak ada kerangka kerja yang mengekstrak set hasil dari prosedur yang disimpan dan menempatkannya dalam suatu entitas.
Pertanyaan saya adalah:
- Adakah yang pernah berada dalam situasi yang sama dan tidak setuju dengan pendekatan prosedur toko? apa yang kamu lakukan?
- Apakah ada manfaat sebenarnya dari menggunakan prosedur tersimpan? terlepas dari titik konyol "tidak ada yang bisa mengeluarkan drop table".
- Apakah ada cara untuk membuat domain kaya menggunakan prosedur tersimpan? Saya tahu bahwa ada kemungkinan menggunakan AOP untuk menyuntikkan DAO / Repositori ke entitas untuk dapat menavigasi objek grafik. Saya tidak suka opsi ini karena sangat dekat dengan voodoo.
Kesimpulan
Pertama, terima kasih atas jawaban Anda. Kesimpulan yang saya sampaikan adalah bahwa ORM tidak memungkinkan pembuatan model Rich Domain (seperti beberapa orang sebutkan), tetapi itu menyederhanakan jumlah pekerjaan (sering berulang). Berikut ini adalah penjelasan yang lebih rinci tentang kesimpulan, tetapi tidak didasarkan pada data keras apa pun.
Sebagian besar aplikasi meminta dan mengirim informasi ke sistem lain. Untuk melakukan ini, kami membuat abstraksi dalam ketentuan model (misalnya acara bisnis) dan model domain mengirim atau menerima acara. Peristiwa biasanya membutuhkan sebagian kecil informasi dari model, tetapi tidak keseluruhan model. Misalnya di toko online, gateway pembayaran meminta beberapa informasi pengguna dan total untuk menagih pengguna, tetapi tidak memerlukan riwayat pembelian, produk yang tersedia, dan semua basis pelanggan. Jadi acara tersebut memiliki set data kecil dan spesifik.
Jika kita mengambil database aplikasi sebagai sistem eksternal, maka kita perlu membuat abstraksi yang memungkinkan kita untuk memetakan entitas Model Domain ke database ( seperti yang NimChimpsky sebutkan , menggunakan data-mapper). Perbedaan yang jelas, adalah bahwa sekarang kita perlu membuat pemetaan untuk setiap entitas model ke basis data (baik skema lama atau prosedur tersimpan), dengan rasa sakit tambahan bahwa, karena keduanya tidak sinkron, satu entitas domain mungkin memetakan sebagian ke entitas basis data (misalnya kelas UserCredentials yang hanya berisi nama pengguna dan kata sandi dipetakan ke tabel Pengguna yang memiliki kolom lain), atau satu entitas model domain dapat memetakan ke lebih dari satu entitas basis data (misalnya jika ada satu-ke- satu pemetaan di atas meja, tetapi kami ingin semua data hanya dalam satu kelas).
Dalam aplikasi dengan beberapa entitas, jumlah pekerjaan tambahan mungkin kecil jika tidak perlu melintangi entitas, tetapi meningkat ketika ada kebutuhan bersyarat untuk melintangi entitas (dan dengan demikian kita mungkin ingin menerapkan semacam 'malas' pemuatan'). Ketika sebuah aplikasi tumbuh memiliki lebih banyak entitas, pekerjaan ini hanya meningkat (dan saya merasa bahwa itu meningkat secara non-linear). Asumsi saya di sini, adalah bahwa kita tidak mencoba untuk menemukan kembali ORM.
Salah satu manfaat memperlakukan DB sebagai sistem eksternal, adalah kita dapat membuat kode di sekitar situasi di mana kita menginginkan 2 versi berbeda dari aplikasi yang berjalan, di mana setiap aplikasi memiliki pemetaan yang berbeda. Ini menjadi lebih menarik dalam skenario pengiriman kontinu ke produksi ... tapi saya pikir ini juga dimungkinkan dengan ORM pada tingkat yang lebih rendah.
Saya akan mengabaikan aspek keamanan, atas dasar bahwa pengembang, bahkan jika dia tidak memiliki akses ke database, dapat memperoleh sebagian besar jika tidak semua informasi yang disimpan dalam sistem, hanya dengan menyuntikkan kode berbahaya (mis. Saya tidak percaya saya lupa menghapus garis yang mencatat rincian kartu kredit pelanggan, Tuanku! ).
Pembaruan kecil (6/6/2012)
Prosedur tersimpan (setidaknya dalam Oracle) mencegah melakukan apa pun seperti pengiriman terus-menerus dengan Zero downtime, karena setiap perubahan pada struktur tabel akan membatalkan prosedur dan pemicu. Jadi selama DB diperbarui, aplikasi akan turun juga. Oracle memberikan solusi untuk Redefinisi Berbasis Edisi ini , tetapi beberapa DBA yang saya tanyakan tentang fitur ini menyebutkan bahwa itu diimplementasikan dengan buruk dan mereka tidak akan memasukkannya ke dalam DB produksi.
Jawaban:
Aplikasi Anda masih harus dimodelkan dari prinsip-prinsip desain berbasis domain. Apakah Anda menggunakan ORM, JDBC langsung, memanggil SP (atau apa pun) tidak masalah . Semoga lapisan tipis yang mengabstraksi model Anda dari SP harus melakukan trik dalam kasus ini. Seperti yang dinyatakan poster lain , Anda harus melihat SP dan hasilnya sebagai layanan dan memetakan hasilnya ke model domain Anda.
sumber
Di dunia keuangan (dan tempat-tempat di mana kepatuhan Sarbanes-Oxley diperlukan), Anda harus dapat mengaudit sistem untuk memastikan bahwa mereka melakukan apa yang seharusnya mereka lakukan. Dalam kasus ini, jauh lebih mudah untuk memastikan kepatuhan ketika semua akses data melalui prosedur yang tersimpan. Dan ketika semua ad-hoc SQL dihapus, jauh lebih sulit untuk menyembunyikan sesuatu. Untuk contoh mengapa ini akan menjadi "hal yang baik", saya merujuk Anda ke makalah klasik Ken Thompson Reflections on Trusting Trust .
sumber
Prosedur tersimpan jauh lebih efisien daripada dan kode SQL sisi klien. Mereka pra-kompilasi SQL di DB yang juga memungkinkannya untuk melakukan beberapa optimasi.
Secara arsitektur, SP akan mengembalikan data minimum yang diperlukan untuk suatu tugas, yang bagus karena berarti lebih sedikit data yang ditransfer. Jika Anda memiliki arsitektur seperti itu, Anda harus menganggap DB sebagai layanan (anggaplah itu sebagai layanan web dan setiap SP adalah metode untuk memanggil). Seharusnya tidak menjadi masalah untuk bekerja dengannya seperti ini, sedangkan ORM memandu Anda untuk bekerja dengan data jarak jauh seolah-olah itu lokal, sehingga menipu Anda untuk memperkenalkan masalah kinerja jika Anda tidak hati-hati.
Saya telah berada dalam situasi di mana kami menggunakan SP sepenuhnya, DB menyediakan API data dan kami menggunakannya. Aplikasi khusus itu berskala sangat besar dan berkinerja sangat baik. Saya tidak akan mengatakan hal buruk tentang SP setelah itu!
Ada keuntungan lain - DBA akan menulis semua pertanyaan SQL Anda untuk Anda, dan dengan senang hati akan menangani semua hierarki relasional dalam DB, jadi Anda tidak perlu melakukannya.
sumber
the approach of letting the DBAs write the procedures smells like development silos
+100 internet kepada Anda untuk permata kebenaran ini. Saya selalu melihat ini sebagai kasus di mana akses data dikendalikan melalui prosedur yang tersimpan.Yang sering terjadi adalah bahwa pengembang salah menggunakan objek ORM mereka sebagai model domain mereka.
Ini tidak benar, dan mengikat domain Anda langsung ke skema DB Anda.
Apa yang benar-benar harus miliki adalah model domain terpisah sekaya yang Anda suka dan gunakan layer ORM secara terpisah.
Ini berarti Anda akan perlu memetakan antara setiap set objek.
sumber
Objek domain Anda dapat diisi sesuka Anda, tidak perlu menggunakan Hibernate. Saya pikir istilah yang tepat adalah data-mapper . Sangat mungkin bahwa data bertahan Anda akan struktur yang sama sekali berbeda dengan objek domain Anda.
sumber