一、表与表之间关系回顾
1.一对多:
(1)分类和商品关系(一个分类里面有多个商品,一个商品只能属于一个分类);
(2)公司和公司员工关系(一个公司多个员工,一个员工属于一个公司)
(3)一对多建表,通过外键建立关系
2.多对多:
(1)订单和商品的关系,一个订单里面有多个商品,一个商品属于多个订单;
(2)用户和角色的关系,一个用户多个角色,一个角色可以多个用户;
(3)多对多建表,创建第三张表维护关系
3.一对一(用的不多):中国一夫一妻;
二、hibernate一对多操作(重点)
1 . 一对多映射配置(以客户和联系人为例)
第一步:创建实体类
第二步:让两个实体类之间互相表示
(1)客户实体类里面表示多个联系人
(2)在联系人实体类里面表示所属客户
第三步:配置映射关系
(1)一般一个实体类对应一个映射文件(有多少个实体类配多少个映射文件)
(2)完成最基本的映射配置
(3)在映射文件中,配置一对多关系:在客户映射文件中,配置所有联系人;在联系人映射文件中,表示所属客户;
第四步:创建核心配置文件,把映射文件引入到核心配置文件中
最后,测试是否配置成功,在工具类里面测试
!!!!!气死人了!!!我没有全部跟着老师打,结果出了错,搞了一天才解决,吐血吐血!!大家注意核心配置文件和映射文件的属性名等等一定要和实体类里面定义的一样,不要以为名字是随便取得!!!不然连接不上数据库什么问题就来了————心态崩了
好在后面解决了:
解决之后,数据库会有两个表
2 . 一对多级联操作
(1)级联保存:添加一个客户,为这个客户添加多个联系人
写法一(复杂):
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.itcast.Utils.HibernateUtils;
import cn.itcast.entity.Customer;
import cn.itcast.entity.LinkMan;
public class HibernateOneToMany {
// 演示一对多级联保存
@Test
public void testAddDemo() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 添加一个客户,为这个客户添加一个联系人
// 1.创建客户和联系人对象
Customer customer = new Customer();
customer.setcName("传智播客");
customer.setcLevel("Vip");
customer.setcMobile("999");
customer.setcPhone("1234332");
customer.setcSource("网络");
LinkMan linkman = new LinkMan();
linkman.setLkm_name("lucy");
linkman.setLkm_gender("男");
linkman.setLkm_phone("991");
//2.建立客户对象和联系人对象关系:
//把联系人对象放到客户对象的set集合里面,把客户对象放到联系人里面
customer.getSetLinkMan().add(linkman);
linkman.setCustomer(customer);
session.save(customer);
session.save(linkman);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}finally{
session.close();
sessionFactory.close();
}
}
}
写法二(简化):
——一般根据客户添加联系人
第一步:在客户映射文件中进行配置:set标签进行配置
第二步:创建客户和联系人对象,只要把联系人放到客户里面就可以了,最终只需要保存客户就可以了
// 2.建立客户对象和联系人对象关系:
// 把联系人对象放到客户对象的set集合里面,把客户对象放到联系人里面
customer.getSetLinkMan().add(linkman);
session.save(customer);
transaction.commit();
(2)级联删除:删除某个客户,这个客户里面的所有的联系人也删除
——具体实现:
第一步:在客户映射文件中set标签,进行配置(多个属性值,用英文逗号隔开)
第二步:在代码中直接删除客户:根据id查询对象,调用session里面delete方法删除
// 演示一对多级联删除
@Test
public void deleteDemo() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
//1 根据id查询对象
Customer customer =session.get(Customer.class, 2);
//调用方法delete
session.delete(customer);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}finally{
session.close();
sessionFactory.close();
}
}
——执行过程
1)根据id查询客户
2)根据外键id值查询联系人
3)把联系人外键设为null
4)删除联系人和客户
(3)一对多级联修改
如果我们要修改一对多之间联系人和客户的关系,我们首先根据id找到想要修改对象(客户cid,联系人lkm_id)
然后将联系人添加到客户里面,联系人设置客户
// 演示一对多级联修改
@Test
public void updateDemo() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
/*
* 如果我们要修改一对多之间联系人和客户的关系 ,
我们首先根据id找到想要修改对象(客户cid,联系人lkm_id)
* 然后将联系人添加到客户里面,联系人设置客户
*/
Customer customer = session.get(Customer.class, 3);// 根据3我们找到对应的客户
LinkMan linkman = session.get(LinkMan.class, 1);// 根据1找到对应的联系人
// 2 设置持久态对象值(持久态会自动更新数据库)
// 把联系人放到客户里面:Lucy成百度的联系人
customer.getSetLinkMan().add(linkman);
linkman.setCustomer(customer);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
一对多修改——inverse属性:
(1)因为hibernate双向维护外键,在客户和联系人里面都需要维护外键,修改客户时修改一次外键,修改联系人时也修改一次外键,造成效率问题;
(2)解决方式:让其中一方不维护外键
(3)具体实现:在放弃关系维护映射文件中,进行配置,在set标签上使用inverse属性
待续。