Hibernate学习第三天

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

Hibernate学习第三天

1.1数据库表与表之间的关系

1.1.1一对一关系

例:一个学生只能有一个学号,一个学号对应着一个学生。

1.1.2一对多关系

一个部门对应多个员工,一个员工只能属于某一个部门。

一个商品对应多张商品图片,一张商品图片只对应一个商品。

1.1.3多对多关系

一个学生可以选择多门课程,一门课程也可以被多个学生选择。

一个用户可以选择多个角色,一个角色也可以被多个用户选择。

1.2Hibernate一对多的关系配置

1.2.1.导包

 log4j配置文件:src/log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###
# error warn info debug trace
log4j.rootLogger= info, stdout

 

1.2.2创建数据库和表

可以先建表也可以不建表(可以通过配置自动生成表)

1.用户表

CREATE TABLE `users` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `name` varchar(20) COLLATE utf8_bin DEFAULT NULL,

  `age` int(11) DEFAULT NULL,

  `sex` varchar(2) COLLATE utf8_bin DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

2.汽车表
 

CREATE TABLE `car` (

  `car_id` bigint(20) NOT NULL AUTO_INCREMENT,

  `car_name` varchar(20) COLLATE utf8_bin DEFAULT NULL,

  `users_id` bigint(20) DEFAULT NULL,

  PRIMARY KEY (`car_id`),

  KEY `FKs40dwwjnjd3apfl0x2ju6oofi` (`users_id`),

  CONSTRAINT `FKs40dwwjnjd3apfl0x2ju6oofi` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

1.2.3创建实体

1.一的一方的实体(用户),一个用户可以拥有多辆车:Users.java

package com.entity;

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

public class Users {
    private Long id;
    private String name;
    private String sex;
    private Integer age;
    // 通过ORM方式表示 一个用户拥有多辆车
    // 放置多的一方的集合:hibernate默认使用的是Set集合 因为内部需要排序
    private Set<Car> set = new HashSet<>();

    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 getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Set<Car> getSet() {
        return set;
    }

    public void setSet(Set<Car> set) {
        this.set = set;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

2.多的一方的实体(车),一辆车只能被一个用户拥有:Car.java

package com.entity;

public class Car {
    private Long car_id;
    private String car_name;
    // 通过ORM方式表示 一两车只能属于某一个用户
    //放置的是一的一方的对象
    private Users users;

    public Long getCar_id() {
        return car_id;
    }

    public void setCar_id(Long car_id) {
        this.car_id = car_id;
    }

    public String getCar_name() {
        return car_name;
    }

    public void setCar_name(String car_name) {
        this.car_name = car_name;
    }

    public Users getUsers() {
        return users;
    }

    public void setUsers(Users users) {
        this.users = users;
    }

    @Override
    public String toString() {
        return "Car{" +
                "car_id=" + car_id +
                ", car_name='" + car_name + '\'' +
                ", users=" + users +
                '}';
    }
}

1.2.3创建映射文件

  1. 一的一方的映射的创建Users.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.entity.Users" table="users">
        <!--建立类中的属性与字段的主键对应-->
        <id name="id" column="id" length="10">
            <generator class="native"/>
        </id>
        <!--建立类中的普通属性和表的其他字段对应关系-->
        <property name="name" column="name" length="20"/>
        <property name="age" column="age" length="10"/>
        <property name="sex" column="sex" length="2"/>
        <!--配置一对多的映射:放置的多的一方的集合-->
        <!--
            set标签
                name   多的一方集合的属性名称
        -->
        <set name="set">
            <!--
                key标签
                    column   多的一方外键的名称
            -->
            <key column="users_id" />
                <!--
                    one-to-many标签
                        class   多的一方的类的全路径
                -->
                <one-to-many class="com.entity.Car"/>
        </set>
    </class>
</hibernate-mapping>
  1. 多的一方的映射的创建Car.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.entity.Car" table="car">
        <!--建立OID与之间映射-->
        <id name="car_id" column="car_id" length="10">
            <generator class="native"/>
        </id>
        <!--建立类中的普通属性和表的其他字段对应关系-->
        <property name="car_name" column="car_name" length="20"/>
        <!--配置多对一的关系:放置的是一的一方的对象-->
        <!--
            many-to-one标签
                name     一的一方的对象的属性名称
                class    一的一方类的全路径
                column   在多的一方外键的名称
        -->
        <many-to-one name="users" class="com.entity.Users" column="users_id" />
    </class>
</hibernate-mapping>

1.2.4创建核心配置文件

核心配置文件:src/hibernate.cfg,xml

<?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>
        <!-- 连接数据库的基本参数 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatedemo</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">mysql</property>
        <!-- 配置Hibernate的方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 是否在控制台打印SQL -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL -->
        <property name="hibernate.format_sql">true</property>
        <!-- 根据实体类自动创建表结构 -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 配置C3P0连接池(可以不用配置) Hibernate有内置的连接池-->
        <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!--在连接池中可用的数据库连接的最少数目 -->
        <property name="c3p0.min_size">5</property>
        <!--在连接池中所有数据库连接的最大数目  -->
        <property name="c3p0.max_size">20</property>
        <!--设定数据库连接的过期时间,以秒为单位,
        如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
        <property name="c3p0.timeout">120</property>
        <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
        <property name="c3p0.idle_test_period">3000</property>
        <!--
            事务隔离级别
            hibernate.connection.isolation=4
            1-Read uncommitted isolation
            2-Read Committed isolation
            4-Repeatable read isolation
            8-Serializable isolation
            -->
        <!-- 设置事务隔离级别 -->
        <property name="hibernate.connection.isolation">4</property>
        <!-- 配置当前线程绑定的Session -->
        <property name="hibernate.current_session_context_class">thread</property>

        <mapping resource="com/entity/Users.hbm.xml"/>
        <mapping resource="com/entity/Car.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

1.2.5引入工具类

工具类 src/com/utils/HibernateUtils.java

package com.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate工具类
 */
public class HibernateUtils {
    public static final Configuration CONFIGURATION;
    public static final SessionFactory SESSION_FACTORY;

    static {
        CONFIGURATION = new Configuration().configure();
        SESSION_FACTORY = CONFIGURATION.buildSessionFactory();
    }
    public static Session openSession(){
        return SESSION_FACTORY.openSession();
    }
    public static Session getCurrentSession(){
        return SESSION_FACTORY.getCurrentSession(); // 默认是不开启的必须在核心配置文件中配置了才能使用
    }
}

1.2.6测试

编写测试类:src/com/test/TestDemo01.java

package com.test;

import com.entity.Car;
import com.entity.Users;
import com.utils.HibernateUtils;
import org.hibernate.*;


import org.junit.Test;


public class TestDemo01 {


    @Test
    public void test01() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个用户
        Users users1 = new Users();
        users1.setName("张三");
        Users users2 = new Users();
        users2.setName("李四");
        // 创建三辆车
        Car car1 = new Car();
        car1.setCar_name("宝马");
        Car car2 = new Car();
        car2.setCar_name("奔驰");
        Car car3 = new Car();
        car3.setCar_name("大众");

        // 设置关系
        car1.setUsers(users1);
        car2.setUsers(users1);
        car3.setUsers(users2);

        users1.getSet().add(car1);
        users1.getSet().add(car2);

        users2.getSet().add(car3);

        // 保存数据
        session.save(users1);
        session.save(users2);
        session.save(car1);
        session.save(car2);
        session.save(car3);
        transaction.commit();
    }
}

1.2.7Hibernate的一对多相关操作

1.2.7.1测试一对多关系只保存一边是否可以

答案:不可以会抛出TransientObjectException

 @Test
    // 测试一对多关系只保存一边是否可以
    public void test02() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个用户
        Users users1 = new Users();
        users1.setName("王五");
        Car car = new Car();
        car.setCar_name("宾利");
        users1.getSet().add(car);
        car.setUsers(users1);
        // 保存一边是否可以 答案:不可以 会抛出TransientObjectException
        session.save(users1);
        transaction.commit();
    }

1.3一对多的级联操作

1.什么叫做级联

        1.1级联指的是,操作一个对象的时候,是否会同时操作其关联的对象。

2级联是有方向性

        2.1操作一的一方的时候,是否操作到多的一方

        2.2操作多的一方的时候,是否操作到一的一方

1.3.1级联保存或更新

1.3.1.1保存用户级联保存车,操作的主题的对象是用户

更改映射文件 User.hbm.xml

set标签增加属性cascade

<set name="set" cascade="save-update">
 /**
     *  级联保存或更新
     *  保存用户级联保存车,操作的主题的对象时用户
     *  Users.hbm.xml  set标签增加属性cascade
     * <set name="set" cascade="save-update">
     */
    @Test
    public void test03() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个用户
        Users users1 = new Users();
        users1.setName("王五五");
        Car car = new Car();
        car.setCar_name("吉利");
        users1.getSet().add(car);
        car.setUsers(users1);
        session.save(users1);
        transaction.commit();
    }

1.3.1.2保存车级联保存用户,操作的主题的对象是车

更改映射文件 Car.hbm.xml

many-to-one标签增加属性cascade

<many-to-one name="users" cascade="save-update" class="com.entity.Users" column="users_id" />
 /**
     *  级联保存或更新
     *  保存用户级联保存车,操作的主题的对象时用户
     *  Car.hbm.xml  many-to-one标签增加属性cascade
     * <many-to-one name="users" cascade="save-update" class="com.entity.Users" column="users_id" />
     */
    @Test
    public void test04() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个用户
        Users users1 = new Users();
        users1.setName("lily");
        Car car = new Car();
        car.setCar_name("丰田");
        users1.getSet().add(car);
        car.setUsers(users1);
        session.save(car);
        transaction.commit();
    }

1.3.2测试对象的导航

/**
     *  测试对象导航
     *  前提条件 一对多关系的双方都配置了 cascade="save-update"
     */
    @Test
    public void test05() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个用户
        Users users1 = new Users();
        users1.setName("张张三"); // 语句1

        // 创建三辆车
        Car car1 = new Car();
        car1.setCar_name("宝马"); // 语句2
        Car car2 = new Car();
        car2.setCar_name("奔驰"); // 语句3
        Car car3 = new Car();
        car3.setCar_name("大众"); // 语句4
        car1.setUsers(users1);

        users1.getSet().add(car2);
        users1.getSet().add(car3);

        // 一对多关系的双方都配置了 cascade="save-update"
       // session.save(car1); // 会发送4条insert语句 1、2、3、4
        //session.save(users1); // 会发送3条insert语句 1、3、4
        session.save(car2);  // 会发送1条insert语句 // 3
        transaction.commit();
    }

1.3.3级联删除

1级联删除:

        1.1删除一边的时候,同时将另一方的数据也一并删除。

2删除客户级联删除联系人

更改映射文件 User.hbm.xml

set标签增加属性cascade

<set name="set" cascade="save-update,delete">
/**
 * 级联删除
 * 删除用户级联删除车
*更改映射文件 User.hbm.xml
*set标签增加属性cascade
*<set name="set" cascade="save-update,delete">

 */
@Test
public void test06() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    // 没有配置级联删除,默认情况  修改了车的外建为null 在删除用户
    /*Users users = session.get(Users.class,1L);
    session.delete(users);*/
    // 设置用户的级联删除
    //  Users.hbm.xml  set标签增加属性cascade
    //  <set name="set" cascade="save-update,delete">
    Users users = session.get(Users.class, 2L);
    session.delete(users);
    transaction.commit();
}

3删除联系人级联删除客户(基本不用)

更改映射文件 Car.hbm.xml

many-to-one标签增加属性cascade

<many-to-one name="users" cascade="save-update,delete" class="com.entity.Users" column="users_id" />

1.3.4一对多设置了双向关联产生多余的SQL语句

引出问题:

车过户:原来归属于4号用户的4号车过户给5号用户

@Test
// 原来归属于4号用户的4号车过户给5号用户
public void test07() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    // 查询4号车
    Car car = session.get(Car.class,4L);
    // 查询5号联系人
    Users users = session.get(Users.class,5L);
    car.setUsers(users);
    users.getSet().add(car);
    transaction.commit();//对比缓冲区与快照区的数据是否一致,发现不一致,会发送update语句

}

此时会发送多于的update语句

1解决多余的SQL语句

1.1单向维护:

1.2使一方放弃外键维护权:

1.2.1一的一方放弃。set上配置inverse=”true”

1.3一对多的关联查询的修改的时候会用inverse=”true”

1.3.5区分cascadeinverse

@Test
// 区分cascade和inverse
public void test08() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Users users = new Users();
    users.setName("遛遛刘");
    Car car =new Car();
    car.setCar_name("蹦蹦车");
    users.getSet().add(car);

    // 条件User.hbm.xml set标签为 <set name="set" cascade="save-update" inverse="true">
   // session.save(users); // 用户和车会插入到数据库中,但是外键为null 因为Users放弃了外键维护
    car.setUsers(users);
    session.save(car); // 用户和车会插入到数据库中,但是外键有值
    transaction.commit();
}

1.4Hibernate多对多的关系配置

1.4.1创建表

1.4.2创建实体

学生实体:Student.java

package com.entity;

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

public class Student {
    private Long id; // 主键id
    private String name; // 姓名
    private String sex; // 性别
    private String dept; // 所在系别

    // 设置多对多关系:表示一个学生选择多门课程
    // 放置的是课程的集合
    private Set<Course> coursesSet = new HashSet<>();

    public Set<Course> getCoursesSet() {
        return coursesSet;
    }

    public void setCoursesSet(Set<Course> coursesSet) {
        this.coursesSet = coursesSet;
    }

    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 getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getDept() {
        return dept;
    }

    public void setDept(String dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", dept='" + dept + '\'' +
                '}';
    }
}

课程实体:Course.java

package com.entity;

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

public class Course {
    private Long cid; // 主键
    private String cno; // 课程号
    private String cname;// 课程名
    private Integer creadet; // 学分
    // 一门课程可以被多个学生选择
    // 放置的是学生的集合
    private Set<Student> studentSet = new HashSet<>();

    public Set<Student> getStudentSet() {
        return studentSet;
    }

    public void setStudentSet(Set<Student> studentSet) {
        this.studentSet = studentSet;
    }

    public Long getCid() {
        return cid;
    }

    public void setCid(Long cid) {
        this.cid = cid;
    }

    public String getCno() {
        return cno;
    }

    public void setCno(String cno) {
        this.cno = cno;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }


    public Integer getCreadet() {
        return creadet;
    }

    public void setCreadet(Integer creadet) {
        this.creadet = creadet;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cid=" + cid +
                ", cno='" + cno + '\'' +
                ", cname='" + cname + '\'' +
                ", creadet=" + creadet +
                '}';
    }
}

1.4.3创建映射

学生的映射

<?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.entity.Student" table="student">
        <!--建立类中的属性与字段的主键对应-->
        <id name="id" column="id" length="10">
            <generator class="native"/>
        </id>
        <!--建立类中的普通属性和表的其他字段对应关系-->
        <property name="name" column="name" length="20"/>
        <property name="sex" column="sex" length="2"/>
        <property name="dept" column="dept" length="50"/>
        <!--配置多对多的映射关系-->
        <!--
            set标签
                name   多的一方集合的属性名称
                table  多对多关系需要使用中间表,table的值是中间表的名称
                cascade 级联
                inverse 是否放弃外建维护
        -->
        <set name="coursesSet" table="sc">
            <!--
                key标签
                    column   当前的对象对应中间表的外键名称
            -->
            <key column="student_id" />
                <!--
                    many-to-many标签
                        class   对方类的全路径
                        column 对方对象在表中外键的名字
                -->
              <many-to-many class="com.entity.Course" column="course_id" />
        </set>
    </class>
</hibernate-mapping>

课程的映射

<?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.entity.Course" table="course">
        <!--建立类中的属性与字段的主键对应-->
        <id name="cid" column="cid" length="10">
            <generator class="native"/>
        </id>
        <!--建立类中的普通属性和表的其他字段对应关系-->
        <property name="cno" column="cno" length="20" />
        <property name="cname" column="cname" length="20"/>
        <property name="credit" column="creadet" length="10"/>
        <!--配置多对多的映射关系-->
        <!--
            set标签
                name   多的一方集合的属性名称
                table  多对多关系需要使用中间表,table的值是中间表的名称
                cascade 级联
                inverse 是否放弃外建维护
        -->
        <set name="studentSet" table="sc" inverse="true">
            <!--
                key标签
                    column   当前的对象对应中间表的外键名称
            -->
            <key column="course_id" />
                <!--
                    many-to-many标签
                        class   对方类的全路径
                        column 对方对象在表中外键的名字
                -->
              <many-to-many class="com.entity.Student" column="student_id" />
        </set>
    </class>
</hibernate-mapping>

核心配置文件中映入映射文件

 <mapping resource="com/entity/Student.hbm.xml"/>
 <mapping resource="com/entity/Course.hbm.xml"/>

1.4.4编写测试

 // 保存操作: 多对多建立了双向的关系必须有一方放弃外键维护
 // 一般被动方放弃外键维护

package com.test;

import com.entity.Course;
import com.entity.Student;
import com.utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

public class TestDemo02 {
    @Test
    public void test01() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 创建两个学生
        Student student1 = new Student();
        student1.setName("李勇");
        student1.setDept("计算机");
        Student student2 = new Student();
        student2.setName("刘晨");
        student2.setDept("数学");
        // 创建三门课程
        Course course1 = new Course();
        course1.setCno("1001");
        course1.setCname("数据库");
        Course course2 = new Course();
        course2.setCno("1002");
        course2.setCname("数学");
        Course course3 = new Course();
        course3.setCno("1003");
        course3.setCname("信息系统");

        // 设置双向的关联关系
        student1.getCoursesSet().add(course1);
        student2.getCoursesSet().add(course1);
        student2.getCoursesSet().add(course3);
        course1.getStudentSet().add(student1);
        course1.getStudentSet().add(student2);
        course3.getStudentSet().add(student2);
        // 保存操作: 多对多建立了双向的关系必须有一方放弃外键维护
        // 一般被动方放弃外键维护
        session.save(student1);
        session.save(student2);
        session.save(course1);
        session.save(course2);
        session.save(course3);

        transaction.commit();
    }
}

1.4.5.1多对多的级联保存或更新

1.只保存一边是否可以(不可以)

不配置cascade只保存一边会抛出瞬时对象异常

需要配置 <set name="coursesSet" cascade="save-update" table="sc"> 并且有外键维护

  @Test
    public void test02() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        Student student1 = new Student();
        student1.setName("李大勇");
        student1.setDept("计算机");

        // 创建三门课程
        Course course1 = new Course();
        course1.setCno("1004");
        course1.setCname("数据库");


        // 设置双向的关联关系
        student1.getCoursesSet().add(course1);

        course1.getStudentSet().add(student1);
        // 需要在Student.hbm.xml
        //配置 <set name="coursesSet" cascade="save-update" table="sc"> 并且有外键维护
        session.save(student1);

       /* // 需要在Couese.hbm.xml
        //配置 <set name="StudentSet" cascade="save-update" table="sc"> 并且有外键维护
        session.save(course1);*/
        transaction.commit();
    }

1.4.5.2多对多的级联删除(基本用不上)

1.删除学生级联删除学生所选课程

 /**
     * 删除学生级联删除学生所选课程
     * 在Student.hbm.xml 配置
     * <set name="coursesSet" cascade="save-update,delete" table="sc" >
     */

 /**
     * 删除学生级联删除学生所选课程
     * 在Student.hbm.xml 配置
     * <set name="coursesSet" cascade="save-update,delete" table="sc" >
     */
    @Test
    // 删除一号学生及其习所选课程
    public void test03() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 查询一号学生
        Student student = session.get(Student.class,1L);
        session.delete(student);
        transaction.commit();
    }

2.删除课程级联删除学生

1相反

 

1.4.5多对多的其他的操作

1.给学生选择课程

 @Test
    // 给一号学生多选一个2号课程
    public void test04() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查一号学生
        Student student = session.get(Student.class, 1L);
        // 查2号课程
        Course course = session.get(Course.class,2L);

        student.getCoursesSet().add(course);
        // 持久态对象会自动发送更新语句
        transaction.commit();
    }

2.给学生改选课程

 @Test
    // 给2号学生原本选的2号课程改为3号课程
    public void test05() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查2号学生
        Student student2 = session.get(Student.class, 2L);
        // 查2号课程
        Course course2 = session.get(Course.class,2L);
        // 查3号课程
        Course course3 = session.get(Course.class,3L);
        student2.getCoursesSet().remove(course2); // 删除2号课程
        student2.getCoursesSet().add(course3);
        // 持久态对象会自动发送更新语句
        transaction.commit();
    }

3.给学生删除课程

 @Test
    // 给2号学生删除3号课程
    public void test06() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查2号学生
        Student student2 = session.get(Student.class, 2L);

        // 查3号课程
        Course course3 = session.get(Course.class,3L);
        student2.getCoursesSet().remove(course3); // 删除3号课程
        // 持久态对象会自动发送更新语句
        transaction.commit();
    }

项目源码码云地址:hibernate_day3

https://gitee.com/greatdistance/hibernate

猜你喜欢

转载自blog.csdn.net/GreatDistance/article/details/84674930