Customer.class
package com.an.entity;
import lombok.Getter;
import lombok.Setter;
import java.util.HashSet;
import java.util.Set;
/**
* @Author: WCY
* @Date: 2019/8/27 16:55
*/
@Setter
@Getter
public class Customer {
//客户id
private Integer cid;
//客户名称
private String custName;
//客户级别
private String custLevel;
//客户来源
private String custSource;
//联系电话
private String custPhone;
//手机
private String custMobile;
//在客户实体类中里面表示多个联系人,一个客户对应多个联系人
//hibernate要求使用集合表示多的数据,使用set集合
private Set<LinkMan> linkManSet = new HashSet<LinkMan>();
}
LinkMan.class
package com.an.entity;
import lombok.Data;
/**
* @Author: WCY
* @Date: 2019/8/27 16:56
*/
@Data
public class LinkMan {
//联系人编号
private Integer lkm_id;
//联系人姓名
private String lkm_name;
//联系人性别
private String lkm_gender;
//联系人办公电话
private String lkm_phone;
//在联系人实体类中表示所属客户,一个联系人只能属于一个客户
private Customer customer;
}
特别注意: 两个实体类中,最多只能有一个实体类包括对方的元素这里就是customer的toString有List<LinkMan>对象,LinkMan中的toString不能有Customer对象,否则导致堆栈溢出
LinkMan.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--class标签 name:实体类的全路径
table:数据库表的名称-->
<class name="com.an.entity.LinkMan" table="t_linkman">
<!--配置实体类中id和表中id对应-->
<id name="lkm_id" column="lkm_id">
<!--设置数据库表的自增长策略
native:生成表id值就是主键自增长-->
<generator class="native"/>
</id>
<property name="lkm_name" column="lkm_name"/>
<property name="lkm_gender" column="lkm_gender"/>
<property name="lkm_phone" column="lkm_phone"/>
<!--表示联系人所属客户
name属性:因为在联系人实体类中使用customer对象表示,写的是customer名称
class属性:customer全路径
column属性:外键名称-->
<many-to-one name="customer" class="com.an.entity.Customer" column="cid"/>
</class>
</hibernate-mapping>
Customer.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--class标签 name:实体类的全路径
table:数据库表的名称-->
<class name="com.an.entity.Customer" table="t_customer">
<!--配置实体类中id和表中id对应-->
<id name="cid" column="cid">
<!--设置数据库表的自增长策略
native:生成表id值就是主键自增长-->
<generator class="native"/>
</id>
<property name="custName" column="custName"/>
<property name="custLevel" column="custLevel"/>
<property name="custSource" column="custSource"/>
<property name="custPhone" column="custPhone"/>
<property name="custMobile" column="custMobile"/>
<!--在客户映射文件中,表示所有的联系人
使用set标签中有name属性: 属性值写在客户实体类中表示联系人的set集合名称-->
<set name="linkManSet" cascade="save-update">
<!--一对多建表需要外键
hibernate机制: 双向维护外键,在一和多的那一方都配置外键
column属性值: 外键名称-->
<key column="cid"/>
<!--客户所有联系人,class中写联系人所有联系人实体类的全路径-->
<one-to-many class="com.an.entity.LinkMan" />
</set>
</class>
</hibernate-mapping>
hibernate核心配置文件
<?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:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--第二部分:配置hibernate信息-->
<!--输出底层的sql语句-->
<property name="show_sql">true</property>
<!--输出底层sql语句格式-->
<property name="format_sql">true</property>
<!--hibernate帮助我们自动创建表,需要配置
update:如果已经有表,更新,如果没有创建-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--配置数据库方言
让hibernate框架识别不同的数据库中特有的语句-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--配置session绑定本地线程-->
<property name="hibernate.current_session_context_class">thread</property>
<!--第三部分:将映射文件放到核心配置文件中-->
<mapping resource="mapper/Customer.hbm.xml"/>
<mapping resource="mapper/LinkMan.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试类
import com.an.entity.Customer;
import com.an.entity.LinkMan;
import com.an.toolkit.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
/**
* @Author: WCY
* @Date: 2019/8/27 17:48
*/
public class HibernateOneToMany {
//一对多的级联保存
@Test
public void addDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
//添加一个客户,为这个客户添加一个联系人
//1 创建联系人和客户对象
Customer customer = new Customer();
customer.setCustName("传智播客");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("lucy");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("911");
//2 把联系人放到客户set集合里面
customer.getLinkManSet().add(linkMan);
//3 保存客户
session.save(customer);
//提交事务
tx.commit();
}catch (Exception e){
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}
//一对多的级联保存(简化版),使用前必须在一方(Customer.hbm.xml)中set标签里配置cascade="save-update"
@Test
public void sampleAddDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
sessionFactory = HibernateUtil.getSessionFactory();
session = sessionFactory.openSession();
//开启事务
tx = session.beginTransaction();
//添加一个客户,为这个客户添加一个联系人
//1 创建联系人和客户对象
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("普通客户");
customer.setCustSource("网络");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("小红包");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("911");
//2.1把联系人放到客户对象的set集合里面
customer.getLinkManSet().add(linkMan);
//3 保存到数据库中
session.save(customer);
//提交事务
tx.commit();
}catch (Exception e){
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}
}