Hibernate的单向多对一
一、映射关系
简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。
它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的形象来对数据库中的数据进行间接的操作。
映射关系是将数据库中的表映射成与之相对应的对象,当你对这个对象进行操作的对象,Hibernate会对数据库中对应的表执行相应的操作,你该对实体的操作实际上就是在间接的操作数据库与之相对应的表。
Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作。
Hibernate主要实现的映射关系

二、映射结构
Hibernate在实现ORM功能的时候主要用到的文件有:映射类xx.Java、映射文件xx.hbm.xml和数据库配置文件xx.properties/xx.cfg.xml,它们各自的作用如下。
映射类xx.Java:它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。
映射文件xx.hbm.xml:它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。
数据库配置文件xx.properties/xx.cfg.xml:它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。
三、单向多对一:比如Student表对Grade表。
Student表
| id | name | age | grade_id |
|---|---|---|---|
| 1 | 张三 | 20 | 1 |
| 2 | 李四 | 22 | 1 |
| 3 | 王五 | 22 | 2 |
Grade表
| id | name |
|---|---|
| 1 | 基础 |
| 2 | 中级 |
-
创建Student类
public class Student implements Serializable { private Integer id; private String name; private Integer age; private Grade grade; @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", grade=" + grade + '}'; } 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 Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } }
-
创建Grade类
public class Grade implements Serializable { private Integer id; private String name; @Override public String toString() { return "Grade{" + "id=" + id + ", name='" + name + '\'' + '}'; } 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; } }
-
创建Student.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 package="com.uestc"> <class name="Student"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="age"/> <!-- 多对一 name对应的字段名称 class对应的类型 not-null不可以为空 column外键列名 foreign-key外键名称 --> <many-to-one name="grade" class="Grade" not-null="true" column="grade_id" foreign-key="fk_grade"/> </class> </hibernate-mapping>
-
创建Grade.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 package="com.uestc"> <class name="Grade"> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
-
在src和test的resources下面的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> <!-- 初始化JDBC连接 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql:///hibernate</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 方言 --> <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property> <!-- 数据库生成方式 --> <property name="hbm2ddl.auto">update</property> <!-- validate检测,create-drop删了重新创建,create重新建表,update表如果存在插数据,如果不存在建表插数据 --> <!-- 打印sql --> <property name="show_sql">true</property> <!-- 格式化sql --> <property name="format_sql">true</property> <!-- 关联对象配置文件 --> <mapping resource="com/uestc/Grade.hbm.xml"/> <mapping resource="com/uestc/Student.hbm.xml"/> </session-factory> </hibernate-configuration>
-
最后在测试类中测试代码
@Test public void testCreateDB(){ //5.1.x版本至目前最新版 //创建注册服务对象 //.configure()如果不写参数,表示默认获取的是hibernate.cfg.xml //配置文件的名字是不能改的,如果改掉之后,就应该在configure()方法中传入配置文件名字,有必要的话还要传入路径 StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build(); //生成Metadata构建元信息 Metadata metadata = new MetadataSources(serviceRegistry).buildMetadata(); SchemaExport schemaExport = new SchemaExport(); //生成表结构 schemaExport.create(EnumSet.of(TargetType.DATABASE),metadata); } /** * 单向多对一 */ @Test public void testSingleManyToOne() { Session session = null; Transaction tx = null; try { session = HibernateUtil.getSession(); tx = session.beginTransaction(); //创建实例对象 Grade grade1 = new Grade(); grade1.setName("基础"); Grade grade2 = new Grade(); grade2.setName("中级"); Student student = new Student(); student.setName("张三"); student.setAge(18); student.setGrade(grade1); Student student2 = new Student(); student2.setName("李四"); student2.setAge(18); student2.setGrade(grade1); Student student3 = new Student(); student3.setName("王五"); student3.setAge(18); student3.setGrade(grade2); //存储的顺序是根据外键约束而定的,如果外键不可以为空,必须先存储外键的一端 //如果外键可以为空,随意存储,但是建议先存储外键的一端,因为会多执行update session.save(grade1); session.save(grade2); session.save(student); session.save(student2); session.save(student3); tx.commit(); }catch (Exception e){ e.printStackTrace(); tx.rollback(); }finally { HibernateUtil.closeSession(); } } /** * 获取 * 查询不用开启事务,会降低性能 */ @Test public void testSingleGetManyToOne() { Session session = null; Transaction tx = null; try { session = HibernateUtil.getSession(); tx = session.beginTransaction(); Student student = session.get(Student.class,1); System.out.println("stuName:" +student.getName() + ",grade:" +student.getGrade().getName()); tx.commit(); }catch (Exception e){ e.printStackTrace(); tx.rollback(); }finally { HibernateUtil.closeSession(); } }
-
最后数据库出现内容,表示hibernate建立成功。

浙公网安备 33010602011771号