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();
