Hibernate使用入门详解(3)

提纲:
1.表与表之间的关系
2.hibernate一对多操作
(1)一对多映射配置
(2)一对多级联保存
(3)一对多级联删除
(4)inverse属性
3.hibernate多对多操作
(1)多对多映射配置
(2)多对多级联保存
(3)多对多级联删除
(4)维护第三张表

###1.表与表之间的关系
####一对多(客户和联系人)
(1)分类和商品关系,一个分类里面有多个商品,一个商品只能属于一个分类
(2)客户与联系人是一对多关系
客户:与公司有业务往来,百度,新浪,360
联系人:公司里面的员工,百度里面有很多员工,练习员工相当于练习客户
公司和公司员工的关系,客户是一,联系人是多:
一个客户里面有多个联系人,一个联系人只能属于一个客户
(3)一对多建表,通过外键建立关系
在多的那一方创建字段作为外键,指向少的那一方的主键

####多对多(用户和角色)
(1)订单和商品的关系,一个订单里面有多个商品,一个商品属于多个订单
(2)用户和角色关系
用户:小王,小马,小宋
角色:总经理,秘书,司机,保安
一个用户可以多个角色,一个角色可以多个用户
一对一
(1)一个男人对应一个老婆,一个女人对应一个老人

###Hibernate的一对多操作(重点)
####一对多的映射关系
以客户和联系人为例,客户是一,联系人是多
第一步 创建实体类(这里我创建的是Customer和LinkMan两个实体类)
第二步 让两个实体类之间互相进行表示

      (1)在客户实体类里面表示多个联系人
         一个客户里面有多个联系人 
             //hibernate要求使用集合表示多的数据,使用set集合
          	private Set<LinkMan> setLinMan=new HashSet<LinkMan>();         	
          	public Set<LinkMan> getSetLinMan() {
          		return setLinMan;
          	}
          	public void setSetLinMan(Set<LinkMan> setLinMan) {
          		this.setLinMan = setLinMan;
          	}
      (2)在联系人实体类中里表示所属客户
         一个联系人只能属于一个客户
            private Customer customer;
            public Customer getCustomer() {
          		return customer;
          	}          
          	public void setCustomer(Customer customer) {
          		this.customer = customer;
          	}

第三步 配置映射文件
(1)一般一个实体类对应一个映射文件
(2)把映射最基本的配置完成
(3)在映射文件文件中,配置一对多关系
在客户映射文件中,表示所有联系人

                 <!--  在客户映射文件中,表示所有联系人 
             			使用set标签表示所有联系人
             			set标签name属性,属性值写在客户实体类里面表示联系人的set集合名称
             		 -->
             		<set name="setLinkMan">
             			<!-- 一对多键表,有外键
             				hibernate机制,双向维护外键,在一和多的那一方配置外键
             				column属性值,外键名称
             			-->
             			<key column="clid">
             			</key>
             			<!-- 客户所有的联系人,class里面写联系人实体类全路径 -->
             			<one-to-many class="cn.lawfree.entity.LinkMan"/>
             		</set>

在联系人映射文件中表示所有的客户

             		<!-- 表示联系人所属客户
             			name属性.因为联系人实体类使用customer对象表示,写customer名称
             			clas属性,customer全路径
             			colmn属性,外键名称
             		 -->
             		<many-to-one name="customer" class="cn.lawfree.entity.Customer" column="clid">   		
             		</many-to-one>
          第四步 创建核心配置文件,把映射文件放到核心配置文件中      
               <mapping resource="cn/lawfree/entity/Customer.hbm.xml"/>
		           <mapping resource="cn/lawfree/entity/LinkMan.hbm.xml"/> 

####一对多级联操作
#####1.级联保存
(1)添加一个客户,为这个客户添加多个联系人

              // 一对多级联保存 (复杂写法)
            	@Test
            	public void testAddDemo1() {
            		SessionFactory sessionFactory = null;
            		Session session = null;
            		Transaction tx = null;
            		try {
            			// 得到sessionFaction
            			sessionFactory = HibernateUtils.getSessionFactory();
            			// 得到session
            			session = sessionFactory.openSession();
            			// 开启事务
            			tx = session.beginTransaction();
            
            			// 添加一个客户,为这个添加联系人
            			// 1.创建客户和联系人对象
            			Customer customer = new Customer();
            			customer.setCustName("传智播客");
            			customer.setCustLevel("vip");
            			customer.setCustSource("网络");
            			customer.setCustPhone("110");
            			customer.setCustPhone("999");
            
            			LinkMan linkman = new LinkMan();
            			linkman.setLkm_name("lucy");
            			linkman.setLkm_gender("男");
            			linkman.setLkm_phone("911");
            
            			// 2.在客户表示所有联系人,再联系人表示客户
            			// 建立客户对象和联系人对象关系
            			// 2.1把联系人放到客户对象的set集合里面
            			customer.getSetLinkMan().add(linkman);
            			// 2.2把客户对象放到联系人里面
            			linkman.setCustomer(customer);       
            			// 3.保存到数据库
            			session.save(customer);
            			session.save(linkman);
            
            			// 提交事务
            			tx.commit();           
            		} catch (Exception e) {
            			tx.rollback();
            		} finally {
            			session.close();
            			sessionFactory.close();
            		}
            	}

一对多级联保存 (简化写法)
第一步 在客户映射文件中进行配置
在客户映射文件里面set标签中配置

                <set name="setLinkMan" cascade="save-update">

第二步 创建客户和联系人对象,只需要把联系人放到客户里面就可以了,最终只需要保存客户就可以了.

                 // 2.在客户表示所有联系人,再联系人表示客户
          			customer.getSetLinkMan().add(linkman);
          			// 3.保存到数据库
          			session.save(customer);  

#####2.级联删除
(1)删除某一个客户,这个客户里面所有联系人都会被删除
(2)具体实现
第一步 在客户映射文件set标签,进行配置属性为cascade,值为delete

                <set name="setLinkMan" cascade="save-update,delete">

第二步 在代码中直接删除客户
根据id查询对象,调用session中的delete方法删除

                	// 1.根据id查询客户对象
            			Customer customer = session.get(Customer.class, 2);
            			// 2.调用方法删除
            			session.delete(customer); 

(3)执行过程
根据id先查询客户
根据外键查联系人
把联系人的外键设置为null
删除联系人与客户
#####3.级联修改
(1)让lucy所属的客户不是网易而是百度

              // 1.根据id查询lucy联系人,根据id查询百度的客户
        			Customer baidu = session.get(Customer.class, 2);
        			LinkMan lucy = session.get(LinkMan.class, 1);
        			// 2.设置持久态对象值
        			// 把联系人放到客户里面
        			baidu.getSetLinkMan().add(lucy);
        			// 把客户放到联系人里面
			        lucy.setCustomer(baidu);   

(2)因为hibernate双向维护外键,在客户和联系人里面都需要维护外键,修改客户时候改了一次外键,修改联系人时又改了一次外键,造成性能下降
解决方式:让其中的一方放弃外键维护
**一对多里面,让其中一方放弃外键维护(让一的那方放弃关系维护)
具体实现:在放弃维护映射文件中进行配置,在set标签上使用

###Hibernate的多对多操作
####多对多映射配置
以用户和角色为例演示
第一步 创建实体类,用户和角色
第二步 让两个实体类之间相互表示
(1) 一个用户里面表示所有的角色,使用set集合

                //一个用户可以有多个角色
              	private Set<Role> setRole=new HashSet<Role>();             
              	public Set<Role> getSetRole() {
              		return setRole;
              	}             
              	public void setSetRole(Set<Role> setRole) {
              		this.setRole = setRole;
              	}

(2) 一个角色有多个用户,使用set集合
// 一个角色有多个用户

              	private Set<User> setUser = new HashSet<User>();            
              	public Set<User> getSetUser() {
              		return setUser;
              	}    
              	public void setSetUser(Set<User> setUser) {
              		this.setUser = setUser;
              	}

第三步 配置映射关系
(1)基本配置
(2)配置多对多关系
在用户里面表示所有的角色,使用set标签

                 <!-- 在用户里面表示所有角色,使用set标签 
               			name属性,角色set集合名称
               			table属性,第三张表名称	
               	 --> 			
               		<set name="setRole" table="user_role">
               			<!-- key标签里面配置 
               				配置当前映射文件在第三张表的外键名称
               			-->
               			<key column="userid"></key>
               			<!-- class 角色实体类全路径
               				column 角色在第三张表的外键名称
               			 -->
               			<many-to-many class="cn.lawfree.manytomany.Role" column="roleid"></many-to-many>
               		</set>
              在角色里面表示所有的用户,使用set标签
                  <!-- 在角色里面表示所有用户,使用set标签 -->
               		<set name="setUser" table="user_role">
               			<!--key标签里面配置
               				角色在第三张表中的配置 
               			-->
               			<key column="roleid"></key>
               			<!-- class 角色实体类的全路径
               				column 角色在第三张表的外键名称
               			 -->
               			 <many-to-many class="cn.lawfree.manytomany.User" column="userid"></many-to-many>
               		</set>    
       第四步 在核心配置中引入配置文件
              <mapping resource="cn/lawfree/manytomany/Role.hbm.xml"/>
               	<mapping resource="cn/lawfree/manytomany/User.hbm.xml"/>

####多对多级联保存
根据用户保存角色
第一步 在用户配置文件set标签中进行配置,cascade值 save-update

           	<set name="setRole" table="user_role" cascade="save-update">

第二步 写代码实现
(1)创建用户和角色对象,把角色放到用户里面,最终保存用户就可以了
(2)

                @Test
              	public void testSave() {
              		SessionFactory sessionFactory = null;
              		Session session = null;
              		Transaction tx = null;
              		try {
              			// 得到sessionFaction
              			sessionFactory = HibernateUtils.getSessionFactory();
              			// 得到session
              			session = sessionFactory.openSession();
              			// 开启事务
              			tx = session.beginTransaction();
              
              			// 添加两个用户,为每个用户添加两个角色
              			// 1.创建对象
              			User user1 = new User();
              			user1.setUser_name("lucy");
              			user1.setUser_password("123");
              
              			User user2 = new User();
              			user2.setUser_name("mary");
              			user2.setUser_password("456");
              
              			Role r1 = new Role();
              			r1.setRole_name("总经理");
              			r1.setRole_memo("总经理");
              
              			Role r2 = new Role();
              			r2.setRole_name("秘书");
              			r2.setRole_memo("总秘书");
              
              			Role r3 = new Role();
              			r3.setRole_name("保安");
              			r3.setRole_memo("保安");
              
              			// 2.建立关系,把角色放到用户里
              			// user1--r1/r2
              			user1.getSetRole().add(r1);
              			user1.getSetRole().add(r2);
              			// user2--r2/r3
              			user2.getSetRole().add(r2);
              			user2.getSetRole().add(r3);
              
              			// 保存用户
              			session.save(user1);
              			session.save(user2);
              
              			// 提交事务
              			tx.commit();
              
              		} catch (Exception e) {
              			tx.rollback();
              		} finally {
              			session.close();
              			sessionFactory.close();
              		}
              	}

####多对多级联删除(了解)
第一步 在set标签进行配置,cascade值delete
第二步 删除用户

        				User lucy=session .get(User.class, 1);
        				session.delete(lucy);

####维护第三张表关系
用户和角色是多对多的关系,维护关系通过第三张表维护
让某个用户有某个角色
第一步 根据id查询用户和角色
第二步 把角色对象放到用户set集合

               // 让某个用户有某个角色
        			// 1.查询lucy总经理
        			User lucy = session.get(User.class, 1);
        			Role role = session.get(Role.class, 3); 
        			// 2.把角色放到用户的set集合里面
		        	lucy.getSetRole().add(role);
            让某个用户没有某个角色  
               第一步 根据id查询用户和角色
               第二步 从用户里面把角色去掉
               // 让某个用户没有有某个角色
        		  	// 1.查询lucy总经理
        		  	User lucy = session.get(User.class, 1);
        		  	Role role = session.get(Role.class, 3);   
        		  	// 2.把角色从用户的set集合里面删掉
          	  	lucy.getSetRole().remove(role);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值