1.Hibernate的一对多
(1)表与表之间关系
一对多关系
多对多关系
一对一关系
(2)Hibernate的一对多配置
1)搭建Hibernate基本环境
2)创建表
3) 创建实体
一的一方:放的是多的一方的集合
多的一方:放的是一的一方的对象
4) 创建映射
一的一方:配置的
多的一方:配置
5) 编写测试类
(3)Hibernate的一对多的操作
1) 级联操作:cascade,用于操作其关联的对象。
级联保存或更新
级联删除
2)测试对象导航
3)放弃外键维护权:inverse,用户控制是否有外键维护能力
2.Hibernate的多对多
(1)Hibernate的多对多配置
1)搭建Hibernate环境
2)创建表
3)创建实体:放置的是对方的集合
4)创建映射:配置的是对象的
4)编写测试类
(2)Hibernate的多对多操作
1)级联操作
级联保存或更新
级联删除(了解)
2)其他的操作
给用户选择角色
给用户改选角色
给用户删除角色
客户与联系人,一个客户可以拥有多个联系人,但是一个联系人只能有一个客户
客户cst_customer为一的一方,联系人cst_linkman为多的一方
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `cst_linkman` (
`lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
`lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',
`lkm_cust_id` bigint(32) DEFAULT NULL COMMENT '客户id',
`lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',
`lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',
`lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',
`lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',
`lkm_qq` varchar(16) DEFAULT NULL COMMENT '联系人qq',
`lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',
`lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',
PRIMARY KEY (`lkm_id`),
KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
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
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
这里的话多的一方的外键不是使用lik_cust_id表示,而是直接使用客户的对象来表示,因为对象的id就是多的一方的外键
(1)多的一方的映射的创建
(2)一的一方的映射的创建
hibernate.cfg.xml
package com.itheima.hibernate.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* Hibernate
* @author jt
*
*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static{
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession(){
return sf.openSession();
}
public static Session getCurrentSession(){
return sf.getCurrentSession();
}
}
package com.itheima.hibernate.demo1;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.hibernate.domain.Customer;
import com.itheima.hibernate.domain.LinkMan;
import com.itheima.hibernate.utils.HibernateUtils;
/**
* 一对多的测试类
* @author jt
*
*/
public class HibernateDemo1 {
@Test
// 保存2个客户 和 3个联系人 并且建立好关系
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 创建两个客户
Customer customer1 = new Customer();
customer1.setCust_name("王东");
Customer customer2 = new Customer();
customer2.setCust_name("赵洪");
// 创建三个联系人
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("凤姐");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("如花");
LinkMan linkMan3 = new LinkMan();
linkMan3.setLkm_name("旺财");
// 设置关系:
linkMan1.setCustomer(customer1);
linkMan2.setCustomer(customer1);
linkMan3.setCustomer(customer2);
customer1.getLinkMans().add(linkMan1);
customer1.getLinkMans().add(linkMan2);
customer2.getLinkMans().add(linkMan3);
// 保存数据:
session.save(linkMan1);
session.save(linkMan2);
session.save(linkMan3);
session.save(customer1);
session.save(customer2);
tx.commit();
}
一对多只保存一边可以吗?
(例如我们在将想要将一个客户进行删除,那么联动的就需要删除与这个客户相关的联系人,如果我们将联系人和客户用原始的方式进行删除,代码量将会很多。级联相当于我们删除客户会连同其联系人一起删除,反之亦然)
这里我们看到我们只需要保存customer那么与其关联的linkMan也会被保存。
这里发送四条的原因是linkMan1关联了customer,而customer关联了linkMan2和linkMan3,所以一共发了四条
发送三条是因为customer关联了linkMan2和linkMan3,而没有关联linkMan1
linkMan2没有与另外三个关联,所以只发送了一条
删除联系人级联删除客户(基本不用)
用户表
CREATE TABLE `sys_user` (
`user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`user_code` varchar(32) NOT NULL COMMENT '用户账号',
`user_name` varchar(64) NOT NULL COMMENT '用户名称',
`user_password` varchar(32) NOT NULL COMMENT '用户密码',
`user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE `sys_role` (
`role_id` bigint(32) NOT NULL AUTO_INCREMENT,
`role_name` varchar(32) NOT NULL COMMENT '角色名称',
`role_memo` varchar(128) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
中间表(同为主键和外键)
CREATE TABLE `sys_user_role` (
`role_id` bigint(32) NOT NULL COMMENT '角色id',
`user_id` bigint(32) NOT NULL COMMENT '用户id',
PRIMARY KEY (`role_id`,`user_id`),
KEY `FK_user_role_user_id` (`user_id`),
CONSTRAINT `FK_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
用户映射
角色映射
package com.itheima.hibernate.demo2;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.hibernate.domain.Role;
import com.itheima.hibernate.domain.User;
import com.itheima.hibernate.utils.HibernateUtils;
/**
* Hibernate的多对多的映射
* @author jt
*
*/
public class HibernateDemo2 {
@Test
/**
* 保存多条记录:保存多个用户和角色
*/
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 创建2个用户
User user1 = new User();
user1.setUser_name("赵洪");
User user2 = new User();
user2.setUser_name("李兵");
// 创建3个角色
Role role1 = new Role();
role1.setRole_name("研发部");
Role role2 = new Role();
role2.setRole_name("市场部");
Role role3 = new Role();
role3.setRole_name("公关部");
// 设置双向的关联关系:
user1.getRoles().add(role1);
user1.getRoles().add(role2);
user2.getRoles().add(role2);
user2.getRoles().add(role3);
role1.getUsers().add(user1);
role2.getUsers().add(user1);
role2.getUsers().add(user2);
role3.getUsers().add(user2);
// 保存操作:多对多建立了双向的关系必须有一方放弃外键维护。
// 一般是被动方放弃外键维护权。
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
session.save(role3);
tx.commit();
}
不可以只保存一边
1.保存用户级联保存角色
2.保存角色级联保存用户
1.删除用户级联删除角色
2.删除角色级联删除用户
1.给用户选择角色
2.给用户改选角色
3.给用户删除角色