Hibernate5单向多对一映射

单向的多对一: 只需要n(多)这端访问1(一)这端的情况!没有1的端访问多的端的时候。

比如: 班主任老师 和学生

一对多:从老师的角度,一个老师对应多个学生 
多对一:从学生的角度,多个学生对应一个老师

 一、 POJO 类 及 xxx.hbm.xml 配置文件

public class Student {
	private int id;
	private String sname;
	
	private Teacher teacher; 

    ... 
}


public class Teacher {
	private Integer id;
	private String tname;

    ....
}

从老师的角度:单向1(老师), 映射没变化

    <class name="cn.jq.hibernate5.model.Teacher" table="T_TEACHER">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
        <property name="tname" type="java.lang.String">
            <column name="t_name" />
        </property>
    </class>

从老师的角度:单向n(学生)many-to-one , 映射用个 package 属性,方便管理包名

<hibernate-mapping package="cn.jq.hibernate5.model">
    <class name="Student" table="T_STUDENT">
        <id name="id" type="int">
            <column name="id" />
            <generator class="native" />
        </id>
        <property name="sname" type="java.lang.String">
            <column name="s_name" />
        </property>
        
        <!-- 
        	name: 为Student(多)类 这端的属性名
        	calss: 为Teacher(yi)类 这端的 全限定类名(此处使用了package属性)
        	column: 为Student(多)表 的外键名
         -->
        <many-to-one name="teacher" class="Teacher">
            <column name="teacher_id" />
        </many-to-one>
    </class>
</hibernate-mapping>

二、 junit 测试  

public class Hibernate5Test {

	SessionFactory sessionFactory = null;
	Session session = null;
	Transaction transaction = null;

	@Before
	public void init() {
		Configuration configuration = new Configuration().configure();
		StandardServiceRegistry serviceRegistry = configuration.getStandardServiceRegistryBuilder().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		
		session = sessionFactory.openSession();
		
		transaction = session.beginTransaction();
	}

	@After
	public void destory() {
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

}

建表 sql :    

Hibernate: 
    
    create table T_STUDENT (
       id integer not null auto_increment,
        s_name varchar(255),
        teacher_id integer,
        primary key (id)
    ) engine=InnoDB
Hibernate: 
    
    create table T_TEACHER (
       id integer not null auto_increment,
        t_name varchar(255),
        primary key (id)
    ) engine=InnoDB
Hibernate: 
    
    alter table T_STUDENT 
       add constraint FK7gnkgubne3mlxj43gqwtf4a97 
       foreign key (teacher_id) 
       references T_TEACHER (id)

从老师的角度

1、 新增推荐先插入一(1)的这端, 效率高!

结论: 先插入 Teacher(1) 这端数据,发起3条 insert 语句。

           先插入 Student(多) 这端数据,发起3条 insert 和 2条 update 语句,    

	@Test
	public void test() {
		Teacher teacher = new Teacher("老师1");
		
		Student student1 = new Student(); 
		student1.setSname("学生1");
		Student student2 = new Student(); 
		student2.setSname("学生2");
		
		//建立单向多对一关联关系  
		student1.setTeacher(teacher);
		student2.setTeacher(teacher);
		
		session.save(teacher);
		session.save(student1);
		session.save(student2);		
	}

2. 删除:

结论: 删除 Student (多) 这端数据,可正常删除,Teacher(1) 这端数据 没影响 。 

           删除 Teacher (1) 这端数据, 会出错, 因为受到 外键约束

	@Test
	public void test() {				
		Teacher  teacher = session.load(Teacher.class, 1);			
		session.delete(teacher);  //报错

	}

3. 修改: 正常修改, 没问题

	@Test
	public void test() {
		Teacher  teacher = session.load(Teacher.class, 1);
		teacher.setTname("老师11");
		session.save(teacher);

		Student student = session.get(Student.class, 2);
		student.setSname("学生22");
		session.save(student);
		
	}

   

4. 查询:

   结论: 默认情况下, 查询多(n)这端对象, 只要没使用到关联的对象, 不会发起关联的对象的查询!

           因为使用的懒加载, 所以在使用关联对象之前关闭session, 必然发生赖加载异常!    

	@Test
	public void test() {
		Teacher  teacher = session.load(Teacher.class, 1);
		System.out.println(teacher);
		
		Student student = session.get(Student.class, 2);
		System.out.println(student.getTeacher().getTname());
		
	}

猜你喜欢

转载自blog.csdn.net/qq_42402854/article/details/81540926