hibernate学习一对一,一对多,多对一,多对多,注解版和XML版

只是个人简单的一点小结

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>


一对一的映射关系

 我们假设一个妻子对应一个老公,一个老公也只有一个妻子,其他社会问题我们不讨论

注解版:

首先在配置文件里添加映射关系:

 <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;
}
}


编写一个测试类测试一下就好了,JunitTest,实在不会就去 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 ,再看看一对多

一本书只属于一个类型,比如《操作系统》这本书属于“计算机类”,而计算机类除了有操作系统,还有计算机组成原理、Java等等,即一类里有多本书

不要较真什么我有基本相同名字的书,那个跟我们现在讨论的没关系,他们可以通过Id区分,我们假设只有一本

一对多:一个类有多本书,

注解版

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)


自动帮我们新增了一张表

一对多的双向(反向)即 多对一,这里先不讨论,到多对一再讨论


再看看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>



多对多

所谓多对多的关系,老师和学生,一个学生有多个老师,一个老师有多个学生

注解版:双向映射取消下面的注释

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值