zoukankan      html  css  js  c++  java
  • hibernate系列之四

    数据库中表之间的关系:

    一对一、一对多、多对多

    一对多的建表原则:在多的一方创建外键指向一的一方的主键;

    多对多的建表原则:创建一个中间表,中间表中至少有两个字段作为外键分别指向多对多双方的主键;

    一对一建表原则:唯一外键对应:假设一对一中的任意一方为多,在多的一方创建外键指向一的一方的主键,将外键设置为唯一

          主键对应:一方的主键作为另一方的主键;

    在hibernate中采用java对象关系描述数据表之间的关系:

    一对多的映射关系的实现案例:

    客户实体类:在hibernate系列一中已经实现点击连接查看:https://www.cnblogs.com/wang-xuan/p/9195795.html

    同时在客户实体类中添加属性:

    //一个客户对应多个联系人
    	private Set<LinkMan> linkMans = new HashSet<LinkMan>();
    public Set<LinkMan> getLinkMans() {
    		return linkMans;
    	}
    	public void setLinkMans(Set<LinkMan> linkMans) {
    		this.linkMans = linkMans;
    	}
    

    实现联系人实体类LinkMan:

    package com.itwx.hibernate.pojo;
    
    public class LinkMan {
    
    	private Long lkm_id;
    	private String lkm_name;
    	private String lkm_gender;
    	private String lkm_phone;
    	private String lkm_mobile;
    	private String lkm_email;
    	private String lkm_qq;
    	private String lkm_position;
    	private String lkm_memo;
    	
    	private Customer customer;
    
    	public Long getLkm_id() {
    		return lkm_id;
    	}
    
    	public void setLkm_id(Long lkm_id) {
    		this.lkm_id = lkm_id;
    	}
    
    	public String getLkm_name() {
    		return lkm_name;
    	}
    
    	public void setLkm_name(String lkm_name) {
    		this.lkm_name = lkm_name;
    	}
    
    	public String getLkm_gender() {
    		return lkm_gender;
    	}
    
    	public void setLkm_gender(String lkm_gender) {
    		this.lkm_gender = lkm_gender;
    	}
    
    	public String getLkm_phone() {
    		return lkm_phone;
    	}
    
    	public void setLkm_phone(String lkm_phone) {
    		this.lkm_phone = lkm_phone;
    	}
    
    	public String getLkm_mobile() {
    		return lkm_mobile;
    	}
    
    	public void setLkm_mobile(String lkm_mobile) {
    		this.lkm_mobile = lkm_mobile;
    	}
    
    	public String getLkm_email() {
    		return lkm_email;
    	}
    
    	public void setLkm_email(String lkm_email) {
    		this.lkm_email = lkm_email;
    	}
    
    	public String getLkm_qq() {
    		return lkm_qq;
    	}
    
    	public void setLkm_qq(String lkm_qq) {
    		this.lkm_qq = lkm_qq;
    	}
    
    	public String getLkm_position() {
    		return lkm_position;
    	}
    
    	public void setLkm_position(String lkm_position) {
    		this.lkm_position = lkm_position;
    	}
    
    	public String getLkm_memo() {
    		return lkm_memo;
    	}
    
    	public void setLkm_memo(String lkm_memo) {
    		this.lkm_memo = lkm_memo;
    	}
    
    	public Customer getCustomer() {
    		return customer;
    	}
    
    	public void setCustomer(Customer customer) {
    		this.customer = customer;
    	}
    	
    }
    

     配置LinkMan.hbm.xml的映射文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    	<class name="com.itwx.hibernate.pojo.LinkMan" table="linkman">
    		<id name="lkm_id" column="lkm_id">
    			<generator class="native" />
    		</id>
    		<property name="lkm_name" column="lkm_name" />
    		<property name="lkm_gender" column="lkm_gender" />
    		<property name="lkm_phone" column="lkm_phone" />
    		<property name="lkm_mobile" column="lkm_mobile" />
    		<property name="lkm_email" column="lkm_email" />
    		<property name="lkm_qq" column="lkm_qq" />
    		<property name="lkm_position" column="lkm_position" />
    		<!-- 配置关联对象 -->
    		<!--  
    			many-to-one:代表多对一:
    				name属性:在实体类中的属性:一的一方的对象的名称;
    				class属性:一的一方的类的全路径
    				column:表中的外键,在一的一方中配置的外键;
    		-->
    		<many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
    			column="lkm_cust_id" />
    	</class>
    </hibernate-mapping>
    

     核心配置文件hibernate.cfg.xml

    <!-- 配置加载映射文件:全路径-->
    			<mapping resource="com/itwx/hibernate/pojo/Customer.hbm.xml"/>
    			<mapping resource="com/itwx/hibernate/pojo/LinkMan.hbm.xml"/>
    

     Customer.hbm.xml配置文件添加一对多的关系映射配置

    <!-- 配置多一之间的映射关系 -->
        	<!-- 
        		set标签:name属性:在实体类中的属性,指多的一方的集合的属性名称
        		key标签:column:多的一方的外键的名称
        		one-to-many标签:class属性:多的一方的类的全路径
        	-->
    		<set name="linkMans">
    			<key column="lkm_cust_id" />
    			<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
    		</set>
    

     测试类中进行测试一对多的关系映射

    @Test
    	public void test4() {
    		// 获取当前与线程绑定的session
    		Session session = HibernateUtils.getCurrentSession();
    		// 开启事务
    		Transaction transaction = session.beginTransaction();
    		// 创建关系对象
    		Customer customer = new Customer();// 此处可以使用带参构造方法
    		customer.setCust_name("张三");
    		customer.setCust_source("产品");
    
    		LinkMan linkMan1 = new LinkMan();
    		linkMan1.setLkm_name("周芷若");
    		linkMan1.setLkm_phone("1223445");
    		LinkMan linkMan2 = new LinkMan();
    		linkMan2.setLkm_name("张无忌");
    		linkMan2.setLkm_gender("男");
    		// 建立关系
    		/**
    		 * 首先获取到set集合对象,然后才能进行添加元素; 所以先调用getXXX()方法获取对象,然后add
    		 */
    		// 客户关联联系人
    		customer.getLinkMans().add(linkMan1);
    		customer.getLinkMans().add(linkMan2);
    		// 联系人关联客户
    		linkMan1.setCustomer(customer);
    		linkMan2.setCustomer(customer);
    		// 执行操作
    		session.save(linkMan1);
    		session.save(linkMan2);
    		session.save(customer);
    		// 提交事务
    		transaction.commit();
              //执行结果 /** * Hibernate: insert into linkman (lkm_name, lkm_gender, lkm_phone, * lkm_mobile, lkm_email, lkm_qq, lkm_position, lkm_cust_id) values (?, * ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into linkman (lkm_name, * lkm_gender, lkm_phone, lkm_mobile, lkm_email, lkm_qq, lkm_position, * lkm_cust_id) values (?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into * customer (cust_name, cust_source, cust_industry, cust_level, * cust_phone, cust_mobile) values (?, ?, ?, ?, ?, ?) Hibernate: update * linkman set lkm_name=?, lkm_gender=?, lkm_phone=?, lkm_mobile=?, * lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=? where lkm_id=? * Hibernate: update linkman set lkm_name=?, lkm_gender=?, lkm_phone=?, * lkm_mobile=?, lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=? * where lkm_id=? Hibernate: update linkman set lkm_cust_id=? where * lkm_id=? Hibernate: update linkman set lkm_cust_id=? where lkm_id=? */ }

     级联操作:

    指在主控方执行保存、更新和删除操作时,其关联(被控方)也执行相同操作。在映射文件中通过对cascade属性的设置来控制是否对关联对象采用级联操作,级联操作对各种关联关系都是有效的;

    级联具有方向性:在保存一的一方级联多的一方和在多的一方可以级联一的一方;

    在映射文件中配置cascade=“save-update”;

    级联删除和级联保存、更新:谁是主控方,则可以在映射文件中配置cascade=“delete、save-update”,也可以同时配置;

    级联删除:在set标签中配置cascade=“delete”或者在mony-to-one中配置cascade属性;

    <many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
    			column="lkm_cust_id" cascade="save-update"  />
    

     或者

    <set name="linkMans" cascade="delete,save-update" >
    			<key column="lkm_cust_id" />
    			<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
    		</set>
    

    防止SQL语句冗余:双向维护关系,持久态对象可以自动更新数据库,更新客户的时候会修改一次外键,更新联系人的时候会修改一次外键,所以会产生SQL语句冗余;

    解决方案:一方放弃外键的维护,通常交给多的一方去维护,所以一的一方就需要放弃维护,即需要配置inverse=“true”;

    <set name="linkMans" cascade="delete,save-update" inverse="true">
                <key column="lkm_cust_id" />
                <one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
            </set>
  • 相关阅读:
    LeetCode(287)Find the Duplicate Number
    LeetCode(290) Word Pattern
    LeetCode(205)Isomorphic Strings
    LeetCode(201) Bitwise AND of Numbers Range
    LeetCode(200) Number of Islands
    LeetCode(220) Contains Duplicate III
    LeetCode(219) Contains Duplicate II
    命令行执行Qt程序
    LeetCode(228) Summary Ranges
    redis 的安装和使用记录
  • 原文地址:https://www.cnblogs.com/wx_blog/p/9199286.html
Copyright © 2011-2022 走看看