一、表间关系回顾
1.一对多
(1)分类和商品的关系,一个分类中有多个商品,一个商品只能属于一个分类
(2)客户和联系人的关系,一个客户里面有多个联系人,一个联系人只能属于一个客户
2.多对多
订单和商品的关系,一个订单中有多个商品,一个商品可以属于多个订单
3.一对一
二、Hibernate的一对多操作
1.一对多映射配置
(1)创建实体类,客户是一,联系人是多
(2)让两个实体类之间互相表示
在客户实体类里面表示多个联系人,一个客户可有多个联系人
在联系人实体类里面表示客户,一个联系人只能属于一个客户
(3)配置映射关系
除了完成两个实体类的最基本映射文件配置,还要配置一对多的关系。
在客户映射文件中,表示所有联系人
在联系人映射文件中,表示所属客户
(4)配置核心配置文件,把映射文件引入到核心配置文件中
2.一对多级联操作
1.级联保存
添加一个客户,为这个客户添加多个联系人
(1)复杂写法
@Test
//复杂写法
public void addDemo1(){
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.setCustLevel("vip");
customer.setCustName("cc");
customer.setCustSource("网络");
customer.setCustMobile("13200222222");
customer.setCustPhone("10086");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("Tom");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("10010");
/*2.在客户中表示联系人,在联系人中表示客户。建立二者之间的联系
* (1)把联系人对象放到客户对象的set集合中
* (2)把客户放到联系人中
* */
customer.getSetLinkMan().add(linkMan);
linkMan.setCustomer(customer);
//3.保存到数据库
session.save(customer);
session.save(linkMan);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
(2)简单写法
根据用户添加联系人,首先在客户映射文件中进行配置。set标签添加一个cascade属性,值为save-update。然后,创建 客户和联系人对象,只需要把联系人放到客户里面就可以了,最后只需保存客户对象。
<set name="setLinkMan" cascade="save-update">
<!-- 一对多关系,有外键
hibernate机制:双向维护外键,即一的一方和多的一方都要配置外键
column属性值为外键名称
-->
<key column="clid"></key>
<!-- 客户所有的联系人,class里面写联系人实体类全路径 -->
<one-to-many class="cn.itcast.entity.LinkMan"/>
</set>
@Test
public void addDemo2(){
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.setCustLevel("vip中p");
customer.setCustName("net");
customer.setCustSource("网络");
customer.setCustMobile("13200333333");
customer.setCustPhone("1008611");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("Jerry");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("1001010");
//2.只需要把联系人放到客户对象中
customer.getSetLinkMan().add(linkMan);
//3.只需保存客户对象
session.save(customer);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
2.级联删除
删除一个客户,里面包含的所有联系人也删除。
(1)在客户映射文件中的set标签中配置,cascade属性加一个delete值
<set name="setLinkMan" cascade="save-update,delete">
(2)
@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, 1);
//2.调用delete方法删除
session.delete(customer);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
3.一对多修改操作
1.把联系人Jerry所属的客户由net改为web
@Test
public void updateDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try{
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
//1.根据id查询对象,先找到联系人Jerry,再找到web客户
LinkMan linkMan = session.get(LinkMan.class, 2);
Customer customer = session.get(Customer.class, 3);
//2.把Jerry对象放到web对象的set集合中,把web客户放到Jerry对象中
customer.getSetLinkMan().add(linkMan);
linkMan.setCustomer(customer);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
2.inverse属性
(1)因为hibernate双向维护外键,在客户和联系人里都要维护,所以修改客户的时候修改了一次外键,修改联系人的时候也修改了一次外键,造成效率问题。
(2)解决方式:让客户放弃维护外键(一对多中一的那方)。在配置文件的set标签中使用inverse属性实现,true为放弃。
<set name="setLinkMan" cascade="save-update,delete" inverse="true">
三、Hibernate的多对多操作
1.多对多映射配置
以用户和角色为例
(1)创建用户和角色实体类
(2)两个实体类相互表示,一个用户表示多个角色,一个角色有多个用户
(3)配置映射关系
在用户里面表示所有角色,使用set标签
在角色里面表示所有用户,使用set标签
(4)在核心配置文件引入映射文件
2.多对多级联保存
根据用户保存角色
(1)在用户配置文件中set标签,cascade值save-update
(2)代码:创建用户和角色对象,把角色放到用户里面去,保存用户
@Test
public void saveDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try{
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
User user1 = new User();
user1.setUser_name("小明");
user1.setUser_password("123");
User user2 = new User();
user2.setUser_name("小刚");
user2.setUser_password("456");
Role role1 = new Role();
role1.setRole_name("司机");
role1.setRole_memo("专车司机");
Role role2 = new Role();
role2.setRole_name("总经理");
role2.setRole_memo("头头");
Role role3 = new Role();
role3.setRole_name("秘书");
role3.setRole_memo("老板助理");
//小明既是司机,又是总经理
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
//小刚既是司机,又是秘书
user2.getSetRole().add(role1);
user2.getSetRole().add(role3);
session.save(user1);
session.save(user2);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
3.多对多级联删除(不用)
4.维护第三张表关系
(1)用户和角色的多对多关系,通过第三张表来维护
(2)让某个用户有某个角色
- 根据id查询用户和角色
- 把角色放到用户里面
@Test
public void tableDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try{
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
User user = session.get(User.class, 1);
Role role = session.get(Role.class, 1);
user.getSetRole().add(role);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}
(3)让某个用户没有某个角色
- 根据id查询用户和角色
- 从用户里面把角色去掉
@Test
public void tableDemo(){
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try{
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
User user = session.get(User.class, 1);
Role role = session.get(Role.class, 2);
user.getSetRole().remove(role);
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
sessionFactory.close();
}
}