一. 映射对象标识符 OID

  1. 先看一个测试
public void testSessionOID() {Session session = sf.openSession(); // 生成一个sessionsession.beginTransaction(); // 开启事务Student s1 = (Student) session.get(Student.class, Long.valueOf(1));Student s2 = (Student) session.get(Student.class, Long.valueOf(2));Student s3 = (Student) session.get(Student.class, Long.valueOf(1));System.out.println(s1 == s2);System.out.println(s1 == s3);session.getTransaction().commit(); // 提交事务session.close(); // 关闭session
}


2. OID原理
Hibernate的session根据OID来标识一个ORM对象,借助session缓存来减少对数据库的访问。

二. Hibernate对象主键生成策略

  1. 主键的分类
  • 业务主键
    具有业务上的含义,如学号。
  • 代理主键
    没有业务上的含义,如ID。在业务变动较大的表格中一般使用无意义的代理主键。
  1. 主键生成策略
策略 含义
increment 由 Hibernate 自动以递增的方式生成标识(ID),适用于代理主键。
identity 由底层数据库生成标识(ID)。适用于代理主键。
sequcence 由 Hibernate 根据底层数据库的序列来生成标识(ID)。适用于代理主键。
hilo Hibernate 根据 high/low 算法来生成标识(ID)。适用于代理主键。
native 根据底层数据库对自动生成标识(ID)的支持能力来选择 identity,sequence 或 hilo。适用于代理主键。

例如:Student.hbm.xml

<?xml version="1.0"?>
<!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.bee.model"><class name="Student" table="t_student"><id name="id" column="stuId"><generator class="native"> <----这里</generator></id><property name="name"></property></class></hibernate-mapping>

注解方式

 @Id@GeneratedValue(generator = "_native")@GenericGenerator(name = "_native", strategy = "native") <----这里public long getId() {return id;}

三. 关联关系

  1. 一对多映射(1:n)
    以学生表,班级表为例。
  • 主配置文件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/hibernate</property><property name="connection.username">root</property><property name="connection.password">123456</property><!-- 方言 --><property name="dialect">org.hibernate.dialect.MySQL5Dialect</property><!-- 控制台显示SQL --><property name="show_sql">true</property><!-- 自动更新表结构 --><property name="hbm2ddl.auto">update</property><!-- 映射项目中的配置文件 --><mapping resource="com/bee/model/Student.hbm.xml"/><mapping resource="com/bee/model/Class.hbm.xml"/></session-factory></hibernate-configuration>
  • 实体类——“1方”

配置文件Class.hbm.xml(与Class.java同目录)

<?xml version="1.0"?>
<!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.bee.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="native"></generator></id><property name="name" column="className"></property></class></hibernate-mapping>

实体类

package com.bee.model;public class Class {private long id;private String name;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;}}
  • 实体类——“n方”

配置文件Student.hbm.xml(与Student.java同目录)

<?xml version="1.0"?>
<!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.bee.model"><class name="Student" table="t_student"><id name="id" column="stuId"><generator class="native"></generator></id><property name="name" column="stuName"></property><!-- 定义外键关联:外键一定在“n方”——t_student --><many-to-one name="c" column="classId" class="com.bee.model.Class" cascade="save-update"></many-to-one></class></hibernate-mapping>

实体类

package com.bee.model;public class Student {private long id;private String name;private Class c; //外键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 Class getC() {return c;}public void setC(Class c) {this.c = c;}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + "]";}}
  • 自动生成的外键


    外键在“多方”——要先于“一方”删除

  • 测试

import com.bee.model.Class;
...@Testpublic void test12n() {Session session = sf.openSession(); // 生成一个sessionsession.beginTransaction(); // 开启事务Class c = new Class();c.setName("全真教");session.save(c);Student s1 = new Student();s1.setName("马钰");s1.setC(c);Student s2 = new Student();s2.setName("丘处机");s2.setC(c);session.save(s1);session.save(s2);session.getTransaction().commit(); // 提交事务session.close(); // 关闭session}
  • 新的JUnit测试类及级联保存更新
package com.bee.service;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import com.bee.model.Class;
import com.bee.model.Student;
import com.bee.utils.HibernateUtil;public class MyJUnitTest02 {private SessionFactory sf = HibernateUtil.getSessionFactory();private Session session;@Beforepublic void setUp() throws Exception {session = sf.openSession(); // 生成一个sessionsession.beginTransaction(); // 开启事务}@Afterpublic void tearDown() throws Exception {session.getTransaction().commit(); // 提交事务session.close(); // 关闭session}@Testpublic void test01() {Class c = new Class();c.setName("全真教");//注意:只有save()之后的对象才持久化到数据库中。//如果注释掉下边对c对象的save,那么c对象将成为临时对象(transient instance),且不能持久化到数据库。//session.save(c);Student s1 = new Student();s1.setName("谭处端");s1.setC(c);Student s2 = new Student();s2.setName("王处一");s2.setC(c);//那么不持久化c对象而只持久化(save)s1和s2对象会发生错误,除非...//在配置文件Student.hbm.xml中启用cascade="save-update",即级联保存更新,以保证在保存1:n的“多方”时级联持久化(save)“一方”的数据。session.save(s1);session.save(s2);}}

四. 对于1:n如何从“一方”操作“多方”的数据?

  1. 在“一方”添加数据,然后在“多方”级联添加相应的数据。
  • “一方”的实体类
public class Class {private long id;private String name;private Set<Student> students = new HashSet<Student>(); //增加操作“多方”的“抓手”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 Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}}
  • 修改Class.hbm.xml配置
<?xml version="1.0"?>
<!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.bee.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="native"></generator></id><property name="name" column="className"></property><!-- 关键是下边的:cascade="save-update" --><set name="students" cascade="save-update"><key column="classId"></key><one-to-many class="com.bee.model.Student"/></set></class></hibernate-mapping>
  • 测试
 @Testpublic void test02() {Class c = new Class();c.setName("江南");Student s1 = new Student();s1.setName("柯镇恶");Student s2 = new Student();s2.setName("朱聪");c.getStudents().add(s1);c.getStudents().add(s2);session.save(c);}
  1. 在“一方”直接查询得到“多方”的数据。
    基于前一步的实体类和配置,直接测试。
 @Testpublic void test03() {Class c = (Class) session.get(Class.class, Long.valueOf(6));Set<Student> students = c.getStudents();Iterator it = students.iterator();while (it.hasNext()) {Student s = (Student) it.next();System.out.println(s);}}
  1. 外键关联“一方”和“多方”数据
  • 孤立添加“一方”和“多方”的数据
 @Testpublic void test04() {Class c = new Class();c.setName("丐帮");Student s1 = new Student();s1.setName("洪七公");session.save(c);session.save(s1);}


  • 外键关联“一方”和“多方”的数据
 @Testpublic void test05() {Class c = (Class) session.get(Class.class, Long.valueOf(7));Student s = (Student) session.get(Student.class, Long.valueOf(7));s.setC(c);c.getStudents().add(s);}


发现SQL有冗余

在“一方”的配置文件中添加属性做优化:
Class.hbm.xml

<?xml version="1.0"?>
<!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.bee.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="native"></generator></id><property name="name" column="className"></property><!-- 在“一方”加inverse=true,从而只让“多方”生成外键关联的SQL。 --><set name="students" cascade="save-update" inverse="true"><key column="classId"></key><one-to-many class="com.bee.model.Student"/></set></class></hibernate-mapping>


4. 在“一方”删除,从而级联删除“多方”数据。

  • 修改配置文件Class.hbm.xml
<?xml version="1.0"?>
<!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.bee.model"><class name="Class" table="t_class"><id name="id" column="classId"><generator class="native"></generator></id><property name="name" column="className"></property><!-- 设置cascade="delete"以保证级联删除 --><set name="students" cascade="delete"><key column="classId"></key><one-to-many class="com.bee.model.Student"/></set></class></hibernate-mapping>
  • 测试
 @Testpublic void test06() {Class c = (Class) session.get(Class.class, Long.valueOf(6));session.delete(c);}

注意:该操作属于高危操作,一般不用。

过一下hibernate4-3相关推荐

  1. Hibernate **关于hibernate4.3版本之后org.hibernate.service.ServiceRegistryBuilder被弃用**

    之前一直都是使用hibernate4.2.21的我,有一天突然没有使用本地的jar包而是让IDEA自动下载最新版本的hibernate5.2.2之后,发现有几个经常使用的方法报错了. //创建配置对象 ...

  2. springmvc3.2+spring+hibernate4全注解方式整合(一)

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  3. hibernate4中取得connection的方法

    在hibernate3中,使用了c3p0连接池,尝试了多种办法取得connection对象,以下两种可以使用. Java代码  Connection conn; // 方法1:hibernate4中将 ...

  4. xml方式整合SpringMVC 4整合 Hibernate4

    2019独角兽企业重金招聘Python工程师标准>>> 本项目是用xml方式使用SpringMVC框架,更常用的是annotation方式,这里仅作记录.用到的所有jar包如下: 项 ...

  5. 基于Struts2.3.x+Spring3.2.x+Hibernate4.2.x+EasyUI1.3.4+Maven架构的示例程序

    基于Struts2.3.x+Spring3.2.x+Hibernate4.2.x+EasyUI1.3.4+Maven架构的示例程序 不知道为什么,保存的时候显示有一个连接为违禁内容,可能是----. ...

  6. 被spring和hibernate4逼疯

    spring3.1整合hibernate4,事务都配置上了的,但getCurrentSession()仍然获得不到 以下是各配置 web.xml ? 1 2 3 4 5 6 7 8 9 10 11 1 ...

  7. hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常

    hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常 参考文章: (1)hibernate4 和 spring3 整合注意事项 否则j ...

  8. Spring4 MVC Hibernate4集成

    2019独角兽企业重金招聘Python工程师标准>>> package com.lei.demo.entity; import javax.persistence.*; @Entit ...

  9. Spring4整合Hibernate4出现的错误的解决

    今天在使用Spring4整合Hibernate4过程中出现错误 org.hibernate.HibernateException: Could not obtain transaction-synch ...

  10. Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9整合

    java教程|Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9整合教程并测试成功一.创建项目二.搭建struts-2.3.4.11.struts2必须的Jar包(放到W ...

最新文章

  1. intval0.57100 php_php中0,'',null,false,true,FLASE,TREU,array()的相等恒等学习
  2. python连接postgresql数据库
  3. 关于相机标定的简单介绍
  4. 以前是传xml的吗_明明不太合适但是还是被用在配置文件和数据传输上的XML
  5. php的mktime,PHP mktime()函数获得本地时间戳
  6. 国内四家物联网实时操作系统浅析
  7. 如何使用python批量压缩图片_python利用Guetzli批量压缩图片
  8. windows10下Qt安装及OpenCV配置
  9. 计算机网络安全技术期末试题,归纳计算机网络安全技术期末复习试题 doc
  10. [数据挖掘笔记01] 关联规则Apriori算法
  11. kafka的topic管理常用命令
  12. 3.计蒜客ACM题库.A1597 结果填空:年龄
  13. xilinx Edition arm M3 使用笔记
  14. 宁波计算机高考总分,盘点宁波的重高成绩单,惊人的升学数据让你想不到!
  15. 畅享10S 鸿蒙,潮流配色+全能实力 华为畅享10S让你做新春最靓的仔
  16. 微信体现计算机网络功能,教你微信提现如何免手续费
  17. Active Directory(活动目录) 域服务
  18. 免费(无辜)ARP与代理ARP
  19. java方法触发器,Quartz.Net任务和触发器实现方法详解
  20. 短信接口在日常服务类行业的应用

热门文章

  1. [USACO08DEC]在农场万圣节Trick or Treat on the Farm【Tarja缩点+dfs】
  2. HDOJ 2021-2030
  3. 20221005CSP-J2/S2模拟赛总结
  4. 三、存储系统(三)主存储器
  5. workflow、BPM及EAI的区别
  6. Hudson之——持续集成服务器的安装与配置
  7. 四个视频营销策略,让你火过傅园慧,Papi酱
  8. Multisim 14.0安装教程---图文讲解
  9. 5月10日云栖精选夜读:阿里专家直击前端盛会JSConf2017_Day2:见证Moment.js精彩分享
  10. Cenots Oracle11g设置开机自启动