hibernate第三天

1.一对多
customer
linkmen
客户对应多个联系人
一个联系人对应一个用户
1.customer.java

package it.cast.hema.hibernate;

import java.util.HashSet;
import java.util.Set;

public class Customer {
	private Long cust_id;
	private String cust_name;
	private String cust_source;
	private String cust_industry;
	private String cust_level;
	private String cust_linkman;
	private String cust_phone;
	private String cust_mobile;
   //使用set集合,表示一对多关系
	private Set<LinkMan> linkMens = new HashSet<LinkMan>();
	set/get方法
}

linkman.java

public class LinkMan {
	private Long lkm_id;
	private Character lkm_gender;
	private String lkm_name;
	private String lkm_phone;
	private String lkm_email;
	private String lkm_qq;
	private String lkm_mobile;
	private String lkm_memo;
	private String lkm_position;
  
	//表达多对一关系
	private Customer customer ;
}

2.配置customer.xml文件

<hibernate-mapping package="it.cast.hema.hibernate">
     <class name="Customer" table="tb_customer">
         <id name="cust_id">
           <generator class="native"></generator>
         </id>
         <property name="cust_name" column="cust_name"/>
         <property name="cust_source" column="cust_source"/>
         <property name="cust_industry" column="cust_industry"/>
         <property name="cust_level" column="cust_level"/>
         <property name="cust_linkman" column="cust_linkman"/>
         <property name="cust_phone" column="cust_phone"/>
         <property name="cust_mobile" column="cust_mobile"/>
         <!--集合的配置-->
         <!--  
            name:集合的属性名字
            column:关联的外键
            class:关联的实体表
            cascade:级联操作
               save-update:级联保存及更新
               detele:级联删除
            inverse:关系维护,优化性能
            ture:表示放弃维护
            false:默认值
                              一对多时,只能是一的一方有权放弃,而多的一方无权放弃  
         -->
         <set name="linkMens" cascade="save-update" inverse="false">
           <key column="lkm_cust_id"></key>
           <one-to-many class="LinkMan"></one-to-many>
         </set>
     </class>
    </hibernate-mapping>

配置linkmen.xml

<hibernate-mapping  package="it.cast.hema.hibernate">
     <class name="LinkMan" table="tb_linkman">
         <id name="lkm_id">
           <generator class="native"></generator>
         </id>
         <property name="lkm_gender" column="lkm_gender"/>
         <property name="lkm_name" column="lkm_name"/>
         <property name="lkm_phone" column="lkm_phone"/>
         <property name="lkm_email" column="lkm_email"/>
         <property name="lkm_qq" column="lkm_qq"/>
         <property name="lkm_mobile" column="lkm_mobile"/>
         <property name="lkm_memo" column="lkm_memo"/>
         <property name="lkm_position" column="lkm_position"/>
         <!--集合的配置-->
         <!--  
            name:类的属性名字
            column:关联的外键
            class:关联的实体表类名
                                     多对一
         -->
       <many-to-one name="customer" column="lkm_cust_id" class="Customer" cascade="save-update">
       </many-to-one>
     </class>
    </hibernate-mapping>

还需在hibernate.cfg.xml添加映射文件

当中注意的是:一对多配置里面的set标签
这个只是起到外键作用,没有任何业务需求,同理多对一也一样

操作:

public class Demo {
   @Test
   public void fun(){
	  Session session =  HibernateUtils.getCurrentSession();
	  //开启事务
	  Transaction tra = session.beginTransaction();
	  Customer customer= new Customer();
	  customer.setCust_name("创智");
	  LinkMan linkman= new LinkMan();
	  LinkMan linkman1= new LinkMan();
	  linkman.setLkm_name("zhangsan");
	  linkman1.setLkm_name("wangwu");
	  //一对多
	  customer.getLinkMens().add(linkman);
	  customer.getLinkMens().add(linkman1);
	  //多对一
	  linkman.setCustomer(customer);
	  linkman1.setCustomer(customer);
	  session.save(customer);
      session.save(linkman1);
      session.save(linkman);
	  //提交
	  tra.commit();
   }
   
   //测试级联下的save-update
   @Test
   public void fun2(){
	   Session session =  HibernateUtils.getCurrentSession();
		  //开启事务
		  Transaction tra = session.beginTransaction();
		  Customer customer= new Customer();
		  customer.setCust_name("梦想科技");
		  LinkMan linkman= new LinkMan();
		  LinkMan linkman1= new LinkMan();
		  linkman.setLkm_name("wabgfei");
		  linkman1.setLkm_name("haha");
		  //一对多
		  customer.getLinkMens().add(linkman);
		  customer.getLinkMens().add(linkman1);
		  //多对一
		  linkman.setCustomer(customer);
		  linkman1.setCustomer(customer);
		  //保存 级联下的save-update
		  session.save(customer);
	      session.save(linkman1);
	      session.save(linkman);
		  //提交
		  tra.commit();
   }
   
   //测试级联下的删除 删除客户,级联删除联系人
   @Test
   public void fun3(){
	   Session session =  HibernateUtils.getCurrentSession();
		  //开启事务
		  Transaction tra = session.beginTransaction();
		 Customer customer = (Customer) session.get(Customer.class,3l);
		  //级联删除
		  session.delete(customer);
		  //提交
		  tra.commit();
   }
   
   @Test
   //级联操作/保存联系人就会级联保存客户save-update
   public void fun4(){
	   Session session =  HibernateUtils.getCurrentSession();
		  //开启事务
		  Transaction tra = session.beginTransaction();
		  Customer customer= new Customer();
		  customer.setCust_name("科技");
		  
		  LinkMan linkman = new LinkMan();
		  linkman.setLkm_name("wangfei");
		  //一对多
		  customer.getLinkMens().add(linkman);
		  //多对一
		  linkman.setCustomer(customer);
		  //级联保存 //保存客户就会跟着保存联系人
//		  session.save(customer);
		  //级联保存 //保存联系人就会跟着保存客户
		  session.save(linkman);
		  //提交
		  tra.commit();
		  
//  为什么要使用级联操作就是为了简化几行代码,但是不建议使用那啥就是delete
   }
}

3.多对多
关系表达:
在这里插入图片描述

对象中的表达

  public class Role {
   private Long role_id;
   private String name;
   //多对多使用set集合表示
   private Set<User> users = new HashSet<User>();
  }  
public class User {
  private Long user_id;
  private String name;
  private Set<Role> roles = new HashSet<Role>();
 }     

配置role.xml文件

```java
 <hibernate-mapping  package="it.hema.hebinate.manyandmany">
     <class name="Role" table="tb_role">
         <id name="role_id">
           <generator class="native"></generator>
         </id>
         <property name="name" column="name"/>
         <!--集合配置多对多`
            name:集合属性名称
            table:配置中间表名
            key:
               column:别人引用我的外键名称
               
               class:类名
            many-to-many:
                Class:我与那个类有关系       
                column:我引用别人的外键名称  
            inverse:放弃维护 
                              在多对多查询当中,一定要放弃要有一方放弃维护资格
         -->
         
         <set name="users" table="tb_role_user" inverse="true">
           <key column="role_id"></key>
          <many-to-many class="User" column="user_id"></many-to-many>
         </set>
     </class>
    </hibernate-mapping>      

user.xml

<hibernate-mapping  package="it.hema.hebinate.manyandmany">
     <class name="User" table="tb_user">
         <id name="user_id">
           <generator class="native"></generator>
         </id>
         <property name="name" column="name"/>
         <!--集合配置多对多
            name:集合属性名称
            table:配置中间表名
            key:
               column:别人引用我的外键名称(相当于我的主键)
               
               class:类名
            many-to-many:
                Class:我与那个类有关系       
                column:我引用别人的外键名称 (相当于别人的主键)
         -->
         <set name="roles" table="tb_role_user"  inverse="false">
           <key column="user_id"></key>
          <many-to-many class="Role" column="role_id"></many-to-many>
        </set>
     </class>
    </hibernate-mapping>

操作:

public class Demo {

	@Test
	public void fun() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		Role role = new Role();
		role.setName("清洁");
		Role role1 = new Role();
		role.setName("总裁");

		User user = new User();
		user.setName("wangfeifei");

		// 多对多
		user.getRoles().add(role1);// wangfeifei即使总裁又是清洁工
		user.getRoles().add(role);
		
		session.save(user);
		session.save(role);
		session.save(role1);
		// org.hibernate.exception.ConstraintViolationException:
		// Could not execute JDBC batch update
		// Caused by: java.sql.BatchUpdateException: Duplicate entry '9-8' for
		// key 'PRIMARY'
		// at com.mysql.jdbc.PreparedStatement.executeBatchSerially
		// 导致此异常的原因是因为:2张表保存时会同时维护各自的业务,这会涉及到对方表,所以会导致主键重复冲突
		// 解决方法是在任意一张表当中的set键配置inverse="ture"放弃维护
		tx.commit();
	}

	// 为用户增添一个角色
	@Test
	public void fun3() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		//添加一个角色
		Role role = new Role();
		role.setName("保洁");
		//获取用户
		User user= (User)session.get(User.class, 21l);
		user.getRoles().add(role);
		//保存
		session.save(user);
		session.save(role);
		//提交事务 
		tx.commit();
	}
	
	//为用户删除角色
	@Test
	public void fun4(){
	Session  session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	//获取用户
	 User user = (User) session.get(User.class,21L);
	 //获取角色
	 Role role =(Role) session.get(Role.class,32L);
//	 删除用户角色
	 user.getRoles().remove(role);
	 //保存
	 session.save(user);
	 //提交事务
	 tx.commit();
	}
}
  总结:无论是多对一还是多对多都会有外键的存在,不同的是一对多会重新创建一个没有业务的外键来进行关联,而多对多则会采取中间表的形式来关联,也就是提取2个表的主键来进行创建中间表
set里面的集合 key里面是自己的主键,多对多里面则是关联的表和词表的主键   多对多里面还需注意的是,必须要有一方放弃维护,不然就会出现主键重复的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值