Hibernate 超简单的一对多和多对一查询

这里使用的Teacher类和Student类(假设一个Teacher对应多个学生,一个学生对应一个老师)

所需jar包

开始建表

1(表名 teacher)

2(表名 student)

主键都为自增长

创建实体类

Teacher类

package com.bright.po;
 
import java.util.Set;
 
public class Teacher {
    private Integer id;
    private String name;
    private Integer age;
    private Set<Student> students;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Teacher [id=" + id + ", name=" + name + ", age=" + age
                + ", students=" + students + "]";
    }
}
Student类

package com.bright.po;
 
public class Student {
    private Integer id;
    private String name;
    private Teacher teacher;
    
    public Student() {
        super();
    }
    public Student(String name, Teacher teacher) {
        super();
        this.name = name;
        this.teacher = teacher;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }
}
配置Teacher类的映射文件

<?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="com.bright.po">
    <!-- 
        name:即实体类的全名
        table:映射到数据库里面的那个表的名称
        catalog:数据库的名称
     -->
    <class name="Teacher" table="teacher" catalog="me">
        <!-- class下必须要有一个id的子元素 -->
        <!-- id是用于描述主键的 -->
        <id name="id" column="id">
            <!-- 主键生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 
            使用property来描述属性与字段的对应关系
            如果length忽略不写,且你的表是自动创建这种方案,那么length的默认长度是255
        -->
        <property name="name" column="name" length="20"></property>
        <property name="age" column="age" length="20"></property>
        <!-- 一对多关联映射配置(通过部门管理到员工)   
             Teacher映射关键点:  
               1.指定映射的集合属性:students  
               2.集合属性对应的集合表:student  
               3.集合表的外键字段:t_id 
               4.集合元素的类型-->  
        <set name = "students" table = "student">
            <key column="t_id"></key>
            <one-to-many class="Student"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
配置Student类的映射文件

<?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="com.bright.po">
    <!-- 
        name:即实体类的全名
        table:映射到数据库里面的那个表的名称
        catalog:数据库的名称
     -->
    <class name="Student" table="student" catalog="me">
        <!-- class下必须要有一个id的子元素 -->
        <!-- id是用于描述主键的 -->
        <id name="id" column="id">
            <!-- 主键生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 
            使用property来描述属性与字段的对应关系
            如果length忽略不写,且你的表是自动创建这种方案,那么length的默认长度是255
        -->
        <property name="name" column="name" length="20"></property>
         <!-- 一对多关联映射配置(通过部门管理到员工)   
             Student映射关键点:  
               1.指定映射的属性:teacher  
               2.集合表的外键字段:t_id 
               3.元素的类型:teacher-->  
        <many-to-one name="teacher" column="t_Id" class="Teacher"></many-to-one>
    </class>
</hibernate-mapping>
配置Hibrnate的配置文件

<?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>
        <!-- 配置关于数据库连接的四个项:driverClass  url username password -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///me</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
 
        <!-- 可以将向数据库发送的SQL语句显示出来 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL语句 -->
        <property name="hibernate.format_sql">true</property>
 
        <!-- hibernate的方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
 
        <!-- 配置hibernate的映射文件所在的位置 -->
        <mapping resource="com/bright/po/Teacher.hbm.xml" />
        <mapping resource="com/bright/po/Student.hbm.xml" />
    </session-factory>
</hibernate-configuration>
表中插入几条数据

teacher表

student表

开始测试

首先写个获取Session的工具类

package com.bright.utils;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
public class SessionUtils {
    public static Session getSession(){
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        session.beginTransaction();
        return session;
    }
    public static void closeSession(Session session){
        if(session!=null){
            session.getTransaction().commit();
            session.close();
        }
    }
}
具体测试

package com.bright.test;
 
 
import java.util.List;
 
 
import org.hibernate.Session;
 
 
import com.bright.po.Student;
import com.bright.po.Teacher;
 
 
import com.bright.utils.SessionUtils;
 
 
public class TestTeacher {
    public static void main(String[] args) {
        Session session = SessionUtils.getSession();
        List<Teacher> list = session.createQuery("from Teacher").list();
        for(Teacher t:list){
            System.out.println(t);
        }
        SessionUtils.closeSession(session);
    }
    
}

输出结果

Hibernate: 
    select
        teacher0_.id as id1_1_,
        teacher0_.name as name2_1_,
        teacher0_.age as age3_1_ 
    from
        me.teacher teacher0_
Hibernate: 
    select
        students0_.t_id as t_id3_0_0_,
        students0_.id as id1_0_0_,
        students0_.id as id1_0_1_,
        students0_.name as name2_0_1_,
        students0_.t_Id as t_Id3_0_1_ 
    from
        me.student students0_ 
    where
        students0_.t_id=?
Teacher [id=1, name=白起, age=27, students=[Student [id=2, name=苏烈], Student [id=3, name=刘邦], Student [id=1, name=亚瑟]]]
Hibernate: 
    select
        students0_.t_id as t_id3_0_0_,
        students0_.id as id1_0_0_,
        students0_.id as id1_0_1_,
        students0_.name as name2_0_1_,
        students0_.t_Id as t_Id3_0_1_ 
    from
        me.student students0_ 
    where
        students0_.t_id=?
Teacher [id=2, name=宫本武藏, age=25, students=[Student [id=6, name=兰陵王], Student [id=4, name=孙悟空], Student [id=5, name=荆轲]]]
Hibernate: 
    select
        students0_.t_id as t_id3_0_0_,
        students0_.id as id1_0_0_,
        students0_.id as id1_0_1_,
        students0_.name as name2_0_1_,
        students0_.t_Id as t_Id3_0_1_ 
    from
        me.student students0_ 
    where
        students0_.t_id=?
Teacher [id=3, name=后羿, age=55, students=[Student [id=7, name=百里守约], Student [id=9, name=公孙离], Student [id=8, name=马可波罗]]]
可以看出,查询执行了多次,多次生成了sql语句,效率低,所以接下来采用了表的“迫切左外连接”。具体代码:

package com.bright.test;
 
import java.util.List;
 
import org.hibernate.Session;
 
import com.bright.po.Student;
import com.bright.po.Teacher;
 
import com.bright.utils.SessionUtils;
 
public class TestTeacher {
    public static void main(String[] args) {
        Session session = SessionUtils.getSession();
        List<Teacher> list = session.createQuery("select t from Teacher t left outer join fetch t.students").list();
        for(Teacher t:list){
            System.out.println(t);
        }
        SessionUtils.closeSession(session);
    }
    
}
查询结果:

Hibernate: 
    select
        teacher0_.id as id1_1_0_,
        students1_.id as id1_0_1_,
        teacher0_.name as name2_1_0_,
        teacher0_.age as age3_1_0_,
        students1_.name as name2_0_1_,
        students1_.t_Id as t_Id3_0_1_,
        students1_.t_id as t_id3_0_0__,
        students1_.id as id1_0_0__ 
    from
        me.teacher teacher0_ 
    left outer join
        me.student students1_ 
            on teacher0_.id=students1_.t_id
Teacher [id=1, name=白起, age=27, students=[Student [id=3, name=刘邦], Student [id=1, name=亚瑟], Student [id=2, name=苏烈]]]
Teacher [id=1, name=白起, age=27, students=[Student [id=3, name=刘邦], Student [id=1, name=亚瑟], Student [id=2, name=苏烈]]]
Teacher [id=1, name=白起, age=27, students=[Student [id=3, name=刘邦], Student [id=1, name=亚瑟], Student [id=2, name=苏烈]]]
Teacher [id=2, name=宫本武藏, age=25, students=[Student [id=4, name=孙悟空], Student [id=5, name=荆轲], Student [id=6, name=兰陵王]]]
Teacher [id=2, name=宫本武藏, age=25, students=[Student [id=4, name=孙悟空], Student [id=5, name=荆轲], Student [id=6, name=兰陵王]]]
Teacher [id=2, name=宫本武藏, age=25, students=[Student [id=4, name=孙悟空], Student [id=5, name=荆轲], Student [id=6, name=兰陵王]]]
Teacher [id=3, name=后羿, age=55, students=[Student [id=8, name=马可波罗], Student [id=7, name=百里守约], Student [id=9, name=公孙离]]]
Teacher [id=3, name=后羿, age=55, students=[Student [id=8, name=马可波罗], Student [id=7, name=百里守约], Student [id=9, name=公孙离]]]
Teacher [id=3, name=后羿, age=55, students=[Student [id=8, name=马可波罗], Student [id=7, name=百里守约], Student [id=9, name=公孙离]]]
这样就好多了
结构图


有 0 个人打赏
————————————————
版权声明:本文为CSDN博主「kd_bright」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kd_bright/article/details/79528818

posted @   silentmuh  阅读(248)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
Live2D
欢迎阅读『Hibernate 超简单的一对多和多对一查询』
  1. 1 Walk Thru Fire Vicetone
  2. 2 爱你 王心凌
  3. 3 Inspire Capo Productions - Serenity
  4. 4 Welcome Home Radical Face
  5. 5 粉红色的回忆 李玲玉
Welcome Home - Radical Face
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : Ben P. Cooper

作曲 : Cooper

Sleep don't visit, so I choke on sun

And the days blur into one

And the backs of my eyes hum with things I've never done

Sheets are swaying from an old clothesline

Was never much but we've made the most

Welcome home

Ships are launching from my chest

Some have names but most do not

If you find one,please let me know what piece I've lost

Heal the scars from off my back

I don't need them anymore

You can throw them out or keep them in your mason jars

I've come home

All my nightmares escaped my head

Bar the door, please don't let them in

You were never supposed to leave

Now my head's splitting at the seams

And I don't know if I can

Here, beneath my lungs

I feel your thumbs press into my skin again

点击右上角即可分享
微信分享提示