Hibernate many to one

Posted 冉兵成

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate many to one相关的知识,希望对你有一定的参考价值。

many-to-one
使用表为emp和dept
配置文件中配置
<many-to-one name="dept" class="com.wode.entity.Dept" column="deptNo" />

将两个表关联起来


完成案例增加和查找


注意在我们使用get的时候,当我们正真去使用连接表数据的时候,才会发出sql语句,这是因为hibernate自动使用了延迟加载。
可以在配置文件中修改
<many-to-one name="dept" class="com.wode.entity.Dept" column="deptNo" lazy="false"/>


我们发现这种方式其实是用了两个sql语句进行了查找。我们也可以使用一条sal语句来做这个事情。
many-to-one name="dept" class="com.wode.entity.Dept" column="deptNo" lazy="false" fetch="join"/>

Emp emp=(Emp) session.get(Emp.class, 5);
System.out.println(emp.getDept().getDeptNo());
这里要注意的时候,这种做法只对get方法有作用,如果用HQL就没有用了
  List<Emp> list=session.createQuery("from Emp").list();
  System.out.println(list.get(0).getDept().getDeptNo());
  System.out.println(list.get(1).getDept().getDeptNo());

如果必须要在HQL中使用呢?
  List<Emp> list=session.createQuery("from Emp e left join fetch e.dept").list();
  System.out.println(list.get(0).getDept().getDeptNo());
  System.out.println(list.get(1).getDept().getDeptNo());

 

使用参数根据ID查询用户
Query query=session.createQuery("from Emp e where e.empno=?");
  query.setParameter(0, 7654);
  List<Emp> list=query.list();
  for(Emp emp:list){
   System.out.println(emp.getEname());
   System.out.println(emp.getDept().getDname());
  }

 

one -to-many的使用
1:在dept表中进行关系管理
Set<Emp> emps=new HashSet<Emp>();

在配置文件中修改
<set name="emps">
         <key column="deptNo"></key>
         <one-to-many class="com.wode.entity.Emp"/>
</set>

完成查找
Dept dept=(Dept) session.get(Dept.class, 10);
  System.out.println(dept.getDname());
  Set<Emp> sets=dept.getEmps();
  for(Emp emp:sets){
   System.out.println(emp.getEname());
  }


注意这里默认的使用就是延迟加载,为了性能。
我们可以这样设置
 <set name="emps" lazy="false">

 

完成订单和订单条目实验
order item

案例1:新增
  Order order=new Order();
  order.setCreateDate(new Date());
  
  Item item=new Item();
  item.setProductName("iphone");
  item.setPrice(new BigDecimal("90.90"));
  item.setAmount(2);
  item.setOrder(order);
  
  Item item2=new Item();
  item2.setProductName("ipad");
  item2.setPrice(new BigDecimal("190.90"));
  item2.setAmount(1);
  item.setOrder(order);
  order.getItems().add(item);
  order.getItems().add(item2);
  session.save(order);
  Transaction tx=session.beginTransaction();
  tx.commit();

我们发现报错了?为什么呢?
 <set name="items" cascade="all">我们需要这样配置
级联操作all 代表所有的。当然我们如果只是增加和修改的话可以配置为save-update


这里还可以继续加入属性inverse="true" 根据名字我们就能得知,作用是将控制权反转。最好都是由many方去维护的。想想我们的外键建立也是这样做的。

 

删除订单。
  Order order=new Order();
  order.setId(8);
  session.delete(order);
  Transaction transaction=session.beginTransaction();
  transaction.commit();
发现这样错误。在hibernate中必须先去查一次再删除。
修改
// Order order=new Order();
//  order.setId(8);
//  session.delete(order);
  Order order=(Order) session.get(Order.class, 8);
  session.delete(order);
  Transaction transaction=session.beginTransaction();
  transaction.commit();

这样就可以了。但是必须要注意的是cascade="all"级联操作必须这样做,当然如果只为删除的话就可以写成cascade="delete"


实验:删除order中的某一个item
 Order order=(Order) session.get(Order.class, 11);
  Set<Item> items=order.getItems();
  System.out.println(items.size());
  Iterator<Item> it=items.iterator();
  while(it.hasNext()){
   if(it.next().getProductName().equals("ipad")){
    it.remove();
   }
  }
  System.out.println(items.size());
  Transaction transaction=session.beginTransaction();
  transaction.commit();

实验成功,但是数据库的数据没有发生改变。

关键是级联
我们修改 <set name="items" cascade="all-delete-orphan" inverse="true">这样就可以了,那想想cascade的值有哪些呢?

 

 

实验:通过get获取order这时候发现, lazy="false"设置延迟加载关闭,发现多次请求
同样的这里可以这样设置fetch="join"

 

实验,查找所有的订单以及所有订单里面的条目
@Test
 public void findAll(){
  List<Order> orders=session.createQuery("from Order").list();
  for(Order order:orders){
   System.out.println(order.getCreateDate()+" "+order.getId());
   for(Item item:order.getItems()){
    System.out.println(item.getProductName()+" "+item.getPrice());
   }
  }
 }

发现有多条sql语句,如果我只想一条sql语句怎么办呢?
再次强调,xml中的fetch只能对get有效的
修改sql语句
List<Order> orders=session.createQuery("from Order o join fetch o.items").list();
但是new question coming??????

修改sql成为
 List<Order> orders=session.createQuery("select distinct(a) from Order a join fetch a.items").list();

以上是关于Hibernate many to one的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate关系映射之many-to-many

Hibernate one-to-many many-to-one 的配置

hibernate one-to-many 和 many-to-one

hibernate关联关系

一XML文件两个many to one映射带出的问题(hibernate)

hibernate_exercise-many- to-one