对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术,本质上就是将数据从一种形式转换到另外一种形式。

面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。 

简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中

Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java)、映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.xml),它们各自的作用如下。

        映射类(*.java):它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。

        映射文件(*.hbm.xml):它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。

        数据库配置文件(*.properties/*.cfg.xml):它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。

两个对象之间一对的关系,例如:Person(人)-IdCard(身份证)实例

有两种策略可以实现一对一的关联映射:

*主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。

单向一对一唯一外键关联例子连接

package cn.itcast.i_hbm_oneToOne;

public class Person {
private Integer id;
private String name; private IdCard idCard; 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 IdCard getIdCard() {
return idCard;
} public void setIdCard(IdCard idCard) {
this.idCard = idCard;
} @Override
public String toString() {
return "[Person��id=" + id + ", name=" + name + "]";
} }

Person

package cn.itcast.i_hbm_oneToOne;

public class IdCard {
private Integer id;
private String number; private Person person; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getNumber() {
return number;
} public void setNumber(String number) {
this.number = number;
} public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} @Override
public String toString() {
return "[IdCard��id=" + id + ", number=" + number + "]";
} }

IdCard

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.i_hbm_oneToOne"> <class name="Person" table="person">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/> <!-- idCard属性,IdCard类型。
表达的是本类与IdCard的一对一。
采用基于外键的一对一映射方式,本方无外键方。
property-ref属性:
写的是对方映射中外键列对应的属性名。
-->
<one-to-one name="idCard" class="IdCard" property-ref="person"/> </class> </hibernate-mapping>

Person.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.i_hbm_oneToOne"> <class name="IdCard" table="idCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="number"/> <!-- person属性,Person类型。
表达的是本类与Person的一对一。
采用基于外键的一对一映射方式,本方有外键方。 -->
<many-to-one name="person" class="Person" column="personId" unique="true"></many-to-one> </class> </hibernate-mapping>

Person.hbm.xml

package cn.itcast.i_hbm_oneToOne;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test; import com.java1234.util.HibernateSessionFactory; public class App { private static SessionFactory sessionFactory =HibernateSessionFactory.getSessionFactory(); // 保存,有关联关系
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 新建对象
Person person = new Person();
person.setName("张三"); IdCard idCard = new IdCard();
idCard.setNumber("100000011X"); // 关联起来
// person.setIdCard(idCard);
idCard.setPerson(person); // 保存
session.save(person);
session.save(idCard); // --------------------------------------------
session.getTransaction().commit();
session.close();
} // 获取,可以获取到关联的对方
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// -------------------------------------------- // 获取一方,并显示另一方信息
// Person person = (Person) session.get(Person.class, 1);
// System.out.println(person);
// System.out.println(person.getIdCard()); IdCard idCard = (IdCard) session.get(IdCard.class, 1);
System.out.println(idCard);
System.out.println(idCard.getPerson()); // --------------------------------------------
session.getTransaction().commit();
session.close(); } // 解除关联关系:一对一中,只能有外键方可以维护关联关系。
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// -------------------------------------------- // 从有外键方解除关系,可以。
// IdCard idCard = (IdCard) session.get(IdCard.class, 1);
// idCard.setPerson(null); // 从无外键方解除关系,不可以。
Person person = (Person) session.get(Person.class, 1);
person.setIdCard(null); // --------------------------------------------
session.getTransaction().commit();
session.close();
} // 删除对象,对关联对象的影响
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// -------------------------------------------- // a, 如果没有关联的对方:能删除。
// b, 如果有关联的对方且可以维护关联关系(有外键方),他就会先删除关联关系,再删除自己。
// c, 如果有关联的对方且不能维护关联关系(无外键方),所以会直接执行删除自己,就会有异常。 IdCard idCard = (IdCard) session.get(IdCard.class, 1);
session.delete(idCard); // Person person = (Person) session.get(Person.class, 1);
// session.delete(person); // --------------------------------------------
session.getTransaction().commit();
session.close();
} }

APP

配置文件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="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/mytest
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- 方言 -->
<property name="dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<!-- 控制台显示SQL -->
<property name="show_sql">true</property>
<!-- 自动更新表结构 -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="cn/itcast/i_hbm_oneToOne/IdCard.hbm.xml" />
<mapping resource="cn/itcast/i_hbm_oneToOne/Person.hbm.xml" /> </session-factory> </hibernate-configuration>

hibernate.cfg.xml

单向一对一主键关联例子连接

其余代码不变只需修改如下文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.i_hbm_oneToOne2"> <class name="Person" table="person2">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/> <!-- idCard属性,IdCard类型。
表达的是本类与IdCard的一对一。
采用基于主键的一对一映射方式,本方无外键方。
-->
<one-to-one name="idCard" class="IdCard"></one-to-one> </class> </hibernate-mapping>

Person.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.i_hbm_oneToOne2"> <class name="IdCard" table="idCard2">
<id name="id">
<!-- 当使用基于主键的一对一映射时,
有外键方的主键生成策略一定要是foreign。
参数property:
生成主键值时所根据的对象。
-->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="number"/> <!-- person属性,Person类型。
表达的是本类与Person的一对一。
采用基于主键的一对一映射方式,本方有外键方。 -->
<one-to-one name="person" class="Person" constrained="true"></one-to-one> </class> </hibernate-mapping>

IdCard.hbm.xml

java框架篇---hibernate(一对一)映射关系的更多相关文章

  1. java框架篇---hibernate(一对多)映射关系

    一对多关系可以分为单向和双向. 一对多关系单向 单向就是只能从一方找到另一方,通常是从主控类找到拥有外键的类(表).比如一个母亲可以有多个孩子,并且孩子有母亲的主键作为外键.母亲与孩子的关系就是一对多 ...

  2. java框架篇---hibernate入门

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDB ...

  3. java框架篇---hibernate(多对多)映射关系

    以学生和老师为例的来讲解多对多映射. 实体类: Student package cn.itcast.g_hbm_manyToMany; import java.util.HashSet; import ...

  4. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  5. java框架篇---hibernate之session状态

    Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存.更新.删除和查询方法.它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新 ...

  6. java框架篇---hibernate之CRUD操作

    CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...

  7. java框架篇---hibernate之连接池

    Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以及DBCP.在配置连接池时需要注意的有三点: 一.Apche的DBCP在Hibernate2中受支持,但在Hiber ...

  8. java框架篇---hibernate主键生成策略

    Hibernate主键生成策略 1.自动增长identity 适用于MySQL.DB2.MS SQL Server,采用数据库生成的主键,用于为long.short.int类型生成唯一标识 使用SQL ...

  9. Hibernate中的一对一映射关系

    Hibernate中的一对一映射关系有两种实现方法(单向一对一,和双向一对一)(一对一关系:例如一个department只能有一个manager) 单向和双向有什么区别呢??例如若是单向一对一,比如在 ...

随机推荐

  1. P1510 精卫填海

    P1510 精卫填海二分答案二分背包容量,判断能否满足v.判断的话就跑01背包就好了. #include<iostream> #include<cstdio> #include ...

  2. python3之Django表单(一)

    1.HTML中的表单 在HTML种,表单是在<form>...</form>种的元素,它允许用户输入文本,选择选项,操作对象等,然后发送这些数据到服务器 表单元素允许用户在表单 ...

  3. 零拷贝-zero copy

    Efficient data transfer through zero copy Zero Copy I: User-Mode Perspective 0. 前言 在阅读RocketMQ的官方文档时 ...

  4. (python数据分析)第03章 Python的数据结构、函数和文件

    本章讨论Python的内置功能,这些功能本书会用到很多.虽然扩展库,比如pandas和Numpy,使处理大数据集很方便,但它们是和Python的内置数据处理工具一同使用的. 我们会从Python最基础 ...

  5. nodejs那些事儿

    http://www.nodeclass.com/ https://cnodejs.org/ 当前版本,v6.11.2 安装node时,牵扯features的选择,在不了解的情况下,我选择了第1个.网 ...

  6. 潭州课堂25班:Ph201805201 WEB 之 页面编写 第二课 (课堂笔记)

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  7. JavaScript_原型和继承(2017-03-15)

    一.函数创建过程 在了解原型链之前我们先来看看一个函数在创建过程中做了哪些事情,举一个空函数的例子: function A() {}; 当我们在代码里面声明这么一个空函数,js解析的本质是(肤浅理解有 ...

  8. 重写alert方法,去掉地址显示

    //重写alert方法,去掉地址显示window.alert = function(name){ var iframe = document.createElement("IFRAME&qu ...

  9. Makefile 中的.PHONY

    PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字.有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能. 所谓的PHONY这个单词就是伪造的意思,makefile中将.PH ...

  10. Linux shell命令 cp 加上-f还是提示是否覆盖

    这是由于环境变量中有 allias cp='cp -i' 为了去掉这个系统自带的别名,能够使用grep -r --include="*" "alias cp"  ...