• 【Hibernate】Re07 关系映射处理


    一、单向多对一关系映射处理

    演示案例列举了员工与部门的关系,一个部门下具有多个员工,相反的一个员工只隶属于一个部门下面

    Maven依赖坐标:

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
    
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-agroal</artifactId>
        <version>5.4.21.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>5.4.21.Final</version>
    </dependency>

    如果缺组件,就再补上这个:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>5.4.21.Final</version>
    </dependency>
    

    部门类编写:

    package cn.zeal4j.domain;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.io.Serializable;
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 19:51
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Department implements Serializable {
        private static final long serialVersionUID = -2834030425366265977L;
        private Integer departmentId;
        private String departmentName;
        private String departmentLocation;
    }

    对应的部门Hibernate映射文件:

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Department" table="department">
            <id name="departmentId" column="department_id" type="java.lang.Integer" access="property" >
                <generator class="increment" />
            </id>
            <property name="departmentName" column="department_name" type="java.lang.String" access="property"/>
            <property name="departmentLocation" column="department_location" type="java.lang.String" access="property" />
        </class>
    </hibernate-mapping>
    

    员工类编写:

    package cn.zeal4j.domain;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.io.Serializable;
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 19:59
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Employee implements Serializable {
        private static final long serialVersionUID = -6524261539072181203L;
        private Integer employeeNo;
        private String employeeName;
        private Department department;// 多个员工中的每一个员工对应一个部门
    }

    对应的员工Hibernate映射文件:

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Employee" table="employee">
            <id name="employeeNo" column="employee_no" type="java.lang.Integer" access="property" >
                <generator class="increment" />
            </id>
            <property name="employeeName" column="employee_name" type="java.lang.String" access="property"/>
    
            <many-to-one name="department" column="department_no" class="Department" />
        </class>
    
    </hibernate-mapping>
    

    Hibernate核心配置文件编写:

    注意数据库hibernate要存在!!!

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- 基本链接参数 -->
            <property name="connection.url">jdbc:mysql://localhost:3308/hibernate?serverTimezone=Asia/Shanghai</property>
            <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
            <property name="connection.username">root</property>
            <property name="connection.password">123456</property>
    
            <!-- c3p0数据源配置 -->
            <property name="hibernate.c3p0.max_size">10</property>
            <property name="hibernate.c3p0.min_size">5</property>
            <property name="hibernate.c3p0.idle_test_period">2000</property>
            <property name="hibernate.c3p0.timeout">2000</property>
    
            <property name="dialect">org.hibernate.dialect.MySQL57Dialect</property> <!-- 数据库版本方言 -->
            <property name="show_sql">true</property> <!-- 是否让控制台输出SQL语句 -->
            <property name="format_sql">true</property> <!-- 控制台输出的SQL格式化 -->
            <property name="hbm2ddl.auto">update</property> <!-- 数据库表的生成策略 -->
    
            <mapping resource="hibernate/mapping/Department.hbm.xml"/>
            <mapping resource="hibernate/mapping/Employee.hbm.xml" />
    
        </session-factory>
    
    </hibernate-configuration>

    工具类编写:

    package cn.zeal4j.util;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.boot.MetadataSources;
    import org.hibernate.boot.registry.StandardServiceRegistry;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 18:43
     */
    public class HibernateUtil {
    
        static {
            final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().
                    configure("hibernate/hibernate.cfg.xml").build();
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        }
    
        private HibernateUtil() {}
    
        private static final SessionFactory sessionFactory;
    
        public static Session getSession() {
            return sessionFactory.openSession();
        }
    
        public static void destroyFactory() {
            sessionFactory.close();
        }
    }

    测试类编写:

    package cn.zeal4j.test;
    
    import cn.zeal4j.domain.Department;
    import cn.zeal4j.domain.Employee;
    import cn.zeal4j.util.HibernateUtil;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import java.io.Serializable;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 20:30
     */
    public class HibernateTest {
    
        @Test
        public void manyToOneTest() {
            Session session = HibernateUtil.getSession();
    
            Transaction transaction = session.beginTransaction();
    
            Employee employee = new Employee(null, "李四", null);
            Department department = new Department(null, "行政部", "地址位置");
            employee.setDepartment(department);
    
            Serializable save = session.save(department); // 注意,多对一的一要先存在,因为两表关系Hibernate会自动创建强制外键约束
    
            Serializable save2 = session.save(employee); // 有一的一方存在,多的一方才能够成功绑定外键
    
            System.out.println(save); // 返回的序列化对象是映射对象的主键值
            System.out.println(save2);
    
            transaction.commit(); // 若没发生异常,表示操作成功,提交事务
    
            session.close(); // 资源释放
            HibernateUtil.destroyFactory();
        }
    }  

    运行结果:

    先是数据表的创建

    Hibernate: 
        
        create table department (
           department_id integer not null,
            department_name varchar(255),
            department_location varchar(255),
            primary key (department_id)
        ) engine=InnoDB
    Hibernate: 
        
        create table employee (
           employee_no integer not null,
            employee_name varchar(255),
            department_no integer,
            primary key (employee_no)
        ) engine=InnoDB
    Hibernate: 
        
        alter table employee 
           add constraint FKawh85bpyoqubu0i27ud5ufld9 
           foreign key (department_no) 
           references department (department_id)
    九月 26, 2020 8:38:38 下午 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
    INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    Hibernate: 
        select
            max(employee_no) 
        from
            employee
    

    然后是记录的插入:

    Hibernate: 
        select
            max(department_id) 
        from
            department
    Hibernate: 
        select
            max(employee_no) 
        from
            employee
    2
    2
    Hibernate: 
        insert 
        into
            department
            (department_name, department_location, department_id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, department_no, employee_no) 
        values
            (?, ?, ?)
    

    两表的字段也是正常的:

    查询方法:

    @Test
    public void manyToOneQuery() {
        Session session = HibernateUtil.getSession();
    
        Department department = new Department();
        department.setDepartmentId(1);
    
        final String HQL_QUERY = "FROM cn.zeal4j.domain.Employee AS emp WHERE emp.department = ?0 ";
    
        Query<Employee> employeeQuery = session.createQuery(HQL_QUERY, Employee.class);
    
        employeeQuery.setParameter(0, department);
    
        Employee employee = employeeQuery.uniqueResult();
    
        System.out.println(employee);
    
        session.close();
        HibernateUtil.destroyFactory();
    }

    在写SpringDataJPA的时候一样的问题,你也需要使用升级版的HQL语句

    需要在参数占位符的后面指定该参数的索引值,虽然语法上被IDEA提示报错,但是运行时不会出现问题

     

    二、双向一对多关系映射处理

    在上述的基础上这样配置映射类:

    package cn.zeal4j.domain;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 19:51
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Department implements Serializable {
        private static final long serialVersionUID = -2834030425366265977L;
        private Integer departmentId;
        private String departmentName;
        private String departmentLocation;
    
        private Set<Employee> employeeSet = new HashSet<>(); // 建立双向一对多关系映射
    }

    部门Hibernate映射文件:

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Department" table="department">
            <id name="departmentId" column="department_id" type="java.lang.Integer" access="property" >
                <generator class="increment" />
            </id>
            <property name="departmentName" column="department_name" type="java.lang.String" access="property"/>
            <property name="departmentLocation" column="department_location" type="java.lang.String" access="property" />
            
            <set name="employeeSet" cascade="all">
                <key column="department_no" />
                <one-to-many class="Employee" />
            </set>
    
            <!--
                cascade属性 :
                默认 none session操作当前对象时,忽略其他关联对象,例如不设置cascade或者设置为none值,这里的employeeSet就会忽略
                插入与更新 save-update 级联相关的游离对象,在执行插入和更新的操作时
                删除 delete 执行删除操作时,级联相关对象
                全部级联 执行上述的操作时级联相关对象
            -->
        </class>
    </hibernate-mapping>

    测试插入:

    首先因为更改了类的原因,之前的测试单元就会编译出错,直接注释掉,然后再清空之前的记录:

    要注意外键的约束问题,不能直接情况部门表

    TRUNCATE TABLE `employee`;
    SET FOREIGN_KEY_CHECKS = 0;   
    TRUNCATE TABLE `department`;

    或者删除表让Hibernate重建:

    DROP TABLE `department`, `employee`

    参考地址:

    https://www.cnblogs.com/fu-yong/p/9889503.html

    测试类编写:

    @Test
    public void two_wayManyToOneTest() {
        Session session = HibernateUtil.getSession();
    
        Transaction transaction = session.beginTransaction();
    
        Department department = new Department();
        department.setDepartmentLocation("xx省xx市xx区xx路xxx号xx栋xx单元");
        department.setDepartmentName("开发部");
    
        Employee employee1 = new Employee(null, "张三", null); // 如果注入了部门,插入将会造成堆溢出,指针嵌套了
        Employee employee2 = new Employee(null, "李四", null);
        Employee employee3 = new Employee(null, "王五", null);
    
        department.getEmployeeSet().add(employee1);
        department.getEmployeeSet().add(employee2);
        department.getEmployeeSet().add(employee3);
    
        session.save(department);
    
        transaction.commit();
    
        session.close();
    
        HibernateUtil.destroyFactory();
    }

    测试结果:

    Hibernate: 
        select
            max(department_id) 
        from
            department
    Hibernate: 
        select
            max(employee_no) 
        from
            employee
    Hibernate: 
        insert 
        into
            department
            (department_name, department_location, department_id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, department_no, employee_no) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, department_no, employee_no) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, department_no, employee_no) 
        values
            (?, ?, ?)
    Hibernate: 
        update
            employee 
        set
            department_no=? 
        where
            employee_no=?
    Hibernate: 
        update
            employee 
        set
            department_no=? 
        where
            employee_no=?
    Hibernate: 
        update
            employee 
        set
            department_no=? 
        where
            employee_no=?

    效果:

    级联删除操作:

    测试类

    @Test
    public void two_wayManyToOneTest2() {
        Session session = HibernateUtil.getSession();
    
        Transaction transaction = session.beginTransaction();
    
        // 要先从数据库中查询出来
        Department department = session.get(Department.class, 1);
    
        // 再来删除
        session.delete(department);
    
        transaction.commit();
    
        session.close();
        HibernateUtil.destroyFactory();
    }

    测试结果:

    Hibernate: 
        select
            department0_.department_id as departme1_0_0_,
            department0_.department_name as departme2_0_0_,
            department0_.department_location as departme3_0_0_ 
        from
            department department0_ 
        where
            department0_.department_id=?
    Hibernate: 
        select
            employeese0_.department_no as departme3_1_0_,
            employeese0_.employee_no as employee1_1_0_,
            employeese0_.employee_no as employee1_1_1_,
            employeese0_.employee_name as employee2_1_1_,
            employeese0_.department_no as departme3_1_1_ 
        from
            employee employeese0_ 
        where
            employeese0_.department_no=?
    Hibernate: 
        update
            employee 
        set
            department_no=null 
        where
            department_no=?
    Hibernate: 
        delete 
        from
            employee 
        where
            employee_no=?
    Hibernate: 
        delete 
        from
            employee 
        where
            employee_no=?
    Hibernate: 
        delete 
        from
            employee 
        where
            employee_no=?
    Hibernate: 
        delete 
        from
            department 
        where
            department_id=?

    效果:

    这里需要注意一些问题:

    使用了Lombok不独立写出SET映射对象的方法,会导致Hibernate级联删除操作的时候指针嵌套,堆溢出错误

    不使用查询出来的对象,而是随便new的一个对象,给定OID值取删除,并不会触发Hibernate级联删除操作

    Hibernate根据给定的OID值删除部门记录本身之后不再级联下面的员工进行删除

     Set关系维护:

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Department" table="department">
            <id name="departmentId" column="department_id" type="java.lang.Integer" access="property" >
                <generator class="increment" />
            </id>
            <property name="departmentName" column="department_name" type="java.lang.String" access="property"/>
            <property name="departmentLocation" column="department_location" type="java.lang.String" access="property" />
    
            <set name="employeeSet" cascade="all" inverse="false" >
                <key column="department_no" />
                <one-to-many class="Employee" />
            </set>
    
            <!--
                cascade属性 :
                默认 none session操作当前对象时,忽略其他关联对象,例如不设置cascade或者设置为none值,这里的employeeSet就会忽略
                插入与更新 save-update 级联相关的游离对象,在执行插入和更新的操作时
                删除 delete 执行删除操作时,级联相关对象
                全部级联 执行上述的操作时级联相关对象
            -->
            
            <!--
                inverse属性:  该属性用以指定关联关系的方向
                默认值false, 表示不反转,由本映射类作为主关系方,进行关系维护
                true,表示反转,由被映射类作为主关系方,进行关系维护 
            -->
        </class>
    </hibernate-mapping>

    三、单向多对多关系映射处理

    演示案例的关系类是:项目类和员工类,一个项目由多个员工合作,一个员工同时也在开发多个项目

    单向多对多只需要其中的任意一方维护外键关系即可

    重新创建一个新的模块,并且删除之前的数据表:

    项目类

    package cn.zeal4j.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 22:08
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Project implements Serializable {
        private static final long serialVersionUID = -4867120608900517525L;
        private Integer projectId;
        private String projectName;
        private Set<Employee> employeeSet = new HashSet<>();
    
        public Set<Employee> getEmployeeSet() {
            return employeeSet;
        }
    }

    员工类:

    package cn.zeal4j.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 22:08
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Employee implements Serializable {
        private static final long serialVersionUID = -6524261539072181203L;
        private Integer employeeId;
        private String employeeName;
    }

    员工类的Hibernate映射文件就按照单表配置即可

    重点是项目类的Hibernate映射文件配置

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Project" table="project" >
            <id name="projectId" column="project_id" type="java.lang.Integer" access="property">
                <generator class="increment" />
            </id>
            <property name="projectName" column="project_name" type="java.lang.String" access="property"/>
    
            <set name="employeeSet" cascade="all">
                <key column="project_id"></key>
                <many-to-many class="Employee" column="employee_id" />
            </set>
        </class>
    
    </hibernate-mapping>

    Hibernate配置文件:

    和之前一样,只要绑好这个就行了

    <mapping resource="hibernate/mapping/Project.hbm.xml"/>
    <mapping resource="hibernate/mapping/Employee.hbm.xml" />

    要注意的一些问题:

    多对多关系必然是需要一张中间表来维护关系,但是单向维护并没有指定第三张关系维护表的内容

    测试单元:

    @Test
    public void getTest() {
        Session session = HibernateUtil.getSession();
        Transaction transaction = session.beginTransaction();
    
    
        Employee employee1 = new Employee(null, "员工01");
        Employee employee2 = new Employee(null, "员工02");
    
        Project project1 = new Project();
        project1.setProjectName("项目01");
        Project project2 = new Project();
        project2.setProjectName("项目02");
    
        // 多对多对象处理
        project1.getEmployeeSet().add(employee1);
        project1.getEmployeeSet().add(employee2);
    
        project2.getEmployeeSet().add(employee1);
        project2.getEmployeeSet().add(employee2);
    
        // 开始操作
        session.save(project1);
        session.save(project2);
    
        transaction.commit();
        session.close();
        HibernateUtil.destroyFactory();
    }

    语句输出:

    Hibernate: 
        
        create table employee (
           employee_id integer not null,
            employee_name varchar(255),
            primary key (employee_id)
        ) engine=InnoDB
    Hibernate: 
        
        create table project (
           project_id integer not null,
            project_name varchar(255),
            primary key (project_id)
        ) engine=InnoDB
    Hibernate: 
        
        create table Project_employeeSet (
           project_id integer not null,
            employee_id integer not null,
            primary key (project_id, employee_id)
        ) engine=InnoDB
    Hibernate: 
        
        alter table Project_employeeSet 
           add constraint FKl70mnietqkmll2ccdn4vtm58n 
           foreign key (employee_id) 
           references employee (employee_id)
    Hibernate: 
        
        alter table Project_employeeSet 
           add constraint FKns1stqcwdxpogvyhauuj82xul 
           foreign key (project_id) 
           references project (project_id)
    九月 26, 2020 10:35:19 下午 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
    INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    Hibernate: 
        select
            max(project_id) 
        from
            project
    Hibernate: 
        select
            max(employee_id) 
        from
            employee
    Hibernate: 
        insert 
        into
            project
            (project_name, project_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            project
            (project_name, project_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Project_employeeSet
            (project_id, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Project_employeeSet
            (project_id, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Project_employeeSet
            (project_id, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Project_employeeSet
            (project_id, employee_id) 
        values
            (?, ?)
    

    外键表的处理也是正确无误的

    四、双向多对多关系映射处理

    双向绑定,对应的员工类和Hibernate映射文件也是同样的赋予对应的对象

    注意双方都不要使用Lombok,否则还是会造成堆溢出错误!!!

    package cn.zeal4j.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author Administrator
     * @file IntelliJ IDEA Hibernate-Tutorial
     * @create 2020 09 26 22:08
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Employee implements Serializable {
        private static final long serialVersionUID = -6524261539072181203L;
        private Integer employeeId;
        private String employeeName;
        private Set<Project> projectSet = new HashSet<>();
    
    public Set<Project> getProjectSet() {
            return projectSet;
        }
    }

    映射文件:

    注意这里,只能指定一个主方进行关系维护,不允许双方都是关系维护者

    还有set标签,双方都指定table属性的为同一个表明,设置的字段也是正好相反的两个字段

    <?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 package="cn.zeal4j.domain" > <!-- 实体类包映射 -->
    
        <class name="Employee" table="employee">
            <id name="employeeId" column="employee_id" type="java.lang.Integer" access="property" >
                <generator class="increment" />
            </id>
            <property name="employeeName" column="employee_name" type="java.lang.String" access="property"/>
            
            <set name="projectSet" cascade="all" table="project_employee_map" inverse="true" >
                <key column="employee_id" />
                <many-to-many class="Project" column="project_id" />
            </set>
        </class>
    
    </hibernate-mapping>

    测试类

    @Test
    public void eachOtherManyToMany() {
        Session session = HibernateUtil.getSession();
        Transaction transaction = session.beginTransaction();
    
        Employee employee1 = new Employee();
        employee1.setEmployeeName("员工01");
        Employee employee2 = new Employee();
        employee2.setEmployeeName("员工02");
    
        Project project1 = new Project();
        project1.setProjectName("项目01");
        Project project2 = new Project();
        project2.setProjectName("项目02");
    
        project1.getEmployeeSet().add(employee1);
        project1.getEmployeeSet().add(employee2);
        project2.getEmployeeSet().add(employee1);
    
        employee1.getProjectSet().add(project1);
        employee1.getProjectSet().add(project2);
        employee2.getProjectSet().add(project1);
    
        session.save(project1);
        session.save(project2);
    
        transaction.commit();
        session.close();
        HibernateUtil.destroyFactory();
    }

    打印的SQL语句:

    Hibernate: 
        
        create table employee (
           employee_id integer not null,
            employee_name varchar(255),
            primary key (employee_id)
        ) engine=InnoDB
    Hibernate: 
        
        create table project (
           project_id integer not null,
            project_name varchar(255),
            primary key (project_id)
        ) engine=InnoDB
    Hibernate: 
        
        create table project_employee_map (
           project_id integer not null,
            employee_id integer not null,
            primary key (project_id, employee_id)
        ) engine=InnoDB
    Hibernate: 
        
        alter table project_employee_map 
           add constraint FKo9hw3isyxdis78q1kjx6dgsx4 
           foreign key (employee_id) 
           references employee (employee_id)
    Hibernate: 
        
        alter table project_employee_map 
           add constraint FKlwh46ok6c1axys3ooh2e5rwfo 
           foreign key (project_id) 
           references project (project_id)
    九月 26, 2020 11:06:31 下午 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
    INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    Hibernate: 
        select
            max(project_id) 
        from
            project
    Hibernate: 
        select
            max(employee_id) 
        from
            employee
    Hibernate: 
        insert 
        into
            project
            (project_name, project_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            employee
            (employee_name, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            project
            (project_name, project_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            project_employee_map
            (project_id, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            project_employee_map
            (project_id, employee_id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            project_employee_map
            (project_id, employee_id) 
        values
            (?, ?)是

    还是不知道为什么Lombok堆溢出的错误,报错指向了@Data注解

    可能单独写SetterGetter会有用吧

  • 相关阅读:
    NOI2010 超级钢琴
    [linux][nginx] 常用2
    [linux][nginx] 常用
    [PHP]听说随机数mt_rand()比rand()速度快,闲的无聊测试了一下!
    [linux] 权限问题
    [Laravel] 自带分页实现以及links方法不存在错误
    [YII2] 去除自带js,加载自己的JS,然后ajax(json)传值接值!
    [PHP]PHP设计模式:单例模式
    [html]浏览器标签小图标LOGO简单设置
    [javascript]JS获取当前时间戳的方法
  • 原文地址:https://www.cnblogs.com/mindzone/p/13736753.html
Copyright © 2020-2023  润新知