创建联系人表
联系人表 与客户表是多对一的关系,所以在联系人表中应该添加一个外键与客户表的主键相关联,通过外键指定联系人所属客户,外键作用:为了数据完整性
设计联系人表:
创建联系人映射文件
一对多和多对一映射配置
一个客户有多个联系人,客户到联系人为一对多关系。
一个联系人只有属于一个客户,联系人到客户多对一关系。
hibernate提供一对多、多对一映射关系。
1. 一对多
客户方
属于一方,配置set属性:
在客户的映射文件中配置:
2.多对一
在联系人中配置多对一关系:
在联系人映射文件配置:
测试
1.测试客户和联系人同时添加的操作:
(code)
//父表(客户)与子表(联系人)同时添加
@Test
public void test1() {
//创建session
Session session = HibernateUtil.openSession();
//开事务
session.beginTransaction();
//创建客户对象
CstCustomer cstCustomer = new CstCustomer();
cstCustomer.setCustName("大哥哥");
//创建联系人对象
CstLinkman cstLinkman = new CstLinkman();
cstLinkman.setLkmName("小哥哥");
//建立关系
//客户包括联系人
cstCustomer.getCstLinkmans().add(cstLinkman);
//联系人所属客户
cstLinkman.setCstCustomer(cstCustomer);
//保存
session.save(cstCustomer);
session.save(cstLinkman);
//提交事务
session.getTransaction().commit();
session.close();
}
2.测试已有客户添加联系人的操作:
(code)
//已有父表(客户)单独添加子表(联系人)
@Test
public void test2() {
//创建session
Session session = HibernateUtil.openSession();
//开事务
session.beginTransaction();
//查询出已有客户,此对象是持久态
CstCustomer cstCustomer = session.get(CstCustomer.class, 101l);
//创建联系人对象
CstLinkman cstLinkman = new CstLinkman();
cstLinkman.setLkmName("小哥哥2");
cstLinkman.setCstCustomer(cstCustomer);
//通过持久态对象添加联系人
cstCustomer.getCstLinkmans().add(cstLinkman);
//提交事务
session.getTransaction().commit();
session.close();
}
方法:通过客户持久态对象添加联系人
控制台出现错误:
object references an unsaved transient instance - save the transient instance
解决:commit之前将瞬时态转成持久态,使用hibernate级联保存方法解决。 在CstCustomer.hbm.xml中配置cascade:
观察控制台,打出一条多条的sql:
上边打出多余sql的原因,当前一对多、多对一的关系由一方来维护的。
解决方法:让关系的维护方变为多方。
3.测试删除客户的操作:
子表中有外键指向客户表,只删除客户,报错外键约束错误:
a foreign key constraint fails (crm_hibernate0120
.cst_linkman
, CONSTRAINT FK_cst_linkman_lkm_cust_id
FOREIGN KEY (lkm_cust_id
) REFERENCES cst_customer
(cust_id
) ON DELETE NO ACTION ON UPDATE NO ACTION)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
解决方法:
删除父表之前要先删除相关联子表记录。
采用hibernate提供级联删除方法,hibernate在删除客户之前将子表记录删除。
在CstCustomer.hbm.xml中配置cascade=”delete”>
功能实现-新增联系人
1.联系人dao
(code)
public class CstLinkmanDaoImpl implements CstLinkmanDao{
@Override
public void insert(CstLinkman cstLinkman) {
//打开session和当前线程绑定
Session session = HibernateUtil.getCurrentSession();
session.save(cstLinkman);
}
2.联系人service
业务接口:
功能:新增联系人,方法是已有客户单独添加联系人
public class LinkmanServiceImpl implements LinkmanService{
@Override
public void insertLinkman(Long custId, CstLinkman cstLinkman) {
//获取一个当前线程绑定session
Session session = HibernateUtil.getCurrentSession();
session.beginTransaction();
try {
//查询出客户
CstCustomer cstCustomer = session.get(CstCustomer.class, custId);
//设置客户Id
cstLinkman.setCstCustomer(cstCustomer);
//通过持久态对象添加联系人
cstCustomer.getCstLinkmans().add(cstLinkman);
//提交事务
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtil.closeCurrentSession();
}
}
}