JavaWeb框架——Hibernate(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jorocco/article/details/79946821

1、多表查询——一对多
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
代码示例
Customer.java

package cn.ctgu.domain;

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

/*CREATE TABLE customer(
        id BIGINT(32) NOT NULL PRIMARY KEY  AUTO_INCREMENT COMMENT'客户编号(主键)',
        NAME VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
        source VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
        industry VARCHAR(32)DEFAULT NULL COMMENT '客户所属行业',
        LEVEL VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
        phone VARCHAR(64) DEFAULT NULL COMMENT '固定电话',
        mobile VARCHAR(16) DEFAULT NULL COMMENT '移动电话'
    );*/
public class Customer {
    private Long id;

    private String name;
    private String source;
    private String industry;
    private String level;
    private String phone;
    private String mobile;
    //使用set集合表达一对多的关系
    private Set<LinkMan>linkMens=new HashSet<LinkMan>();

    public Set<LinkMan> getLinkMens() {
        return linkMens;
    }
    public void setLinkMens(Set<LinkMan> linkMens) {
        this.linkMens = linkMens;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSource() {
        return source;
    }
    public void setSource(String source) {
        this.source = source;
    }
    public String getIndustry() {
        return industry;
    }
    public void setIndustry(String industry) {
        this.industry = industry;
    }
    public String getLevel() {
        return level;
    }
    public void setLevel(String level) {
        this.level = level;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getMobile() {
        return mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + "]";
    }

}

LinkMan.java

package cn.ctgu.domain;

//联系人实体
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;

    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public Long getLkm_id() {
        return lkm_id;
    }
    public void setLkm_id(Long lkm_id) {
        this.lkm_id = lkm_id;
    }
    public Character getLkm_gender() {
        return lkm_gender;
    }
    public void setLkm_gender(Character lkm_gender) {
        this.lkm_gender = lkm_gender;
    }
    public String getLkm_name() {
        return lkm_name;
    }
    public void setLkm_name(String lkm_name) {
        this.lkm_name = lkm_name;
    }
    public String getLkm_phone() {
        return lkm_phone;
    }
    public void setLkm_phone(String lkm_phone) {
        this.lkm_phone = lkm_phone;
    }
    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_mobile() {
        return lkm_mobile;
    }
    public void setLkm_mobile(String lkm_mobile) {
        this.lkm_mobile = lkm_mobile;
    }
    public String getLkm_memo() {
        return lkm_memo;
    }
    public void setLkm_memo(String lkm_memo) {
        this.lkm_memo = lkm_memo;
    }
    public String getLkm_position() {
        return lkm_position;
    }
    public void setLkm_position(String lkm_position) {
        this.lkm_position = lkm_position;
    }

}

ORM配置文件
Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
    <class name="Customer" table="customer">
        <id name="id"  column="id">
            <!-- generator:主键生成策略
                就是每条记录录入时,主键的生成规则(7个)
                identity:主键自增,有数据库来维护主键值,录入时不需要指定主键
                increment(不用,存在线程安全问题,当多个线程同时插入数据事可能会产生覆盖):主键自增,由hibernate来维护,每次插入时会先查询表中id最大值,+1作为新主键值
                sequence:Oracle中的主键生成策略
                hilo(不用,同样存在线程安全问题):高低位算法,主键自增,由hibernate来维护,开发时不使用
                native:hilo+sequence+identity 自动三选一策略
                uuid:产生随机字符串作为主键,主键类型必须为String类型,否则会报错
                assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
             -->
            <generator class="native"></generator>
        </id>
        <property name="name" column="NAME" ></property>
        <property name="source" column="source"></property>
        <property name="industry" column="industry"></property>
        <property name="level" column="LEVEL"></property>
        <property name="phone" column="phone"></property>
        <property name="mobile" column="mobile"></property>

        <!-- 集合,一对多关系,在配置文件中配置 -->
        <!-- 
            name属性:集合属性名
            column属性:外键列名
            class属性:与我关联的对象完整类名
         -->
         <!-- 级联操作
            级联操作:cascade
                save-update:级联保存更新,即在保存customer的同时将linkman也保存(session.save(c))至数据库,更加便捷
                delete:级联删除
                all:save-update+delete
            级联操作:简化操作
          -->
        <!--  <set name="linkMens" cascade="save-update"> -->

        <!-- inverse属性:配置关系是否维护 
             inverse:
             true:customer不维护关系  配置关系即对主键的配置关系完全交给对方,即联系人维护
             false(默认值):customer维护关系

        inverse属性:性能优化,提高关系维护的性能
        原则: 无论怎么放弃,总有一方必须要维护关系
        一对多关系中:一的一方放弃,也只能一的一方放弃,多的一方不能放弃
        -->

        <set name="linkMens" inverse="true">
            <key column="lkm_cust_id"></key>
            <one-to-many class="LinkMan"/>
        </set>

    </class>
</hibernate-mapping>

LinkMan.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
    <class name="LinkMan" table="link_man">
        <id name="lkm_id" >
            <generator class="native"></generator>
        </id>
        <property name="lkm_name" ></property>
        <property name="lkm_phone" ></property>
        <property name="lkm_email" ></property>
        <property name="lkm_qq" ></property>
        <property name="lkm_mobile" ></property>
        <property name="lkm_memo" ></property>
        <property name="lkm_position" ></property>
        <property name="lkm_gender" ></property>

        <!-- 多对一
            name属性:引用属性名
            column属性:外键列名
            class属性:与我关联的对象完整类名
         -->
         <!-- 级联操作
            级联操作:cascade
                save-update:级联保存更新,即在保存customer的同时将linkman也保存(session.save(c))至数据库,更加便捷
                delete:级联删除
                all:save-update+delete
            级联操作:简化操作
          -->
          <!--<many-to-one name="customer" column="lkm_cust_id" class="Customer" cascade="save-update"></many-to-one>-->
         <!-- 多的一方:不能放弃维护关系的,因为外键在多的一方,所有不能放弃它的维护,只能一的一方(Customer)可以放弃维护-->
         <many-to-one name="customer" column="lkm_cust_id" class="Customer"></many-to-one>
    </class>
</hibernate-mapping>

一对多关系操作
Demo.java

package cn.ctgu.one2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.domain.LinkMan;
import cn.ctgu.utils.HibernateUtils;

//一对多|多对一关系操作
public class Demo {
    @Test
     public void fun1() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         Customer c=new Customer();
         c.setName("传智播客");

         LinkMan lm1=new LinkMan();
         lm1.setLkm_name("老李");

         LinkMan lm2=new LinkMan();
         lm2.setLkm_name("刘悦东");

         LinkMan lm3=new LinkMan();
         lm3.setLkm_name("老好");

         //表达一对多,客户下有多个联系人
         c.getLinkMens().add(lm1);
         c.getLinkMens().add(lm2);


         //表达多对多,联系人属于哪个客户
         lm1.setCustomer(c);
         lm2.setCustomer(c);


         session.save(c);
         session.save(lm1);
         session.save(lm2);



         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //为客户增加联系人
     public void fun2() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作

          //1、获得要操作的客户对象
         Customer c=session.get(Customer.class, 1l);
          //2、创建联系人
         LinkMan lm1=new LinkMan();
         lm1.setLkm_name("张三");
          //3、将联系人添加到客户,将客户设置到联系人中
         c.getLinkMens().add(lm1);
         lm1.setCustomer(c);
          //4、执行保存
         session.save(lm1); 
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //为客户删除联系人
     public void fun3() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作

          //1、获得要操作的客户对象
         Customer c=session.get(Customer.class, 1l);
          //2、获得要移除的联系人
         LinkMan lm=session.get(LinkMan.class, 3l);
          //3、将联系人从客户集合中移除
         c.getLinkMens().remove(lm);
         lm.setCustomer(null);
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }
}

级联操作

package cn.ctgu.one2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.domain.LinkMan;
import cn.ctgu.utils.HibernateUtils;


public class Demo2 {
    @Test
    //级联更新操作
     public void fun1() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         Customer c=new Customer();
         c.setName("传智播客");

         LinkMan lm1=new LinkMan();
         lm1.setLkm_name("老李");

         LinkMan lm2=new LinkMan();
         lm2.setLkm_name("刘悦东");

         LinkMan lm3=new LinkMan();
         lm3.setLkm_name("老好");

         //表达一对多,客户下有多个联系人
         c.getLinkMens().add(lm1);
         c.getLinkMens().add(lm2);
         c.getLinkMens().add(lm3);

         //表达多对多,联系人属于哪个客户
         lm1.setCustomer(c);
         lm2.setCustomer(c);
         lm3.setCustomer(c);

         session.save(c);
        //Customer配置文件中使用了级联更新,即cascade,就不需要操作这一步,它在执行session.save(c)
        // 的同时更新了下面的
        /* session.save(lm1);
         session.save(lm2);
         session.save(lm3);
         */

         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //级联删除客户下的联系人
     public void fun2() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作

          //1、获得要操作的客户对象
         Customer c=session.get(Customer.class, 8l);
          //2、获得要移除的联系人
         session.delete(c);
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //保存联系人以及联系人对应的客户,通过联系人级联客户
     public void fun3() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         Customer c=new Customer();
         c.setName("ctgu");

         LinkMan lm1=new LinkMan();
         lm1.setLkm_name("刘总");

         //表达一对多,客户下有多个联系人
         c.getLinkMens().add(lm1);
         //表达多对多,联系人属于哪个客户
         lm1.setCustomer(c);
         session.save(lm1);
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }
}

关系维护

package cn.ctgu.one2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.domain.LinkMan;
import cn.ctgu.utils.HibernateUtils;

//操作进阶————关系维护
public class Demo3 {
    @Test
    //级联更新操作
     public void fun1() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         Customer c=new Customer();
         c.setName("传智播客");

         LinkMan lm1=new LinkMan();
         lm1.setLkm_name("老李");

         LinkMan lm2=new LinkMan();
         lm2.setLkm_name("刘悦东");

         LinkMan lm3=new LinkMan();
         lm3.setLkm_name("老好");

         //表达一对多,客户下有多个联系人
         /*如果客户放弃维护与联系人的关系,维护关系的代码可以省略
          * c.getLinkMens().add(lm1);
         c.getLinkMens().add(lm2);
         c.getLinkMens().add(lm3);*/

         //表达多对多,联系人属于哪个客户
         lm1.setCustomer(c);
         lm2.setCustomer(c);
         lm3.setCustomer(c);

         session.save(c);
        //Customer配置文件中使用了级联更新,即cascade,就不需要操作这一步,它在执行session.save(c)
        // 的同时更新了下面的
        /* session.save(lm1);
         session.save(lm2);
         session.save(lm3);
         */

         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //删除客户下的联系人,有两种方式:一是级联,二是维护关系,它会将外键置为空
     public void fun2() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作

          //1、获得要操作的客户对象
         Customer c=session.get(Customer.class, 8l);
          //2、获得要移除的联系人
         session.delete(c);
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }
}

2、多对多
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
代码示例
实体对象
User.java

package cn.ctgu.domain;

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

public class User {
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private Character user_state;
    //表达多对多
    private Set<Role>roles=new HashSet<Role>();
    public Long getUser_id() {
        return user_id;
    }
    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }
    public String getUser_code() {
        return user_code;
    }
    public void setUser_code(String user_code) {
        this.user_code = user_code;
    }
    public String getUser_name() {
        return user_name;
    }
    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }
    public String getUser_password() {
        return user_password;
    }
    public void setUser_password(String user_password) {
        this.user_password = user_password;
    }
    public Character getUser_state() {
        return user_state;
    }
    public void setUser_state(Character user_state) {
        this.user_state = user_state;
    }
    public Set<Role> getRoles() {
        return roles;
    }
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

}

Role.java

package cn.ctgu.domain;

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

//角色对象
public class Role {
    private Long role_id;
    private String role_name;
    private String role_memo;
    //表达多对多
    private Set<User>users=new HashSet<User>();

    public Long getRole_id() {
        return role_id;
    }
    public void setRole_id(Long role_id) {
        this.role_id = role_id;
    }
    public String getRole_name() {
        return role_name;
    }
    public void setRole_name(String role_name) {
        this.role_name = role_name;
    }
    public String getRole_memo() {
        return role_memo;
    }
    public void setRole_memo(String role_memo) {
        this.role_memo = role_memo;
    }
    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }

}

ORM配置文件
User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
    <class name="User" table="user">
        <id name="user_id"  column="id">
            <generator class="native"></generator>
        </id>
        <property name="user_name"></property>
        <property name="user_code" ></property>
        <property name="user_password"></property>
        <property name="user_state" ></property>

        <!-- 多对多关系表达 -->
        <!-- 
            name:集合属性名
            table:配置中间表名
            key
              |-column:外键,别人引用“我”(User,因为实在它的配置文件中)的外键列名
            class:我与哪个类是多对多关系
            column:外键,我引用别人的外键列名
         -->
         <!--cascade级联操作:
            save-update:级联保存更新
            delete:级联删除
            all:级联保存更新+级联删除
         结论:cascade简化代码书写,该属性使不使用无所谓,建议不用,要用也只用save-update
         使用delete操作太过危险,尤其在多对多中,建议不使用
           -->
        <set name="roles" table="sys_user_role" cascade="save-update">
            <key column="user_id"></key>
            <many-to-many class="Role" column="role_id"/>
        </set>

    </class>
</hibernate-mapping>

Role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
    <class name="Role" table="role">
        <id name="role_id"  column="id">
            <generator class="native"></generator>
        </id>
        <property name="role_name"></property>
        <property name="role_memo" ></property>

        <!-- 维护关系属性 
            true:放弃维护关系
            false:维护关系

            结论:在业务开发中,如果遇到多对多关系,一定要选择一方放弃维护关系
            一般谁来放弃要看业务方向,例如:录入员工时,需要为员工指定所属角色
            那么业务方向就是由员工维护角色,角色不需要维护与员工关系,角色放弃维护
        -->
        <!-- <set name="users" table="sys_user_role" inverse="true"> -->
        <set name="users" table="sys_user_role">
            <key column="role_id"></key>
            <many-to-many class="User" column="user_id"/>
        </set>

    </class>
</hibernate-mapping>

核心配置
hibernate.cfg.xml(包含上面一对多的配置,每增加一个ORM就得在核心配置文件中进行映射)

<?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>
        <!--
        #hibernate.dialect org.hibernate.dialect.MySQLDialect
        #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
        #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
        #hibernate.connection.driver_class com.mysql.jdbc.Driver
        #hibernate.connection.url jdbc:mysql:///test
        #hibernate.connection.username gavin
        #hibernate.connection.password 
         -->
        <!-- 必选配置 5个-->

        <!-- 数据库驱动 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 数据库url -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <!-- 数据库用户名 -->
        <property name="hibernate.connection.username">root</property>
         <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">123456</property>
        <!-- 数据库方言
            不同的数据中,sql语法略有差别,指定方言可以让hibernate框架
            在生成sql语句时,针对数据库的方言生成。
            不同的数据库方言只有细微差别,因都按sql99标准: DDL  定义语言    库、表的增删改查
                                                 DML    控制语言    事务、权限
                                                 DCL    操纵语言    增删改查
            注意:Mysql在选择方言时,选择最短的方言,因为这个引擎是通用的,而其他的引擎在解析语法可能有差别,导致我们与导入的包不匹配产生异常
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>


        <!-- 可选配置3个 -->
        <!--
         hibernate.show_sql true
         hibernate.format_sql true
          -->
          <!-- 将hibernate生成的sql语句打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
          <!--将hibernate生成的sql语句格式化(语法缩进)  -->
        <property name="hibernate.format_sql">true</property>

        <!-- 
        ## auto schema export  自动到处表结构,自动建表,意思就是即使数据库中没有建立与实体相对应的表,它也不会插入数据
        失败,因为它会自动创建一个表到数据库中,然后在插入数据

        #hibernate.hbm2ddl.auto create-drop 自动建表,每次框架运行都会将所有表删除(开发环境中使用)
        #hibernate.hbm2ddl.auto create  自动建表,每次框架运行都会创建新的表,以前的表将会被覆盖,表数据会丢失(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update  (推荐使用)自动生成表,如果已经存在就不会生成,如果表有变动,自动更新表(不会删除任何数据)
        #hibernate.hbm2ddl.auto validate    校验,不自动生成表,每次启动会校验数据库中表是否正确,也就是校验是否与实体匹配,校验失败则抛出异常
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>       

        <!-- 引入orm元数据
                路径书写:填写src下的路径
         -->
         <!--指定hibernate操作数据库时的隔离级别

            ## specify a JDBC isolation level

            #hibernate.connection.isolation 1|2|4|8
            0001    1   读未提交
            0010    2   读已提交
            0100    4   可重复读
            1000    8   串行化
           -->
           <property name="hibernate.connection.isolation">4</property>

           <!-- 指定session与当前线程绑定 -->
           <property name="hibernate.current_session_context_class">thread</property>

        <mapping resource="cn/ctgu/domain/Customer.hbm.xml"/>
        <mapping resource="cn/ctgu/domain/LinkMan.hbm.xml"/>
        <mapping resource="cn/ctgu/domain/User.hbm.xml"/>
        <mapping resource="cn/ctgu/domain/Role.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

关系操作
Demo.java

package cn.ctgu.many2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.domain.LinkMan;
import cn.ctgu.domain.Role;
import cn.ctgu.domain.User;
import cn.ctgu.utils.HibernateUtils;

//多对多关系操作
public class Demo {
    @Test
    //保存员工以及角色
     public void fun1() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         //1、创建两个User
         User u1=new User();
         u1.setUser_name("张三");

         User u2=new User();
         u2.setUser_name("李四");

         //2、创建两个Role
         Role r1=new Role();
         r1.setRole_name("保洁");

         Role r2=new Role();
         r2.setRole_name("保安");

         //3、用户表达关系
         u1.getRoles().add(r1);
         u1.getRoles().add(r2);

         u2.getRoles().add(r1);
         u2.getRoles().add(r2);

         //角色表达关系
         //如果在配置文件中不配置维护关系,则默认两个表都维护主从关系,所以两个表都会向中间表中插入重复数据,违反了主从约束,导致错误,所以只能一方维护关系即可
         //或者在一方配置中放弃维护关系
//       r1.getUsers().add(u1);
//       r1.getUsers().add(u2);
//       
//       r2.getUsers().add(u1);
//       r2.getUsers().add(u2);
         //调用save方法一次保存
         session.save(r1);
         session.save(r2);
         session.save(u1);
         session.save(u2);
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

}

级联操作
Demo2.java

package cn.ctgu.many2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.domain.LinkMan;
import cn.ctgu.domain.Role;
import cn.ctgu.domain.User;
import cn.ctgu.utils.HibernateUtils;

//多对多关系操作
public class Demo2 {
    @Test
    //为用户张三新增一个角色
     public void fun1() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         //获得张三用户
         User user=session.get(User.class, 1l);
         //创建公关角色
         Role r=new Role();
         r.setRole_name("男公关");
         //将角色添加到用户中
         user.getRoles().add(r);
         //将角色转换为持久化
        // session.save(r);//在User中配置级联关系,则可简化此处代码
         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

    @Test
    //为用户张三解除一个角色
     public void fun2() {
         //1、获得session
         Session session = HibernateUtils.openSession();
         //2、开启事务
         Transaction tx = session.beginTransaction();
         //---------------------------------------
         //3、操作
         //获得张三用户
         User user=session.get(User.class, 1l);
         //获得要操作的角色对象(保洁、保安)
         Role r1=session.get(Role.class, 1l);
         Role r2=session.get(Role.class, 2l);
         //将角色从用户的角色集合中移除
         user.getRoles().remove(r1);
         user.getRoles().remove(r2);

         //---------------------------------------
         //4、提交事务
         tx.commit();
         //5、关闭资源
         session.close();
     }

}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页