2016-09-23 15 views
1

2テーブルpatientmedicineを持つMySQLデータベースがあるとします。私はその下の列を表示しています。関係処理:HibernateとJDBC

患者

idPatient (int) (primary key) 
first_name (varchar) 
last_name (varchar) 

医学

idMedicine (int) (primary key) 
idPatient (int) (foreign key) 
drug_name (varchar) 

Medicine表がPatientテーブルのforiegnキーを持っていることに注意してください。私は純粋なJDBCを使用する場合

今、私は私がのために自分のデータベースをリバースエンジニアリングしかし場合MedicinePatientテーブル

PatientBeanクラス

public class PatientBean 
{ 
    private int idPatient; 
    private String first_name; 
    private String last_name; 

    public void setIdPatient(int idPatient) 
    { 
     this.idPatient = idPatient; 
    } 

    public int getIdPatient() 
    { 
     return idPatient; 
    } 

    public void setFirstName(String first_name) 
    { 
     this.first_name = first_name; 
    } 

    public String getFirstName() 
    { 
     return first_name; 
    } 

    public void setLastName(String last_name) 
    { 
     this.last_name = last_name; 
    } 

    public String getLastName() 
    { 
     return last_name; 
    } 

} 

`MedicineBean` class 

public class MedicineBean 
{ 
    private int idMedicine; 
    private int idPatient; 
    private String drug_name; 

    public void setIdMedicine(int idMedicine) 
    { 
     this.idMedicine = idMedicine; 
    } 

    public int getIdMedicine() 
    { 
     return idMedicine; 
    } 

    public void setIdPatient(int idPatient) 
    { 
     this.idPatient = idPatient; 
    } 

    public int getIdPatient() 
    { 
     return idPatient; 
    } 

    public void setDrugName(String drug_name) 
    { 
     this.drug_name = drug_name; 
    } 

    public String getDrugName() 
    { 
     return drug_name; 
    } 

} 

ためのBeanを作成するには、次のことを行いますPOJOファイルを生成するNetBeansのようなツールを使ってHibernateをHibernateにマッピングするなど、私は以下のようなものが期待できます。

PatientBeanクラス

public class PatientBean 
    { 
     private int idPatient; 
     private String first_name; 
     private String last_name; 
    private MedicineBean medicineBean; 

     public void setIdPatient(int idPatient) 
     { 
      this.idPatient = idPatient; 
     } 

     public int getIdPatient() 
     { 
      return idPatient; 
     } 

     public void setFirstName(String first_name) 
     { 
      this.first_name = first_name; 
     } 

     public String getFirstName() 
     { 
      return first_name; 
     } 

     public void setLastName(String last_name) 
     { 
      this.last_name = last_name; 
     } 

     public String getLastName() 
     { 
      return last_name; 
     } 

    public void setMedicineBean(String medicineBean) 
     { 
      this.medicineBean = medicineBean; 
     } 

     public String getMedicineBean() 
     { 
      return medicineBean; 
     } 
    } 

MedicineBeanクラス

public class MedicineBean 
    { 
     private int idMedicine; 
     private int idPatient; 
     private String drug_name; 
    private Set<PatientBean> patients = new HashSet<PatientBean>(0); 

     public void setIdMedicine(int idMedicine) 
     { 
      this.idMedicine = idMedicine; 
     } 

     public int getIdMedicine() 
     { 
      return idMedicine; 
     } 

     public void setIdPatient(int idPatient) 
     { 
      this.idPatient = idPatient; 
     } 

     public int getIdPatient() 
     { 
      return idPatient; 
     } 

     public void setDrugName(String drug_name) 
     { 
      this.drug_name = drug_name; 
     } 

     public String getDrugName() 
     { 
      return drug_name; 
     } 

    public void setPatients(Set<PatientBean>patients) 
    { 
     this.patients = patients; 
    } 

    public Set<PatientBean> getPatients() 
    { 
     return patients; 
    } 

    } 

だけでなく、この、Hibernateはまた(、多くの1つに多くを一から一、1)関係タイプをマップしますxmlファイルの中にあります。しかし、JDBCではまったく気にしませんが、同じように扱われる外部キーです。

私の質問は、なぜこの違いがあるのですか?私は、Hibernateの操作の大半は役に立たず、ただCPUを使用していると信じています。たとえば、getAllMedicines()メソッドを呼び出すと、patientsのリストをPatientテーブルに取得しようとしています。 99%の症例では、患者のリストではなく、すべての医薬品が必要なだけです。必要な場合は、参加して入手することができます。

これの背後にある理由は何ですか?それとも、JDBCに対しても同じ動作を維持する必要がありますか?

+0

通常、 'patient'リストは遅延ロードされます。つまり、必要な場合にのみデータを読み込みます。 2番目の方法は、通常はOOプログラムに書き込むのと同じようにデータを含みます –

+0

@ScaryWombat:はいわかっています。私の質問は、JDBCで同じことをしない理由です。私はそれが単に役に立たないと思う。 –

+1

あなたがJDBCでそれをやっていない唯一の理由は、あなたがJDBCでそれをやっていないからです。 *あなたは、あなたがそれをやりたいことを完全にコントロールしているので、MedicineBeanの 'int idPatient'を' PatientBean patient'に置き換え、PatientBeanに 'List 医薬品 'を加えることでそれを実現できます。彼らがどのように使用されているかによって、これは別の方法です。 – Andreas

答えて

0

私は休止状態では、あなたが恐れているように完全なコントロールを失うとは思わない。

主な違いは、hibernateがコードとjdbcの間に余分なレイヤーを追加する点です。この層は本当に薄いものです。いつでも、hibernate でjdbcを使用する選択があります。。だからあなたは何のコントロールも失っていない。

難易度が高いほど、ハイバーネーションがどのように機能し、より高いレベルのAPIを使用して、ハイバーネイトがそれをjdbcに変換するかを理解することです。これは、ormマッピングが複雑なテーマであるため、少し複雑な作業です。いくつかのリファレンスドキュメントを読んで、ハイバネートができることを正確に知るために、そして彼らが何をすることを勧めているのか、しないことを勧めているのかは良い出発点です。残りは、休止状態を使用した経験から来ます。

あなたの例では、休止状態のマップ関係と言いますが、これはそうではありません。あなたのリバースエンジニアリングツールがそうでした。関係をマップしたり、代わりに外部キーの基本型(idが数字の場合はLongなど)をマップすることは自由ではありません。

物の積み込みについて。 @OneToManyを常にロードしたい場合は、FetchType.EAGERと注釈を付けてください。 @*ToManyアソシエーションはデフォルトでは遅延があります(あまりにも多くのデータを読み込まないようにする)一方、@*ToOneのアサーションはデフォルトでEAGERです。

これはエンティティレベルで構成することができ、クエリのデフォルトの動作にしますが、クエリごとにオーバーロードすることができます。

ご覧ください。あなたはコントロールを失うことはありません、あなたは単に休止状態のAPIがjdbcに変換する方法を理解する必要があります。

休止状態のチームに提起されたときに修正されるバグは別として、休止状態のパフォーマンスへの影響はあまりありません。また、アプリケーションのパフォーマンス上重要な部分では、休止状態のオーバーヘッドが0であるjdbcに常に頼ることができます。

休止状態を使用して得られるものは何ですか?私が経験したことから、エンティティモデル/データベースモデルのリファクタリングは、Hibernateマッピングを変更し、Hibernateによって生成されたすべてのクエリも自動的に変更されるため、ずっと簡単です。手書きで作成したカスタムクエリ(SQL/HQL/Criteria)を更新するだけで済みます。数百個のテーブル(以上10B行のうちのいくつか)上の(休止状態使用して10年)私の経験から、

、数テラバイトのデータベース、私はドンを意味するものではありませんこれは、バックプレーンJDBCに行きたくありませんそれが完璧なツールであるときには使用しないでくださいが、ormコードの1〜2%と同じです。

希望に役立ちます。

EDIT:springでhibernateを使用している場合は、spring-jdbcを見てください。これはjdbcの周りに素敵なレイヤーを追加します。そこでは、ドキュメントを読む必要はほとんどありません。jdbcへの変換方法を直接認識していますが、jdbcを直接使用することの定型文を少なくするユーティリティがたくさんあります(例外処理のように、ResultsetPreparedStatement、 DTOのリストへのResultSetの変換など)。

もちろん、hibernateとspring-jdbcは同じアプリケーションで使用できます。同じトランザクションレイヤーを使用するように設定するだけで済みます。同じtxで使用する場合は注意が必要です。

+0

お返事ありがとうございます。いいえ、SpringでHibernateを使用していません。私はREST APIを構築しています。 @OneToManyが常にロードされるようにしたいのであれば、FetchType.EAGERでアノテートしてください。これは膨大なオーバーヘッドになります.'とにかく、あなたは 'idPatient'のような外部キーを使うことができます単に 'SET'や完全なbeanにすることなくHibernateのものと同じように?それから、関連するXMLを変更する必要がありますか?私は注釈を使用していません。 –

+0

私はhbmマッピングにも立っていると言っています。なぜあなたはそれが大きなオーバーヘッドだと言いますか?親エンティティをロードするために、hibernateは2つのクエリを起動します:親を読み込むためのもの(id、1行、重くはない)、興味のある子コレクションのものです。 parent_id = parent.idの子エンティティをロードするためのCriteria/HQL/SQLを作成します(そしてManyToOneをLAZYとしてマークすることを忘れないでください)。 hbmマッピングファイルは、データベースモデルと、Javaコードからエンティティにアクセスする方法の2つを反映する必要があります。参考までに、hbmファイルは推奨されていません。 – Thierry

+0

私は高レベルの立場からあなたの質問に答えました。なぜなら、あなたは、冬眠の正確な部分についての答えよりも、より多くのグローバルな洞察をしたいと思ったからです。そうでない場合は、テーブルのデータベースモデル、hbmマッピングファイル、生成するために休止状態になると予想されるSQLクエリ、および休止状態のローディングコードを質問に追加してください。あなたが望むものを得るためのマッピングとハイバネーションのコード。 – Thierry