Hibernate基础知识整理(三)

继承映射

Employee(id,name,age);

Skiller  extends Employee {skill};

Seller extends Employee{sell};

一:一张表实现继承映射

create table  Employee(id int primary key,name varchar(20),age date,skill varchar(20),sell varchar(20));

映射文件Employee.hbm.xml相关配置:

<class name="Employee">

  <id name="id">

    <generator class="native"/>

  </id>

  <property name="name"/>

  <property name="age"/>

</class>

添加<discriminator  column="type" type="int">     ——鉴别器,缺省类型是字符串类型,挨着id写  ,并用discriminator-value=""进行区分,如下:

<class name="Employee"  discriminator-value="0">

  <id name="id">

    <generator class="native"/>

  </id>

  <discriminator  column="type" type="int">

  <property name="name"/>

  <property name="age"/>

  <subclass name="Skiller" discriminator-value="1">

    <property name="skill"/>

  </subclass>

  <subclass name="Seller" discriminator-value="2">

    <property name="sell"/>

  </subclass>

</class>

这种配置效率较高,但是再增加子类,就必须再增加字段,并且不能设置多出来的字段为不为空;

二:每一个子类一张表,通过外键关联

Employee(id,name,age);

Skiller  extends Employee {skill};

Seller extends Employee{sell};

表:

create table employee(id int primary key,name varchar(20),age date);

create table skiller(employee_id int primary key,skill varchar(20),foreign key (employee_id) references employee(id));

create table seller(employee_id int primary key,sell varchar(20),foreign key (employee_id) references employee(id));

 映射Employee.hbm.xml文件相关配置:

<class name="Employee">

  <id name="id">

    <generator class="native"/>

  </id>

  <property name="name"/>

  <property name="age"/>

</class>

添加

<joined-subclass name="Skiller" table="skiller"><!-- join表示数据库表中使用连接与子类关联 -->
<key column="emp_id"/><!-- 连接使用的外键列 -->
<property name="skill"/>
</joined-subclass>     如下:
<class name="Employee">

  <id name="id">

    <generator class="native"/>

  </id>

  <property name="name"/>

  <property name="age"/>

  <joined-subclass name="Skiller" table="skiller">

    <key column="emp_id">

    <property name="skill"/>

  </joined-subclass>

  <joined-subclass name="Seller" table="seller">

    <key column="emp_id">

    <property name="sell"/>

  </joined-subclass>

</class>

  

表结构合理,子类和主类差距比较大的时候使用。
多态方式查询的话关联表过多效率低。不使用多态查询的话就比较优秀

每个子类映射成一张表有如下步骤:
    父类用普通的<class>标签定义即可
    父类不再需要定义discriminator字段
    子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:
    Joined-subclass标签的name属性是子类的全路径名
    Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。
    如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。
    Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
    也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass
    标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。

 三:鉴别器和内连接相关联

Employee(id,name,age);

Skiller  extends Employee {skill};

Seller extends Employee{sell};

表:

create table employee(id int primary key,name varchar(20),age date,skill varchar(20));

create table seller(employee_id int primary key,sell varchar(20),foreign key (employee_id) references employee(id));

适用情况:雇员中销售的字段比较多但是技术的字段比较少

映射文件Employee.hbm.xml相关配置:

<class name="Employee">

  <id name="id">

    <generator class="native"/>

  </id>

  <property name="name"/>

  <property name="age"/>

</class>

添加鉴别器和join如下:

<class name="Employee" discriminator-value="0"> <!-- 鉴别属性值为0表示为普通雇员,注意:鉴别器的值如果不给的话,默认认为是类名的全名称 -->
<id name="id" >
<generator class="native"/>
</id>

<discriminator column="type" type="int"/>
<!-- 鉴别器,缺省类型是字符串类型 ,鉴别器的位置放置在property前面-->
<property name="name"/>
<subclass name="Skiller" discriminator-value="1">
<property name="skill"/>
</subclass>
<subclass name="Sales" discriminator-value="2">
<join table="sales">
<key column="emp_id"/>
<property name="sell"/>
</join>
</subclass>
</class>

  

四:每一个类一张表,且每一个表中都具有完整信息,如果父类不是抽象的,也会有父类表
<class name="Employee">
  <id name="id" >
    <generator class="hilo"/>
   </id>
  <property name="name"/>
  <union-subclass name="Skiller" table="skiller">    <!-- union表示结合的意思 -->
    <property name="skill"/>
    </union-subclass>
    <union-subclass name="Sales" table="sales">    <!-- union表示结合的意思 -->
       <property name="sell"/>
    </union-subclass>
</class>

  注意:父类和子类表的id是不能重复的,所以我们的主键生成策略不能再时native或者identity这种自增长了。

五:懒加载  懒加载就是返回的其实是一个代理对象,该代理对象是你的domain对象的一个子类。在你使用到该对象的时候,hibernate才进行数据库的查询懒加载的对象在session关闭之后调用该属性会报错。no Session,无法访问数据库,解决方法:1、在session未关闭之前就调用一下该对象的属性,使得hibernate访问数据库,将代理对象中的对应值填充好。2、使用Hibernate.initialize(Object)方法实例化懒加载的对象,这样他就会查询数据库将该对象持久化。 one-to-one(元素)懒加载必须同时满足下面三个条件:(主表不能有constrained=true,所以主表没有懒加载)1、lazy属性不等于false2、constraint=true。有外键关联3、fetch=select 抓取方式为select多对一、一对多、多对多进行懒加载的要求:lazy属性不能为false,fetch为select六:hibernate中的缓存Hibernate的缓存分为一级缓存和二级缓存;一级缓存(session级别的缓存):hibernate默认缓存;非线程安全save、update、saveOrUpdate、load、get、list、iterate、lock这些方法都会将对象存入session一级缓存中;一级缓存不能控制缓存的数量,所以请注意大批量操作数据时可能造成内存溢出,可以用evict,clear方法清除缓存中的指定对象和清空缓存。二级缓存:可插拔的缓存,SessionFactory级别,线程安全配置缓存插件的步骤:1、hibernate中开启二级缓存。在hibernate.cfg.xml中配置<property name="cache.use_second_level_cache">true</property>。这个属性在缺省状态下为true,也就是默认hibernate是打开二级缓存的2、指定二级缓存插件的提供者。这里我使用的是OSCache<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>使用该缓存插件的时候注意你有没有导入该缓存包src下面加入一个oscache.properties文件,然后在该文件中配置了os缓存的一些信息;3.加入你需要对user类的对象进行缓存,当然缓存的额是持久化对象。可以在hibernate.cfg.xml中配置:<class-cache usage="read-only" class="cn.itcast.domain.User"/>也可以在bean的映射文件中配置,比如:<class name="User"><cache usage="read-only"/>其中usage属性是表示缓存的级别:read-only则表示缓存的东西不会发生改变,比如缓存省市这种东西的时候就可以使用这个级别的缓存。如果缓存的对象发生了改变就会报错read-write表示允许对缓存的对象进行读写操作,而且具有很好的并发性,缓存的内容基本不会出现问题nonstrict-read-write表示允许对缓存的对象进行读写操作,并发要求不高,可能出现一些错误数据。在你允许一些缓存问题的情况下使用,比如评论。查看一些hibernate的状态:可以在配置文件中打开统计信息,然后借助统计信息,得到你需要的信息。<property name="hibernate.generate_statistics">true</property> 

hibernate进行数据的查询,首先在一级缓存查找,然后如果没有在二级缓存查找,如果还没有再往数据库查找

将信息放入二级缓存的方法:


save、update、saveOrUpdate、list、iterator、get、load、以及Query、Critria都会填充二级缓存,查询数据时session的iterator、get、load可以从缓存中读取数据


注意:session中的save方法不适合native生成方式的主键,也就是说native生成方式的主键使用save方法可能不会存入缓存


Query、Criteria(查询缓存)由于命中率低,所以hibernate缺省是关闭修改hibernate.cfg.xml中的property:


<property name="cache.use_query_cache">true</property>才能打开查询缓存


并且query和Criteria存储结果入二级缓存中需要使用query.setCacheable(true),Criteria.setCacheable(true)结果才能存入二级缓存


SessionFactory中使用evit()或者evitXXX()清除缓存内容


统计信息打开generate_statics用sessionFactory.getStatics()获取统计信息

 
时间: 2024-08-10 09:31:17

Hibernate基础知识整理(三)的相关文章

Hibernate基础知识整理(二)

关联映射多对一(Employee - Department)一对多(Department - Employee)一对一(Person - IdCard)多对多(teachet - student)组件映射(User - Name)集合映射(set,list,map,bag)inverse和cascade(Employee - Department) create table Department(id int primary key,name varchar(20)); create table

DIV+CSS网页布局常用的一些基础知识整理

CSS命名规范一.文件命名规范 全局样式:global.css:框架布局:layout.css:字体样式:font.css:链接样式:link.css:打印样式:print.css: 二.常用类/ID命名规范页 眉:header内 容:content容 器:container页 脚:footer 版 权:copyright 导 航:menu主导航:mainMenu子导航:subMenu 标 志:logo标 语:banner标 题:title侧边栏:sidebar 图 标:Icon注 释:note

Kali Linux渗透基础知识整理(二)漏洞扫描

Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网络上传输的数据量. TCP协议 TCP是因特网中的传输层协议,使用三次握手协议建立连接.当主动方发出SYN连接请求后,等待对方回答SYN+ACK ,并最终对对方的 SYN 执行 ACK 确认.这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议. 连接建立 TC

Java基础知识整理(一)

概述 公司业务需要,产品既要有.NET又需要Java,没得选择,只能业余时间学习Java,整体觉得Java也.NET还是很相似的,只是语法有差别,差别也不是很大,这就将学习Java的基础知识整理下,以便于自己的学习.作为个.NET程序猿也可以学习Java ,毕竟技多不压身,学习多也要精通. 开发工具 eclipse ,开发java类似.NET 需要装JDK类似.NET Framework. Java开发工具eclipse设置 1.设置字体:window设置: 2.设置快捷键:window--ke

JAVA基础知识整理

一.首先先明白get与post的基本定义和区别: 这是两种在客户端和服务器端进行请求-响应的方法. 1get:从指定的资源请求数据. 2post:向指定的资源提交要处理的数据. get基本上用于从服务器取回数据,注意:get方法可能返回缓存数据. post可以从服务器上获取数据,不过,post方法不会缓存数据,并且常用语连同请求一起发送数据. 二. Jquery $.get()方法. $.get()方法通过Http Get发起请求,从服务器上请求数据. 语法:&.get(URL,callback

web基础知识(三)关于ajax,Jquery传值最基础东西

今天补充一下两个小功能,一个是关于radio单选框的情况,如何在前面选了后,传到后台,编辑修改的时候再次传回来,并且在当时选的那个上:再一个就是关于添加小标签的时候添加接着弹出在下面,并点击出现删除. 一:radio 1 <div class="newlylist"> 2 <div class="newlyhead">图示商品:</div> 3 <div class="newlycontent">&

spring基础知识(三)——aop

spring基础知识(三)--aop面向切面编程 1.概念术语 aop面向切面编程(Aspect ariented Programming) 在开始之前,需要理解Spring aop 的一些基本的概念术语(总结的个人理解,并非Spring官方定义): 切面(aspect):用来切插业务方法的类. 连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析. 通知(advice):在切面类中,声明对业务方法做额外处理的方法. 切入点(poin

Java基础知识的三十个经典问答

Java基础知识的三十个经典问答 1.面向对象的特点 抽象: 抽象是或略一个主题中与当前目标的无关的因素,一边充分考虑有关的内容.抽象并不能解决目标中所有的问题,只能选择其中的一部分,忽略其他的部分.抽象包含两个方面:一是过程抽象:一是数据抽象. 继承 继承是一种联接类的层次模型,允许和鼓励类的重用,提供了一种明确的共性的方法.对象的一个新类可以从现有的类中派生,这叫做类的继承.心累继承了原始类 的特性,新类称为原始类的派生类或者是子类,原始类称为新类的基类或者父类.子类可以从父类那里继承父类的

perl重点基础知识整理

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86