Hibernate入门(七)一对多入门案例
一对多
场景模拟:用户(一)对订单(多)
1.建表
创建客户表,字段有:客户id,客户姓名,客户性别,客户年龄,客户年纪,客户电话。
创建订单表,字段有:订单编号,明细编号,客户编号(外键)
DROP TABLE IF EXISTS ordersA; DROP TABLE IF EXISTS customerA;
CREATE TABLE customerA( cust_id TINYINT PRIMARY KEY AUTO_INCREMENT, cust_name VARCHAR(30), cust_gender CHAR(5), cust_age SMALLINT, cust_phone VARCHAR(20) ); CREATE TABLE ordersA( order_id VARCHAR(50) PRIMARY KEY, detail_id VARCHAR(50), cust_order_id TINYINT, CONSTRAINT fk_customerA_ordersA FOREIGN KEY(cust_order_id) REFERENCES customerA(cust_id) ON DELETE CASCADE );
2.创建项目,配置hibernate.cfg.xml主配置文件
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定session与当前线程绑定 --> <property name="hibernate.current_session_context_class">thread</property> </session-factory> </hibernate-configuration>
3.创建实体
创建用户实体类:基本属性+配置一对多的属性(set集合存储多个订单)
创建订单实体类:基本属性+配置多对一的属性(Customer类存储客户实体)
package deep.domain; import java.io.Serializable; import java.util.HashSet; import java.util.Set; /** * 客户实体类 * @author DeepSleeping * */ public class Customer implements Serializable { private static final long serialVersionUID = 1L; private Integer cust_id; private String cust_name; private String cust_gender; private Integer cust_age; private String cust_phone; /* * 一对多 * */ private Set<Order> ods = new HashSet<Order>(); public Integer getCust_id() { return cust_id; } public void setCust_id(Integer cust_id) { this.cust_id = cust_id; } public String getCust_name() { return cust_name; } public void setCust_name(String cust_name) { this.cust_name = cust_name; } public String getCust_gender() { return cust_gender; } public void setCust_gender(String cust_gender) { this.cust_gender = cust_gender; } public Integer getCust_age() { return cust_age; } public void setCust_age(Integer cust_age) { this.cust_age = cust_age; } public String getCust_phone() { return cust_phone; } public void setCust_phone(String cust_phone) { this.cust_phone = cust_phone; } public Set<Order> getOds() { return ods; } public void setOds(Set<Order> ods) { this.ods = ods; } }
package deep.domain; import java.io.Serializable; /** * 订单实体类 * @author DeepSleeping * */ public class Order implements Serializable{ private static final long serialVersionUID = 1L; private String order_id; private String detail_id; /* * 多对一 */ private Customer cst; public String getOrder_id() { return order_id; } public void setOrder_id(String order_id) { this.order_id = order_id; } public String getDetail_id() { return detail_id; } public void setDetail_id(String detail_id) { this.detail_id = detail_id; } public Customer getCst() { return cst; } public void setCst(Customer cst) { this.cst = cst; } }
4.配置实体的映射文件:Customer.hbm.xml,Order.hbm.xml
Customer.hbm.xml中的set标签对中:
set:存储多的一方的集合 name:存储多的一方的集合属性名
key标签对:配置外键
column:是数据库中外键的字段名(注意这里写的名一定要与后面多方中配置外键的名称一致,否则就会创建多个外键)
<one-to-many> 是表示,我这里是一对多,对的多的一方的实体类的路径是:class = "order"(这里只写order是因为在配置文件中我已经用package定位到实体类的包下了)
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="deep.domain"> <class name="Customer" table="customera"> <id name="cust_id" column = "cust_id"> <generator class="native"></generator> </id> <property name="cust_name" column = "cust_name"></property> <property name="cust_gender" column = "cust_gender"></property> <property name="cust_age" column = "cust_age"></property> <property name="cust_phone" column = "cust_phone"></property> <!-- 配置一对多属性 --> <set name="ods"> <key column="cust_order_id"></key> <one-to-many class="Order"/> </set> </class> </hibernate-mapping>
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="deep.domain"> <class name="Order" table="ordersa"> <id name="order_id" column = "order_id"> <generator class="uuid"></generator> </id> <property name="detail_id" column = "detail_id"></property> <!-- 配置多对一属性 --> <many-to-one name="cst" column="cust_order_id" class="Customer"/> </class> </hibernate-mapping>
5.在主配置文件中引入两个实体对应的映射文件
<mapping resource="deep/domain/Customer.hbm.xml"/> <mapping resource="deep/domain/Order.hbm.xml"/>
6.添加订单到客户id为1的客户中
package deep.test; import java.util.UUID; import org.hibernate.Session; import org.junit.Test; import deep.common.HibernateUtils; import deep.domain.Customer; import deep.domain.Order; public class TestClass { /** * 添加订单到客户 */ @Test public void fun(){ Session session = HibernateUtils.getSession(); session.getTransaction().begin(); try { //获取客户 持久 Customer cst = session.get(Customer.class, 1); //新建订单 瞬时 Order od = new Order(); od.setOrder_id(UUID.randomUUID().toString()); od.setDetail_id(UUID.randomUUID().toString()); //表达客户和订单的关系 cst.getOds().add(od); //表达订单和客户的关系 od.setCst(cst); //持久化订单 session.save(od); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } session.getTransaction().commit(); } }
添加订单成功!