您的位置:首页 > 其它

Hibernate关系映射----单向一对多实例

2017-07-26 17:06 435 查看
Hibernate关系映射----单向一对多实例
一对多关系:
我们都知道,一个用户对应多个订单,而一个订单只能对应一个用户,那么数据库中是如何实现这种情况的呢?
        建立两张表,一张表是用户表,一张表是订单表,并且在订单表中加入用户表的主键id作为外键。如下图所示:



那么,在hibernate中是如何处理这种情况的呢?
hibernate中分为两种情况处理:分别是:单向一对多、双向一对多
单向一对多:由一端作为主导,所有的操作都有一端来完成,在一端加入多端的set集合,在数据库中,多端加入一端
的主键id作为外键,代码中不做任何处理。

实例如下:
1、新建一个Java工程,添加hibernate 3.3支持,连接test数据库
2、在src下新建com.etc.dao包,在包下新建Order.java类:
package com.etc.dao;
import java.util.Date;
/**
* Descript:订单类
* @author zoey
* @date 2017年7月26日
*/
public class Order {
private int oid;
private String state;
private Date createDate;
public int getOid() {
return oid;
}
public void setOid(int oid) {
this.oid = oid;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
3、在com.etc.dao下新建User.java类:
package com.etc.dao;

import java.util.HashSet;
import java.util.Set;
/**
* Descript:用户类
* @author zoey
* @date 2017年7月26日
*/
public class User {
private int id;
private String username;
private Set<Order> orders = new HashSet();//在一端加入多端的set集合
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
4、在com.etc.dao包下新建Order.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>
<class name="com.etc.dao.Order" table="t_order" catalog="test">
<id name="oid" type="java.lang.Integer">
<column name="order_id"/>
<generator class="native"/>
</id>
<property name="state" type="java.lang.String">
<column name="order_state"></column>
</property>
<property name="createDate" type="java.util.Date">
<column name="order_createdate"></column>
</property>
</class>
</hibernate-mapping>
5、在com.etc.dao包下新建User.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>
<!-- 类对应表格 -->
<class name="com.etc.dao.User" table="t_user" catalog="test">
<!-- 类的属性名称 -->
<id name="id" type="java.lang.Integer">
<!-- 表的字段名称 -->
<column name="user_id"/>
<generator class="native"></generator>
</id>
<property name="username" type="java.lang.String">
<column name="user_name"/>
</property>
<!-- 在一端加入多端的set集合,name是User类中对应的属性名称,cascade 级联 -->
<set name="orders" cascade="all">
<key>
<!-- 此处定义的是User表的主键id在Order表的中外键的名称 -->
<column name="user_id"></column>
</key>
<!-- 指明一对多关系,class是多端对应的类 -->
<one-to-many class="com.etc.dao.Order"/>
</set>
</class>
</hibernate-mapping>
6、配置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">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- java类中使用getCurrentSession()方法时需要配置current_session_context_class -->
<property name="current_session_context_class">thread</property>
<!-- 表不存在时,会自动创建表,刚开始的时候执行一次便可 -->
<property name="hbm2ddl.auto">create</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">
com.mysql.jdbc.Driver
</property>
<!-- 配置映射文件 -->
<mapping resource="com/etc/dao/User.hbm.xml" />
<mapping resource="com/etc/dao/Order.hbm.xml" />

</session-factory>

</hibernate-configuration>
7、在工程下新建test文件夹,在文件夹下新建com.etc.dao包,在包下新建UserDAOTest.java类如下:
package com.etc.dao;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class UserDAOTest {
@Test
public void test1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.getTransaction().commit();
}
}
8、右键RunAs--JUnit Test,查看数据库,我们就会发现,t_user和t_order表已经自动创建完成,并且t_order表中
增加user_id为外键,对应t_user表。
9、更改UserDAOTest.java,操作两张表,如下:
package com.etc.dao;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class UserDAOTest {
@Test
public void test1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
//新建一个用户
User user = new User();
user.setUsername("zoey");

//新建两个订单
Order o1 = new Order();
o1.setState("1");
o1.setCreateDate(new Date());

Order o2 = new Order();
o2.setState("0");
o2.setCreateDate(new Date());

//将多个订单加入一个用户的
user.getOrders().add(o1);
user.getOrders().add(o2);

//保存用户,因为在映射文件中设置了cascade=all,所以保存用户信息的同时也会保存与之关联的订单信息
session.save(user);
session.getTransaction().commit();
}
}
10、查看数据库,结果如下:





我们可以看到:用户表增加了一条记录,订单表增加了两条记录,都属于同一个用户所有。
总结:
1、单向一对多关系实现步骤
(1)编写java类,在一端加入多端的set集合
(2)编写映射文件,将类和表联系在一起,在一端加入多端的set集合,配置one-to-many,设置cascade级联属性
(3)配置hibernate.cfg.xml文件,需要将映射文件配置到其中,还需要配置hbm2ddl.auto属性,使得表不存在时自动
创建表,在刚开始时执行一次便可,否则会一直重新创建表(表存在时先删除再创建)
<property name="hbm2ddl.auto">create</property>
(4)编写测试类,验证表是否创建成功
(5)操作一端,增加一端的值,同时增加多端的值。
2、所有的操作都是针对一端的,在多端看来,并不知道一端的存在。java类中操作的也是一端。
3、cascade:级联,就是对一个对象进行操作的时候,会把他相关联的对象也一并进行相应的操作,相关联的对象意思是指 比如用户和订单,User的实体类中,存在着Order对象的引用变量,如果保存Order对象的引用变量有值的话,则该值就是相关联的对象,并且在对User进行save时,如果保存Order对象的引用变量有值,那么就会将Order对象也进行save操作,
这个就是级联的作用。cascade的值如下:
(1)all:
所有情况下均进行关联操作,即save-update和delete。
(2)none:
所有情况下均不进行关联操作。这是默认值。 
(3)save-update:
在执行save/update/saveOrUpdate时进行关联操作。 
(4)delete:
在执行delete 时进行关联操作。
(5)all-delete-orphan:
当一个节点在对象图中成为孤儿节点时,删除该节点

4、因为Hibernate本身提供了反向生成的机制,所以,我们也可以先在数据库中建立好t_user表和t_order表,然后在DB Browser界面选中两张表,然后选择hibernate反向生成机制,hibernate会自动帮我们生成User.java类和Order.java类,并且会自动生成User.hbm.xml映射文件和Order.hbm.xml映射文件,也会在hibernate.cfg.xml中自动帮我们配置好映射文件,我们只需要编写测试类便可以。使得我们省去了很多的代码编写工作。但是,如果对映射文件不熟悉的情况下,建议自己手写映射文件,深入学习了解。(注意:hibernate默认是按照双向一对多的关系生成)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: