• hibernate之关联映射


    No.1

    映射一对多双向关联关系:

    当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象。

    步骤一:

    注意:hibernate要求在持久化类中定义集合类属性时,必须把属性类型设置为接口类型(如:java.util.Set)

    优点:声明接口类型可以提高持久化类型的透明性,当hibernate调用setEmp()时,传递的参数是hibernate自定义的该接口的类的实例,

    如果把setEmp()设置成java.util.HashSet,就强迫hibernate只能把HashSet类的实例作为参数传递。

    例:

    javabean

    public class Department {
        private Integer id;
        private String name;
        private Set<Employee> employees=new HashSet<Employee>();     
        @Override
        public String toString() {
            return "Department [id=" + id + ", name=" + name +"]";
        }
        //get,set方法省略.....
    }
         ☆定义Employee类
     public class Employee {
        private Integer id;
        private String name;
         private Department dept;
         //get,set方法省略.....
     }

    这样可以提高程序的健壮性,避免应用程序访问取值为null的Emp集合而抛出的空指针异常,因为该集合不为null。

    步骤二:

    编写hbm.xml配置文件

    1.

    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     
     <hibernate-mapping package="entity">
         <class name="Dept" table="DEPT">
             <id name="did" type="int" column="DID">
                 <generator class="native">
                 </generator>
             </id>
             <property name="name" type="string" column="NAME"/>
             <set name="set" cascade="save-update" inverse="true">
               <key column="deptNo"></key> <!-- key:这里是多的一方定义的外键 -->
               <one-to-many class="Emp"/>  <!-- 多的一方的实体类型 -->
            </set>
         </class>    
     </hibernate-mapping>

    2.

    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     
     <hibernate-mapping package="entity">
         <class name="Emp" table="EMP">
             <id name="eid" type="int" column="EID">
                 <generator class="native">
                 </generator>
             </id>
             <property name="ename" type="string" column="ENAME"/>
             <many-to-one name="dept" class="Dept" column="deptNo"></many-to-one>
         </class>    
     </hibernate-mapping>
    
    

     

    <set>元素包含以下属性:

    1)name:设定待映射的持久化类的属性名,这里为dept类的set属性。

    2)cascade:当取值为“save-update",表示级联保存和更新。

    <set>元素还包含两个子元素:<key>和<one-to-many>,<one-to-many>元素设定所关联的持久化类,此处为Dept类,<key>元素

    设定与所关联的持久化类对应的表的外键(也就是多的一方定义的外键)。

    而hibernate从此配置获取以上信息:

    *<set>元素表明emp集合:类型为java.util.Set

    *<class>子元素表明emp集合中存放的一组emp对象。

    *<key>子元素表明emp通过deptNo参照dept表。

    *cascade属性取值“save-update“,表明当保存更新dept时,会级联保存或更新Emp集合中的数据!

    步骤三:

    大配置如下:

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    
    
        <session-factory>
    
            <!-- Database connection settings 数据库连接设置-->
            <!-- 驱动类 -->
            <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
            <!-- url地址 -->
            <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
            <property name="connection.username">Y2162</property>
            <property name="connection.password">1</property>
    
            <!-- SQL dialect  (SQL 方言) -->
            <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
    
    
            <!--在控制台打印后台的SQL语句 -->
            <property name="show_sql">true</property>
            
            
            <!-- 格式化显示SQL -->
            <!-- <property name="format_sql">true</property> -->
            
    
            
            <!-- 自动生成student表 -->
             <property name="hbm2ddl.auto">update</property>  
            <!-- 关联小配置 -->
            <mapping resource="entity/Emp.hbm.xml" />
            <mapping resource="entity/Dept.hbm.xml" />
            <!-- <mapping class="cn.happy.entity.Grade"/> -->
            
        </session-factory>
        </hibernate-configuration>

    步骤四:编写测试类

    public static void one()
        {
            Dept de=new Dept();
            Emp em=new Emp();
            Session session = ElectronicUtil.getSession();
            Transaction tx = session.beginTransaction();
            de.setName("运维部");
            em.setEname("发哥");
            em.setDept(de);
            de.getSet().add(em);
            session.save(de);
            tx.commit();
            System.out.println("success");
            session.close();
        }

    一对多双向关联完成!!!!!

    浅谈cascade和inverse

    1:首先明确cascade和inverse的作用:

    inverse:决定是否把对象中集合的改动反映到DB中,所以inverse只对集合起作用,也只有one-to-many和many-to-many有效,因为只有这两种关系有集合(而many-to-one和one-to-one只含有关系对方的一个引用)

    cascade:决定是否把对象的改动反映到DB中,所以,cascade对所有的关联关系都起作用。

    2:inverse:inverse所描述的是对象之间关联关系的维护方式。

       inverse:只存于集合标记的元素中。

       inverse的作用是:把对象中对集合的改动反映到DB中

       inverse的默认值是:false,表示集合的改动反映到DB中,inverse:false为主动方,由主动方负责维护关联关系。

       inverse为true:表示不将改动过的集合反映到数据库中。

       一对多:该属性在多的一方。应在少的一方设置inverse属性:true,而多的一方设置为false,这说明关联关系由多的一方来维护,如果

       要少的一方维护,就会使插入或删除时一方去update多的一方每一个与这个对象有关系的对象,如果交给多的一方来维护,则会大大提高

       了效率(因为关系就是在多的一方中,直接插入或删除就好了嘛)

       多对多:属性存在独立表中。inverse属性默认为false;在多对多的关系中,关系两端的inverse不能都设置为false,如果都设置为false,则在插入操作时会导致关系表中插入两次关系,也不能都设置成true(任何操作都不会影响到关系表中的数据)

    ,因此在任意一方设置为true,另一方设置为false;

       No.2 多对多双向关联

      步骤一: 实体类的创建

      

    public class Employee implements java.io.Serializable {
        // Fields
        private Integer empid;
        private String empname;
        private Set<Project> projects = new HashSet<Project>();
    ...其他内容省略
    }
     02.创建Project持久化类
    public class Project implements java.io.Serializable {
        private Integer proid;
        private String proname;
        private Set<Employee> employees = new HashSet<Employee>();
    ...其他内容省略
    }

        步骤二:创建hbm.xml文件

       

    ?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="cn.happy.daymanymany.Employee" table="EMPLOYEE">emploee
            <id name="empid" type="java.lang.Integer">
                <column name="EMPID"/>
                <generator class="sequence">
                <param name="sequence">SEQ_ID</param>
                </generator>
            </id>
            <property name="empname" type="java.lang.String">
                <column name="EMPNAME" length="32" not-null="true" />
            </property>
            <set name="projects" inverse="true" table="PROEMP">promp
                <key column="REMPID"/><!-- 表PROEMP的外键REMPID -->
                <many-to-many class="cn.happy.daymanymany.Project" column="RPROID" />
            </set>
        </class>
    </hibernate-mapping>
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="cn.happy.daymanymany.Project" table="PROJECT">
            <id name="proid" type="java.lang.Integer">
                <column name="PROID"/>
                <generator class="sequence">
                  <param name="sequence">SEQ_ID</param>
                </generator>
            </id>
            <property name="proname" type="java.lang.String">
                <column name="PRONAME" length="32" not-null="true" />
            </property>
            <set name="employees" table="PROEMP" cascade="save-update">
                <key column="RPROID" />
                <many-to-many class="cn.happy.daymanymany.Employee" column="REMPID" />
            </set>
        </class>
    </hibernate-mapping>

    通过第三张表的外键关联两个类的多对多关系

    大配置同上:步骤三:编写测试类

    public void addTest(){
                 Emp emp=new Emp();
                 emp.setEmpname("大美丽");    
                 Project pro=new Project();
                 pro.setPname("中央支援地方");
                 pro.getEmps().add(emp);
                 emp.getPros().add(pro);         
                 session.save(pro);
                 session.save(emp);
        }


  • 相关阅读:
    C#面向过程之类型转换、算术运算符、关系运算符、逻辑运算符、if-else语句、switch-case、循环结构(while、for)、三元表达式
    C#面向过程之编译原理、变量、运算符
    VS快捷键整理
    简单聊聊mybatis插件(附源码)
    高性能页面加载技术(流水线加载)BigPipe的C#简单实现(附源码)
    聊聊js运算符 ‘与(&&)’和‘ 或(||)’
    从内部剖析C# 集合之--Dictionary
    从内部剖析C# 集合之---- HashTable
    字符串查找和函数操作题目解析
    常用排序算法实现
  • 原文地址:https://www.cnblogs.com/chimingyang/p/5835860.html
Copyright © 2020-2023  润新知