zoukankan      html  css  js  c++  java
  • 03_Hibernate关系映射

    关系映射?

     Hibernate的主要目的就是JAVA程序员可以随心所欲的使用对象编程思维来操作数据库。一些数据库表的关系我们应该可以通过hibernate实现,比如数据库中用到的主外键关系,还有一些与主外键关系的设置,比如主键的信息被删除,外键关联的信息也要删除等,所以hibernate同样应该实现这种映射关系。

    系统设计中的三种实体关系

     

    数据库实体表之间的关系映射

            一对多:客户(customers)和订单(orders)的关系

                    一般在多的一方添加外键

            一对一:公司(company)和公司地址(address)的关系

                    在任意一方添加对方的主键作为外键

           

            多对多:订单(orders)和商品(products)数据表

                    关系上升为第三张表,分别引入双方的主键作为外键

    Hibernate关联映射

    hibernate的一对多关联映射又分为两种实现方式:

           单项关联:立从employee到department的多对一关联,或者仅仅建立从department到employee的一对多关联。

           双项关联:既建立从employee到department的多对一关联,又建立从department到employee的一对多关联。

    1.单向多对一

    员工emp和部门dept,

    规则:在多的一方配置,多的一方要封装一个(一的一方)属性
    name:是一的一方的属性名 , column:外键 列名 class:one的类的全路径
    <many-to-one name="dept" column="deptid" class="com.manytoone.Dept" not-null="false" cascade="all">
    </many-to-one>

    Emp.java

    public class Emp {
        private Integer eid;
        private String ename;
        private Dept dept;
    
        public Integer getEid() {
            return eid;
        }
    
        public void setEid(Integer eid) {
            this.eid = eid;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public Dept getDept() {
            return dept;
        }
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    }

    Emp.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="com.manytoone.Emp" table="emp">
        <id name="eid" column="eid" type="java.lang.Integer" length="10">
            <!--主键生成策略-->
            <generator class="increment">
            </generator>
        </id>
        <!--ename属性-->
        <property name="ename" column="ename" type="java.lang.String" length="50">
        </property>
        <!--name:属性名  column:外键  class: 与name属性的全路径  cascade:表示会影响所关联的的表-->
        <many-to-one name="dept" column="deptid" class="com.manytoone.Dept" not-null="false" cascade="save-update">
        </many-to-one>
    </class>
    </hibernate-mapping>

    Dept.java

    public class Dept {
        private Integer did;
        private String dname;
    
        public Integer getDid() {
            return did;
        }
    
        public void setDid(Integer did) {
            this.did = did;
        }
    
        public String getDname() {
            return dname;
        }
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    }

    dept.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="com.manytoone.Dept" table="dept">
        <id name="did" column="did" type="java.lang.Integer" length="10">
            <!--主键生成策略-->
            <generator class="increment">
            </generator>
        </id>
        <!--dname属性-->
        <property name="dname" column="dname" type="java.lang.String" length="50">
        </property>
    </class>
    </hibernate-mapping>

    2.单向一对多关联

    dept->emp(单向一对多)

    规则:在一的一方配置,要封装一个set集合.
    <!-- name属性:表示一的一方set集合的属性,  table: 多的一方的表名 -->
    <set name="emps" table="emp" cascade="all">
        <key>
                <!-- 外键  -->
            <column name="deptid"></column>
        </key>
        <!-- class: many方的全类名  -->
        <one-to-many class="Emp"/>
    </set>

    dept.java

    public class Dept {
        private Integer did;
        private String dname;
        private Set<Emp> emps = new HashSet<Emp>();
    
        public Integer getDid() {
            return did;
        }
    
        public void setDid(Integer did) {
            this.did = did;
        }
    
        public String getDname() {
            return dname;
        }
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    
        public Set<Emp> getEmps() {
            return emps;
        }
    
        public void setEmps(Set<Emp> emps) {
            this.emps = emps;
        }
    }

    Dept.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="com.onetomany.Dept" table="dept" lazy="true">
        <id name="did" column="did" type="java.lang.Integer" length="10">
            <!--主键生成策略-->
            <generator class="increment">
            </generator>
        </id>
        <!--dname属性-->
        <property name="dname" column="dname" type="java.lang.String" length="50">
        </property>
        <!--关联级别及时加载,查询时会把关联的也会查询出来-->
        <set name="emps" table="emp" cascade="all" lazy="true">
            <key>
                <column name="deptid"></column> <!--外键-->
            </key>
            <one-to-many class="com.onetomany.Emp"/><!--外键关联的类-->
        </set>
    </class>
    </hibernate-mapping>

    Emp.java

    
    public class Emp {
        private Integer eid;
        private String ename;
        private Integer deptid;
    
        public Integer getEid() {
            return eid;
        }
    
        public void setEid(Integer eid) {
            this.eid = eid;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public Integer getDeptid() {
            return deptid;
        }
    
        public void setDeptid(Integer deptid) {
            this.deptid = deptid;
        }
    }
    

    Emp.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="com.onetomany.Emp" table="emp">
        <id name="eid" column="eid" type="java.lang.Integer" length="10">
            <!--主键生成策略-->
            <generator class="increment">
            </generator>
        </id>
        <!--ename属性-->
        <property name="ename" column="ename" type="java.lang.String" length="50">
        </property>
        <property name="deptid" column="deptid" type="java.lang.Integer" length="10">
        </property>
    </class>
    </hibernate-mapping>

    3.双向一对多*

    dept->Emp

    规则:1.在多的一方配置,多的一方要封装一个(一的一方)属性
               2.在一的一方配置,要封装一个set集合.
    上述两个配置综合

    Dept.java

    public class Dept {
        private Integer did;
        private String dname;
        private Set<Emp> emps = new HashSet<Emp>();
    
        public Integer getDid() {
            return did;
        }
    
        public void setDid(Integer did) {
            this.did = did;
        }
    
        public String getDname() {
            return dname;
        }
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    
        public Set<Emp> getEmps() {
            return emps;
        }
    
        public void setEmps(Set<Emp> emps) {
            this.emps = emps;
        }
    }

    Dept.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="com.doubleonetomany.Dept" table="dept">
            <id name="did" column="did" type="java.lang.Integer" length="10">
                <!--主键生成策略-->
                <generator class="increment">
                </generator>
            </id>
            <!--dname属性-->
            <property name="dname" column="dname" type="java.lang.String" length="50">
            </property>
            <set name="emps" table="emp" cascade="all">
                <key>
                    <column name="deptid"></column> <!--外键-->
                </key>
                <one-to-many class="com.doubleonetomany.Emp"/><!--外键关联的类-->
    
            </set>
        </class>
    </hibernate-mapping>

    Emp.java

    public class Emp {
        private Integer eid;
        private String ename;
        private Dept dept;
    
        public Integer getEid() {
            return eid;
        }
    
        public void setEid(Integer eid) {
            this.eid = eid;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public Dept getDept() {
            return dept;
        }
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    }

    Emp.hbn.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="com.icss.doubleonetomany.Emp" table="emp">
        <id name="eid" column="eid" type="java.lang.Integer" length="10">
            <!--主键生成策略-->
            <generator class="increment">
            </generator>
        </id>
        <!--ename属性-->
        <property name="ename" column="ename" type="java.lang.String" length="50">
        </property>
        <!--name:属性名  column:外键  class: 与name属性的全路径  cascade:表示会影响所关联的的表-->
        <many-to-one name="dept" column="deptid" class="com.icss.doubleonetomany.Dept" not-null="false">
        </many-to-one>
    </class>
    </hibernate-mapping>

    4.双向一对一

    employee->joinpart 员工和入党申请书

    规则:在实体类中分别要定义对方类型的属性 
    在有外键一方配置 :<many-to-one name="joinpart" column="joinpart_id" class="JoinPart" cascade="save-update"></many-to-one>
    在没有外键的一方配置 :<one-to-one name="emp" class="Employee" property-ref="joinpart"></one-to-one>
    注:property-ref:对方封装的相关类型的属性

    Employee.java

    package com.icss.doubleonetoone;
    
    import java.util.Date;
    
    /**
     * Created by jiatp on 2019/8/2.
     */
    public class Employee {
        private Integer eid;
        private String name;
        private Date birthday;
        private JoinPart joinPart;
    
        public JoinPart getJoinPart() {
            return joinPart;
        }
    
        public void setJoinPart(JoinPart joinPart) {
            this.joinPart = joinPart;
        }
    
        public Integer getEid() {
            return eid;
        }
    
        public void setEid(Integer eid) {
            this.eid = eid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    }
    

    Employee.hbm.java

    <?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="com.doubleonetoone.Employee" table="employee">
            <id name="eid" column="eid" type="java.lang.Integer" length="10">
                <generator class="increment"/>
            </id>
            <property name="name" column="name" type="java.lang.String" length="50">
            </property>
            <property name="birthday" column="birthday" type="java.util.Date">
            </property>
            <many-to-one name="joinPart" column="joinPart_id" class="com.doubleonetoone.JoinPart" cascade="save-update"></many-to-one>
        </class>
    </hibernate-mapping>
    JoinPart.java
    public class JoinPart {
        private Integer jid;
        private Date joindate;
        private Employee emp;
    
        public Integer getJid() {
            return jid;
        }
    
        public void setJid(Integer jid) {
            this.jid = jid;
        }
    
        public Date getJoindate() {
            return joindate;
        }
    
        public void setJoindate(Date joindate) {
            this.joindate = joindate;
        }
    
        public Employee getEmp() {
            return emp;
        }
    
        public void setEmp(Employee emp) {
            this.emp = emp;
        }
    }
    JoinPart.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="com.icss.doubleonetoone.JoinPart" table="joinPart">
            <id name="jid" column="jid" type="java.lang.Integer" length="10">
                <generator class="increment"/>
            </id>
            <property name="joindate" column="joindate" type="java.util.Date">
            </property>
            <one-to-one name="emp" class="com.doubleonetoone.Employee" property-ref="joinPart"></one-to-one>
        </class>
    </hibernate-mapping>

    5.双向多对多

    User->Role  用户和角色

    规则:双向多对多
    处理中间表,在中间表中存放它们的外键 
    name:集合类型的属性名   table:中间表的表名     column: 中间与之对应的外键 
    class :  后面many方的类的全路径   column: 后面many类对应中间表的外键 
    <set name="users" table="sys_role_user">
        <key column="r_id"></key>
        <many-to-many class="User" column="u_id"></many-to-many>
    </set>

    User.java

    public class User {
        private Integer uid;
        private String name;
        private Set<Role> roles = new HashSet<Role>(); //双向多对多
    
        public Integer getUid() {
            return uid;
        }
    
        public void setUid(Integer uid) {
            this.uid = uid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Set<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(Set<Role> roles) {
            this.roles = roles;
        }
    }

    User.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="com.doublemanytomany.User" table="user">
            <id name="uid" column="uid" type="java.lang.Integer" length="10">
                <!--主键生成策略-->
                <generator class="increment">
                </generator>
            </id>
            <property name="name" column="name" length="50" type="java.lang.String">
            </property>
            <!--inverses属性;true关联维护时将控制权交给对方-->
            <set name="roles" table="sys_role_user" inverse="true">
                <key column="u_id">
                </key>
                <many-to-many class="com.doublemanytomany.Role" column="r_id">
                </many-to-many>
            </set>
           
        </class>
    </hibernate-mapping>

    Role.java

    public class Role {
        private Integer rid;
        private String name;
        private Set<User> users = new HashSet<User>();  //多对多
    
        public Integer getRid() {
            return rid;
        }
    
        public void setRid(Integer rid) {
            this.rid = rid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Set<User> getUsers() {
            return users;
        }
    
        public void setUsers(Set<User> users) {
            this.users = users;
        }
    }

    Role.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="com.doublemanytomany.Role" table="role">
            <id name="rid" column="rid" type="java.lang.Integer" length="10">
                <!--主键生成策略-->
                <generator class="increment">
                </generator>
            </id>
            <property name="name" type="java.lang.String" column="name" length="50">
            </property>
            <set name="users" table="sys_role_user">
                <key column="r_id">
                </key>
                <many-to-many class="com.doublemanytomany.User" column="u_id">
                </many-to-many>
            </set>
    
        </class>
    </hibernate-mapping>

    注意:对于双向 n-n 关联, 须把其中一端的 inverse 设置为 true, 否则可能会造成主键冲突.

    测试

    /**
     * Description:测试双向多对多关联
     * User:jiatp
     * Date: 2019/8/3 18:14
     */
    public class doublemanytomanyTest {
        @Test
        public void test(){
            Session session = HibernateUtils.openSession();
            Transaction ts = session.beginTransaction();
            //创建用户
            User user1 = new User();
            user1.setName("jtp");
    
            // 创建角色
            Role role = new Role();
            role.setName("CEO");
    
            //关联关系
            user1.getRoles().add(role);
            role.getUsers().add(user1);
            session.save(user1);
            session.save(role);
    
    
            ts.commit();
            session.close();
    
        }
    }

    只举例双向对多的例子,其余的自行测试。

  • 相关阅读:
    Ubuntu adb devices :???????????? no permissions (verify udev rules) 解决方法
    ubuntu 关闭显示器的命令
    ubuntu android studio kvm
    ubuntu 14.04版本更改文件夹背景色为草绿色
    ubuntu 创建桌面快捷方式
    Ubuntu 如何更改用户密码
    ubuntu 14.04 返回到经典桌面方法
    ubuntu 信使(iptux) 创建桌面快捷方式
    Eclipse failed to get the required ADT version number from the sdk
    Eclipse '<>' operator is not allowed for source level below 1.7
  • 原文地址:https://www.cnblogs.com/jatpeo/p/11767538.html
Copyright © 2011-2022 走看看