hibernate学習一対一、一対多、多対一、多対多、注釈版とXML版

17209 ワード

個人的な簡単なまとめにすぎない
hibernateのプロファイルhibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost/hibernate
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">10</property>

<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache      -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<property name="format_sql">true</property>

</session-factory>


</hibernate-configuration>

1対1のマッピング関係
私たちは妻が夫に対応していると仮定して、夫も妻が一人しかいません.他の社会問題は議論しません.
注記:
まず、プロファイルにマッピング関係を追加します.
 <mapping class="com.cl.hiberanate.bean.Husband" />
<mapping class="com.cl.hiberanate.bean.Wife" />

Husbandクラス
@Entity
public class Husband {


private int id;
private String name;
private Wife wife;

@OneToOne
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}

wifeクラス
@Entity
public class Wife {

private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

sql文を表示するには、次の手順に従います.
 create table Husband (
        id integer not null auto_increment,
        name varchar(255),
        wife_id integer,
        primary key (id)
     )


    create table Wife (
        id integer not null auto_increment,
        name varchar(255),
        primary key (id)
    )
    alter table Husband 
        add index FKAEEA401BA8A19199 (wife_id), 
        add constraint FKAEEA401BA8A19199 
        foreign key (wife_id) 
        references Wife (id)

以上は一方向マッピングです.次に、双方向マッピングを見てみましょう.つまり、両方のクラスにマッピング関係を書きます.
husbandは修正する必要はありません.wifeクラスを修正するだけです.
@Entity
public class Wife {

private int id;
private String name;
//  
private Husband husband;
//  com.cl.hiberanate.bean.Husband.wife    
//        ,    ,    
@OneToOne(mappedBy="wife")
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

テストクラスを作成してテストすればいいJunit Test、本当にmain関数の中で実行することはできません
Session session  = new AnnotationConfiguration().configure().buildSessionFactory().openSession();

Wife w = new Wife();
w.setName("Helen");

Husband h = new Husband();
h.setName("Tom");
h.setWife(w);

session.save(w);
session.save(h);

session.beginTransaction().commit();

xml版を見てみると、今は会社がこれをあまり使わないので、開発速度が遅すぎます.
hibernate.cfg.xmlこれは必ずありますが、
クラスは上のクラスをそのまま使えばいいです.
新規:マッピングファイルHusband.hbm.xml,Wife.hbm.xmlはあなたのクラスと同じ名前でパッケージの下にあることを覚えています.
Husband.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.cl.hiberanate.bean">

<class name="Husband">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<!-- one-to-one       ,           unique-->

<many-to-one name="wife" column="wifeId" unique="true"></many-to-one>

</class>

</hibernate-mapping>

Wife.hbm.xml双方向はコメントをキャンセルするだけです
<hibernate-mapping package="com.cl.hiberanate.bean">


<class name="Wife">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" not-null="true" length="20" type="java.lang.String"></property>
<!-- one-to-one    -->
<!-- <one-to-one name="husband" property-ref="wife"></one-to-one> -->
</class>


</hibernate-mapping>

hibernate.cfg.xmlに追加:
<mapping resource="com/cl/hiberanate/bean/Husband.hbm.xml" />
<mapping resource="com/cl/hiberanate/bean/Wife.hbm.xml" />

注釈版との違いに注意
データベース文を見てみましょう.上と同じです.
create table Husband (
        id integer not null auto_increment,
        name varchar(255),
        wifeId integer unique,
        primary key (id)
    )
    create table Wife (
        id integer not null auto_increment,
        name varchar(20) not null,
        primary key (id)
    )
    alter table Husband 
        add index FKAEEA401B29AAB07C (wifeId), 
        add constraint FKAEEA401B29AAB07C 
        foreign key (wifeId) 
        references Wife (id) 

テスト:
Session session  = new Configuration().configure().buildSessionFactory().openSession();

Wife w = new Wife();
w.setName("Helen");

Husband h = new Husband();
h.setName("Tom");
h.setWife(w);

session.save(w);
session.save(h);

session.beginTransaction().commit(); 

OK、もう一対多を見て
1冊の本はただ1つのタイプに属して、例えば《オペレーティングシステム》のこの本は“コンピュータ類”に属して、コンピュータ類はオペレーティングシステムのほかに、コンピュータの構成原理、Javaなどがあって、つまり1種類の中で多くの本があります
私が基本的に同じ名前の本を持っているのと比べないでください.それは私たちが今議論しているのとは関係ありません.彼らはIdで区別することができます.私たちは1冊しかないと仮定します.
1対多:1種類に複数の本があり、
注釈版
Book :
@Entity
public class Book {

private int id;
private String bookname;

@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}

}

BookType :
@Entity
public class BookType {

private int id;
private String typename;

@Id
@GeneratedValue
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
public String getTypename() {
return typename;
}
public void setTypename(String typename) {
this.typename = typename;
} 
//   
private Set<Book> books;
@OneToMany
public Set<Book> getBooks() {
return books;
}

public void setBooks(Set<Book> books) {
this.books = books;
}
}

hibernateを修正します.cfg.xml
<mapping class="com.cl.hibernate.bean.Book" />
<mapping class="com.cl.hibernate.bean.BookType" />

テスト、
Session session  = new AnnotationConfiguration().configure().buildSessionFactory().openSession();

Book book = new Book();
BookType booktype = new BookType();
book.setBookname("hibernate");
booktype.setTypename("computer");
Set<Book> books = new HashSet<Book>() ;
books.add(book);
booktype.setBooks(books);

session.save(book);
session.save(booktype);

session.beginTransaction().commit();

テーブル文を確認
create table Book (
        id integer not null auto_increment,
        bookname varchar(255),
        primary key (id)
    )

    create table BookType (
        id integer not null auto_increment,
        typename varchar(255),
        primary key (id)
    )

    create table BookType_Book (
        BookType_id integer not null,
        books_id integer not null,
        primary key (BookType_id, books_id),
        unique (books_id)
    )

    alter table BookType_Book 
        add index FK13FA97E56EF30904 (BookType_id), 
        add constraint FK13FA97E56EF30904 
        foreign key (BookType_id) 
        references BookType (id)

    alter table BookType_Book 
        add index FK13FA97E53B4450C3 (books_id), 
        add constraint FK13FA97E53B4450C3 
        foreign key (books_id) 
        references Book (id)

自動的に時計を1枚追加してくれました
一対多の双方向(逆方向)すなわち多対一であり,ここではまず議論しないで,多対まで何度も議論する
XML版の
上のルールと同様に、同じ名前のマッピングファイルを新規作成します.
BookType
<hibernate-mapping package="com.cl.hibernate.bean">

<class name="BookType">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="typename"></property>
<!--     -->
<set name="books">
<!--   book    -->
<key column="typeId"></key>
<one-to-many class="com.cl.hibernate.bean.Book"/>
</set>
</class>

</hibernate-mapping>

Book:双方向でその注釈をキャンセルすればいいです.
<class name="Book">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="bookname"></property>
<!-- many-to-one  -->
<!-- <many-to-one name="booktype" column="typeId" ></many-to-one> -->

</class>

テーブル文は上と同じです
マルチペア
やはり上の図書と分類の例です
Book :
@Entity
public class Book {


private int id;
private String bookname;
//         ,        
private BookType booktype;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}

@ManyToOne
@JoinColumn(name="typeId")
public BookType getBooktype() {
return booktype;
}
public void setBooktype(BookType booktype) {
this.booktype = booktype;
}

}

BookType:多対一の双方向即ち一対多
@Entity
public class BookType {

private int id;
private String typename;


@Id
@GeneratedValue
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
public String getTypename() {
return typename;
}
public void setTypename(String typename) {
this.typename = typename;
}

//          
private Set<Book> books;

@OneToMany(mappedBy="booktype")
public Set<Book> getBooks() {
return books;
}

public void setBooks(Set<Book> books) {
this.books = books;
}
}

XML版
Book.hbm.xml:
<class name="Book">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="bookname"></property>
<!-- many-to-one  -->
<many-to-one name="booktype" column="typeId" ></many-to-one>

</class>

BookType.hbm.xml:
<class name="BookType">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="typename"></property>

</class>

多対多
いわゆる多対多の関係、先生と学生、1人の学生は多くの先生があって、1人の先生は多くの学生がいます
注記:双方向マッピングによる次のコメントの取り消し
Student :
@Entity
public class Student {

private int id;
private String sname;
/* //    
private Set<Teacher> teachers;
//      com.cl.hibernate.bean.Teacher.students
@ManyToMany(mappedBy="students")
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
*/
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}

}

Teacher :
@Entity
public class Teacher {


private int id;
private String tname;
private Set<Student> students;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return tname;
}
public void setName(String tname) {
this.tname = tname;
}

@ManyToMany
//                                     ,          
@JoinTable(name="t_s",joinColumns={@JoinColumn(name="teacher_id")},
inverseJoinColumns={@JoinColumn(name="student_id")})
public Set<Student> getStudent() {
return students;
}
public void setStudent(Set<Student> students) {
this.students = students;
}

}

構築文を参照してください.
 
create table Student (
        id integer not null auto_increment,
        sname varchar(255),
        primary key (id)
    )
    create table Teacher (
        id integer not null auto_increment,
        name varchar(255),
        primary key (id)
    )
    create table t_s (
        teacher_id integer not null,
        student_id integer not null,
        primary key (teacher_id, student_id)
    )
    alter table t_s 
        add index FK1BF68467CBB30 (teacher_id), 
        add constraint FK1BF68467CBB30 
        foreign key (teacher_id) 
        references Teacher (id)
    alter table t_s 
        add index FK1BF6835E17090 (student_id), 
        add constraint FK1BF6835E17090 
        foreign key (student_id) 
        references Student (id)

OK、XML版の
Student.hbm.xml:
<class name="Student">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="sname"></property>

</class>

Teacher.hbm.xml:
<class name="Teacher">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="tname"></property>
<!-- many-to-many -->
<!--               -->
<set name="students" table="t_s">
<!--       -->
<key column="teacher_id"></key>
<!--          +  -->
<many-to-many class="com.cl.hibernate.bean.Student" 
column="student_id"></many-to-many>
</set>
</class>

OK、関係マッピングはすべて完了しました
hibernateのページングを見てみると、どのデータベースも同じで、hibernateはすでに実現しています.
次はテストコードです
Session session  = new AnnotationConfiguration().configure().buildSessionFactory().openSession();
Query query = session.createQuery("from Book ");
List<?> total = query.list();

//  
int pageSize = 3;
int totalPage = total.size() / pageSize ;
if(total.size() % pageSize != 0){
totalPage++;
}
System.err.println(totalPage);

query.setMaxResults(pageSize);
int currentPage = 1;//    
query.setFirstResult((currentPage - 1)*pageSize);

List<?> list = query.list();

書き方、パラメータpageSize、currentPageでページング方法を実現できます
クエリーにパラメータがある場合は、プレースホルダを使用できますか?
例:
Query query = session.createQuery("from Book b where b.id = ? ");
query.setString(0, "1");
List<?> list = query.list();
for(Object o : list){
Book b = (Book)o;
System.out.println(b);
}

代替変数を使用することもできます
次のようになります.
hql = "from Book b where b.id = :id";

Query query = session.createQuery(hql);
query.setParameter("id", 1) //.setParameter("id", 1);

どちらのパラメータ設定も可能です
hibernateの機能はとても強くて、学んでから不足を知っています.
すべての練習ソース:http://download.csdn.net/detail/i_do_can/9372156
でもjarファイルをアップロードするのを忘れたようです.http://download.csdn.net/detail/i_do_can/9372177