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 one-to-many many-to-one 的配置
hibernate one-to-many 和 many-to-one