一个Customer中有多个Order,删除(增加)Customer同事删除(增加)Order.命名很多不规范,临时写的demo,凑合着....
Customer.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.demo.hibernate.model.Customer" table="CUSTOMER">
<id name="id" type ="java.lang.Integer" column="CID">
<generator class="increment" />
</id>
<property name="username" column="USERNAME" />
<property name="password" column="PASSWORD" />
<set name="order" table="ordertt" inverse="false" cascade="all">
<key column="CID"/>
<one-to-many class="com.demo.hibernate.model.Order"/>
</set>
</class>
</hibernate-mapping>
Order.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.demo.hibernate.model.Order" table="ORDERTT">
<id name="orderId" type ="java.lang.Integer" column="orderId" unsaved-value="0">
<generator class="increment" />
</id>
<property name="id" column="CID" />
<property name="orderName" column="orderName" />
</class>
</hibernate-mapping>
相应的Javabean:
public class Customer {
private int id;
private String username;
private String password;
private Set<Order> order= new HashSet<Order>();
//get和set方法
}
public class Order {
private int orderId;
private int id; //customerid
private String orderName;
}
测试:
package com.demo.hibernate.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import com.demo.hibernate.model.Customer;
import com.demo.hibernate.model.Order;
public class Test {
public static void main(String[] args) {
try {
SessionFactory sf = new Configuration().configure()
.buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
// List<Customer> customers = session.createQuery("select c from Customer as c").list();
// for(Iterator iterator = customers.iterator();iterator.hasNext();) {
// Customer customer= (Customer)iterator.next();
// System.out.println(customer.getId()+ " "+customer.getUsername());
// }
Customer customer = new Customer();
customer.setPassword("customer");
customer.setUsername("customer203");
Order order = new Order();
order.setOrderName("customer203");
Set<Order> orders = new HashSet<Order>();
orders.add(order);
customer.setOrder(orders);
// session.delete(customer);
session.save(customer);
tx.commit();
session.close();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
小结:1.在hibernate中设置级联关系是通过cascade进行设定:
Hibernate: select max(CID) from CUSTOMER
Hibernate: select max(orderId) from ORDERTT
Hibernate: insert into CUSTOMER (USERNAME, PASSWORD, CID) values (?, ?, ?)
Hibernate: insert into ORDERTT (CID, orderName, orderId) values (?, ?, ?)
Hibernate: update ORDERTT set CID=? where orderId=?
3.unsaved-value属性
在进行级联插入时,最初没有对子表的id设置unsaved-value="0",导致抛出如下异常:
Hibernate: select max(CID) from CUSTOMER
Hibernate: insert into CUSTOMER (USERNAME, PASSWORD, CID) values (?, ?, ?)
Hibernate: update ORDERTT set CID=?, orderName=? where orderId=?
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
可以看到原本应该执行insert的sql却执行了update。这就是unsaved-value这个属性的作用了。
我们级联插入数据时,save(customer)时,hibernate根据配置文件找到了子表,同时给子表生成save(order)方法,这个时候根据unsaved-value判断了,
hibernate会根据配置文件,找到order主键,getOrderId();若是orderId与unsaved-value指定的值一样,则表示,此对象尚未持久化,hibernate一系列
逻辑之后,就有了insert,反之就是update。如果不写unsaved-value,很显然,hibernate默认为update。因为sql找不到相应的id,导致报错。
5.我们在查询customer对象时,记住是用createQuery而非createSqlQuery,前者是面向对象查询,后者是纯粹的sql,想要得到customer对象,使用前者
4.Google的时候看到的,一并记下。当hibernate设置级联时,数据库无需任何外键或者触发器之类的操作,都说hibernate效率差,没有验证过,通过触发器
和数据库直接设置外键关联,几者效率如何,有待研究。