Hibernate关系映射---双向一对多增删查改实例
1、新建一个Java工程,添加hibernate3.3支持,连接test数据库
2、在src下新建com.etc.dao包,在包下新建User.java类:
package com.etc.dao;
import java.util.HashSet;
import java.util.Set;
public class User {
private int userId;
private String userName;
private Set orders = new HashSet();//在一端加入多端的set集合
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Set getOrders() {
return orders;
}
public void setOrders(Set orders) {
this.orders = orders;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName
+ ", orders=" + orders + "]";
}
}
3、在com.etc.dao下新建Order.java类:
4、在com.etc.dao下新建User.hbm.xml映射文件:
5、在com.etc.dao下新建Order.hbm.xml映射文件:
6、配置hibernate.cfg.xml文件:
true
true
thread
org.hibernate.dialect.MySQLDialect
jdbc:mysql://localhost:3306/test
root
root
com.mysql.jdbc.Driver
com.mysql.jdbc.Driver
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 {
/**
* Description:新增:由一端操作多端(不建议),不可行
* @author zoey
* @date 2017年7月26日
*/
@Test
public void testCreate1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = new User();
user.setUserName("zoey");
Order o1 = new Order();
o1.setOrderState("1");
o1.setOrderCreatedate(new Date());
Order o2 = new Order();
o2.setOrderState("0");
o2.setOrderCreatedate(new Date());
//将订单加入到用户中去
user.getOrders().add(o1);
user.getOrders().add(o2);
//保存用户信息:双向关系中不建议设置cascade=all,建议从多端去操作一端(使用多对一的操作)
session.save(user);
session.getTransaction().commit();
}
/**
* Description:新增:由多端操作一端,标准做法,可行,建议使用
* @author zoey
* @date 2017年7月26日
*/
@Test
public void testCreate2(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = new User();
user.setUserName("lan");
Order o1 = new Order();
o1.setOrderState("1");
o1.setOrderCreatedate(new Date());
Order o2 = new Order();
o2.setOrderState("0");
o2.setOrderCreatedate(new Date());
//通过多端去操作一端,增加完订单之后,再增加用户
o1.setUser(user);
o2.setUser(user);
session.save(user);
session.save(o1);
session.save(o2);
session.getTransaction().commit();
}
/**
* Description:删除:一端操作多端(删除用户信息,同时将订单表的用户id设为null),可行
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testDelete1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = (User)session.get(User.class,1);
session.delete(user);
session.getTransaction().commit();
}
/**
* Description:删除:多端操作一端:只是删除订单信息,用户信息还是存在,可行,建议使用
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testDelete2(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Order order = (Order)session.get(Order.class,3);
session.delete(order);
session.getTransaction().commit();
}
/**
* Description:更新:一端操作多端:修改用户,同时修改该用户下的订单 ,可行
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testUpdate1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = (User)session.get(User.class,1);
user.setUserName("zoey");
for(Order order:user.getOrders()){
order.setOrderCreatedate(new Date());
}
session.getTransaction().commit();
}
/**
* Description:更新:多端操作一端:修改订单,同时修改该订单的用户,可行,建议使用
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testUpdate2(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Order order = (Order)session.get(Order.class, 1);
order.setOrderCreatedate(new Date());
order.getUser().setUserName("lan");
session.getTransaction().commit();
}
/**
* Description:查询:一端操作多端:查询用户信息,再查询该用户的订单信息,可行
* (执行两次sql,不建议在set中配置fetch=join)
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testRetrieve1(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
User user = (User)session.get(User.class, 1);
System.out.println(user.getUserName());
for(Order order:user.getOrders()){
System.out.println(order.getOrderCreatedate());
}
session.getTransaction().commit();
}
/**
* Description:查询:多端操作一端:查询订单信息,再查询该订单的用户信息,可行
* (执行两次sql,可以在many-to-one中配置fethc=join),建议使用
* @author zoey
* @date 2017年7月27日
*/
@Test
public void testRetrieve2(){
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Order order = (Order)session.get(Order.class,1);
System.out.println(order.getOrderCreatedate());
System.out.println(order.getUser().getUserName());
session.getTransaction().commit();
}
}
1、一对多双向关系:需要在一端加入多端的配置,也需要在多端加入一端的配置,java代码和xml映射文件中都需要配置相应的信息。于是,对于增删查改操作,我们基本都可以有两种选择:由一端操作多端、由多端操作一端。但是,我们建议,把一对多双向看成多对一单向,也就是,所有的增删查改操作都有多端来操作一端。
2、一对多双向关系中,不建议在一端配置cascase=all或者fetch=join属性。但是可以在多端的映射文件中配置。
3、可以在一端的映射文件中配置inverse=true,表示一端放弃控制多端。
之后,所有的增删查改操作都有多端来控制一端。
所以,我们只需要把一对多双向,想成多对一关系来操作就可以了。