`

hibernate05:二级缓存、一级与二级的差别、主键生成策略

 
阅读更多

第一.概念

Shift+第一个+最后一个=全部选中jar包
1.数据库和tomcat服务器不在一台电脑上,一级缓存是保存在服务器的内存中,二级缓存保存在服务器的硬盘上(因此我们可以设置溢出时保存到哪个硬盘),二级缓存也是在tomcat服务器上的,因此减少了与数据库的交互次数(因为保存到服务器的话不用跟其他的电脑进行交互)。
2.hibernate的一级缓存是session级别的缓存。sessionFactory级别的缓存是二级缓存。
3.二级缓存要指定hibernate的二级缓存插件(插件是个现成的程序,需要我们指定用这个插件),需要开启
4.hibernate主配置文件中的设置都是给某个类进行赋值,是个sessionFactory类(session工厂)中的属性赋值。sessionFactory是个接口,实现类是sessionFactoryimpl
资源文件Properties 继承了hashtable,因此Properties 是个键值对。
来自JDK1.6说明文档:Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

5.在properties文件中#表示注释
6,使用二级缓存的步骤:
  ---1.开启二级缓存
 ---2.指定缓存插件(功能是把内容写到磁盘中,当开启二级缓存之后就该想到我们将来要把内容存到哪里)
  --3.写配置文件说明二级缓存的大小,在src下配置缓存文件
  --4.指定需要缓存的对象和缓存策略
7.statics是对二级缓存进行统计,输出来的内容create(可瑞的)是该对象的属性。在主配置文件中配置。
他是查看二级缓存或查询缓存区域的内容,但是如果想查看二级缓存,需要在主配置文件中进行配置。查看二级缓存是SessionFactory类中的的方法Statistics ss=HibernateSessionFactory.getSessionFactory().getStatistics();
其实不难理解为什么是SessionFactory类中的方法,因为SessionFactory表示的是二级缓存。而session表示一级缓存。

8.适合放入二级缓存中的数据:1.不经常做修改的数据,2.安全性不高的数据。
9.先查询已经缓存,一级缓存中如果没有在查询二级缓存,如果二级缓存中也没有,就查询数据库。
10.session(一级)和sesionFactroy(二级)的线程安全问题
 session是线程不安全的:ThreadLocal是给每个来的线程都给他一个副本,用这种方式来解决多线程问题。sessionFactroy是线程安全的。
注意:在hibernate主配置文件中,二级缓存的配置要放到映射文件配置的前面

11.session和sessionFactory都有evict方法,该方法的参数是个对象或者类,表示让该对象与一级缓存或者二级缓存断开联系:sessionFactory.evict(Cat.class, catId); sessionFactory.evict(Cat.class);
/**
关于二级缓存:二级缓存就是给大家共享的,每个线程都能够使用,因此就出现了多线程并发的现象。
      第一步(1):在hibernate主配置文件中写:
               <!--设置二级缓存  -->
  <property name="hibernate.cache.provider_class">
   org.hibernate.cache.EhCacheProvider
  </property>
  <!--默认是使用二级缓存的,但是可以设置关闭  -->  
  <property name="hibernate.cache.use_second_level_cache">
     false
  </property>
  <!-- 使用查询缓存 -->
  <property name="hibernate.cache.use_query_cache">true</property>
     第一步(2):在映射文件中写二级缓存的并发策略。usage表示并发策略。
 <cache usage="read-write"/>
     第二步:指定二级缓存的插件(有好多种插件都能实现二级缓存,其实就是把某个xml文件放到src目录下(放在src下就会随着项目的启动而启动二级缓存)。现在要指定插件,在老师给的hibernate-3.2下的ect目录下)
     第三步:配置上面的插件(可以只配置缓存的大小)
----------------------------------
注意:现在我们只导入了hibernate的jar包,在配置好二级缓存之后运行的时候报错Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory。
这是找不到这个jar包(也就是说明二级缓存要使用这个jar包),因此我们可以找一个这样的jar包放到项目中,也可以直接把struts框架的jar包生成,因为struts2框架的jar包就有这个jar包
并发策略有好多种,看张老师的,可是我们常用的只有两种只读模式和读写模式,当我们设置读写模式的时候就不能设置事务的隔离级别了,因为这两个是互相矛盾的。
**/

11.主键生成策略:
increment(k瑞特门):自动增长因用于mysql,
identity自增用于mysql,server,db2,
sequence是oracle中的自增
native(内t我):根据数据库自动匹配(相当于综合各种数据库),由数据库底层自己决定。
assigned:程序员自己指定
uuid:是个算法

12.hql的多表关联(多表关联有三种,一种是hql的多表关联,一个createCriteria(也就是QBC查询),一个是本地sql查询)
inner默认是内连接,inner join。左是left join
   内左外右外连接查询:查询结果是个object类型的数组,因为这个查询结果中包含两个或者两个以上的表(类),因此不能是具体类型,只能是object类型。因为包含多个表,表中又有属性,因此每个表都是一个数组。
   迫切查询:返回值是个对象

13.createCriteria多表关联
  两个参数,第一个是类名,第二个是别名,单词是alias
  两个参数,第一个参数表示地址,第二个参数是数据类型(在Criteria里面的常量)

14,hibernate的源码在hibernate-3.2这个老师给的文件中的src中,如果找二级缓存的资源文件在这个文件夹中的ect中。

一级缓存session的声明周期是与数据库的一次交互过程,当我们把session放到action层的时候,它的声明周期是一次请求和响应的过程(可能多次与数据库交互)
而二级缓存是:不但在一级缓存的map结构中存放(),还在二级缓存中存放(在二级缓存存放的内容是共享的)。
一级缓存的作用域相当于是hibernate主配置文件中的map标签里,而二级缓存的作用域相当于是整个hibernate主配置文件。
------------------
书17章:三种检索(查询)方式
1.hql语句检索:session.createQuery(hql);
2.QBC检索:session.createCriteria(XXX.class)
3.本地SQL检索:session.createSQLQuery(sql)
 

第二:代码

1、hibernate主配置文件

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>
 <!-- 注意:hibernatefactory里面配置的所有标签其实就是hibernatefactory接口中的属性,该接口的实现类是hibernatefactoryImpl,下面的所有配置 都是该实现类中的属性。 -->
<session-factory>
 <property name="dialect">
  org.hibernate.dialect.Oracle9Dialect
 </property>
 <property name="connection.url">
  jdbc:oracle:thin:@localhost:1521:ORCL
 </property>
 <property name="connection.username">chu1</property>
 <property name="connection.password">1234</property>
 <property name="connection.driver_class">
  oracle.jdbc.OracleDriver
 </property>
 <property name="myeclipse.connection.profile">chu</property>
 <property name="format_sql">true</property>
 <property name="show_sql">true</property>
 <!--设置二级缓存,指定缓存插件,是个类,是个jar包里面的类  -->
 <property name="hibernate.cache.provider_class">
  org.hibernate.cache.EhCacheProvider
 </property>
 <!--默认是使用二级缓存的,但是可以设置关闭。打开二级缓存  -->
 <property name="hibernate.cache.use_second_level_cache">
  true
 </property>
 <!-- 使用查询缓存,查询缓存有利于提高查询速度,也是个jar包里的类 -->
 <property name="hibernate.cache.use_query_cache">true</property>
 <!--表示允许查看二级缓存里面放的数据-->
 <property name="generate_statistics">true</property>

 <mapping resource="com/model/pojo/Student6.hbm.xml" />

</session-factory>

</hibernate-configuration>

 

 

2.basedao公共类

package com.comm;

import java.io.Serializable;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class BaseDao
{
 public static SessionFactory sf;
 static
 {
  Configuration cfg=new Configuration().configure("/hibernate.cfg.xml");
  sf = cfg.buildSessionFactory();
  System.out.println(sf);
 }

 public Session getSession()
 {
  return sf.openSession();
 }
 
 public Serializable save(Object obj)
 { 
  Transaction  tr=null;
  Session session=null;
  Serializable ser=null;
  try
  {
   session = this.getSession();
   
   tr= session.beginTransaction();
   
   ser=session.save(obj);
   
   tr.commit();
   
   
  }
  catch(Exception ex)
  {
   ex.printStackTrace();
  }
  finally
  {
   session.close();
  }
  return ser;
  
 }
 
 public static void main(String[] args) {
  new BaseDao();
 }
}

 

3.dao层

package com.model.dao;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.stat.Statistics;

import com.comm.BaseDao;
import com.comm.HibernateSessionFactory;
import com.model.pojo.Student6;

public class StudentDao extends BaseDao{
 //一级缓存。此时不开启二级缓存。在主配置文件中设置成false
 public void search(){
  Session session=super.getSession();
  Student6 stu=(Student6) session.get(Student6.class, 168);
  System.out.println(stu.getSname()+"\t"+stu.getSsex()); 
  //session.evict(stu);//将当前对象与session断开
  //session.clear();//清空session
  session.close();//关闭session
  Session session2=super.getSession();
  System.out.println("session是打开的?"+session.isOpen());
  //System.out.println("当前session"+session.hashCode());
  System.out.println(stu.getSname()+"\t"+stu.getSsex());//无论什么操作,这里都会输出值,因为这里跟缓存无关,由于限制存在一个完整的stu对象,所以理所当然的能够输出他的属性值。
    
 }
 //自己的session关闭之后其他session来访问相同的内容(id相同的学生),由于第一个session把查询结果放在了二级缓存中了,因此第二个session查询相同的学生的时候不会访问数据库而是直接去二级缓存中取,因此控制台输出一条sql语句
 public void search2(){
  Session session=HibernateSessionFactory.getSession();
  Student6 stu=(Student6) session.get(Student6.class, 168);
  System.out.println(stu.getSname()+"\t"+stu.getSsex());
  //session.clear();//清空一级缓存
  session.close();
  Session session2=HibernateSessionFactory.getSession();
  Student6 stu2=(Student6) session2.get(Student6.class, 168);//会查看二级缓存中有没有,当我们开启二级缓存的时候,使用二级缓存,因此不会再输出select语句了
  System.out.println(stu2.getSname()+"\t"+stu2.getSsex());//
  Statistics ss=HibernateSessionFactory.getSessionFactory().getStatistics();//getSessionFactory()是获得sesionFactory也就是获得二级缓存,getStatistics是获得二级缓存中的统计信息
  System.out.println(ss);
 }
 
 
 public static void main(String[] args) {
  StudentDao sdao = new StudentDao();
  //sdao.search();
  sdao.search2();
  //sdao.search3();
 }

}

 

 

第三:多表连接查询,对象查询的代码

1.员工表的映射文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.model.pojo">
    <class name="Emp" table="HIB_EMP" schema="CHU1">
        <id name="eid" type="int">
            <column name="EID" precision="10" scale="0" />
            <generator class="assigned" />
        </id>
        <many-to-one name="dept" class="Dept" fetch="select">
            <column name="DID" precision="10" scale="0" />
        </many-to-one>
        <property name="ename" type="string">
            <column name="ENAME" length="40" />
        </property>
        <property name="job" type="string">
            <column name="JOB" length="40" />
        </property>
     
    </class>
</hibernate-mapping>

 

2.部门表的映射文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.model.pojo">
    <class name="Dept" table="HIB_DEPT" schema="CHU1">
        <id name="did" type="int">
            <column name="DID" precision="10" scale="0" />
            <generator class="assigned" />
        </id>
        <property name="dname" type="string">
            <column name="DNAME" length="40" />
        </property>
        <set name="emps" inverse="true">
            <key>
                <column name="DID" precision="10" scale="0" />
            </key>
            <one-to-many class="Emp" />
        </set>
    </class>
</hibernate-mapping>

3.连接查询和本地查询

package com.model.dao;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;

import com.comm.HibernateSessionFactory;
import com.model.pojo.Dept;
import com.model.pojo.Emp;

public class DeptDao {

 public static void main(String[] args) {
  DeptDao ddao=new DeptDao();
  //ddao.selDept();
  //ddao.selDept1();
  //ddao.selDept2();
  ddao.selDept3();
 }
 //通过这个方法我们发现内连接,左连接、右连接的查询结果是个object类型的数组
 public void selDept(){
  Session session=HibernateSessionFactory.getSession();
  String hql="from Dept as d inner join d.emps";
  Query query = session.createQuery(hql);
  List list = query.list();
  for(int x=0;x<list.size();x++){
   System.out.print(list.get(x)+"    ");//这个得到的是个数组,也就是说集合里面放的是数组。由此得出结论
   System.out.println();
  }
  
 }
 //通过这个方法我们知道,数组中的每个元素都表示多表关联中的每个表,也就是说有几个表数组中就会有几个元素
 public void selDept1(){
  Session session=HibernateSessionFactory.getSession();
  String hql="from Dept as d inner join d.emps";
  Query query = session.createQuery(hql);
  List<Object[]> list = query.list();//首先查询结果有很多,是个list集合(query.list的返回值就是个list)。每个查询结果又是个数组,数组中的每个元素表示一个表(由于内连接,左右连接都是两个或者两个以上的表在参与)
  for(Object[] d:list){
   System.out.println(d[0].getClass().getName()+"\t"+d[1].getClass().getName());
  }  
 }
 //迫切左外连接。集合的返回值得到的是对象类型的list集合
 public void selDept2(){
  Session session=HibernateSessionFactory.getSession();
  String hql="from Dept as d left join  fetch d.emps";
  Query query = session.createQuery(hql);
  List<Dept> list=query.list();
  for(Dept d:list){
   System.out.println(d.getDname());
   Set<Emp> set=d.getEmps();
   Iterator<Emp> it = set.iterator();
   while(it.hasNext()){
    System.out.println(it.next().getEname());
   }
  }
  
 }
 //本地sql查询
 public void selDept3(){
  Session session=HibernateSessionFactory.getSession();
  String sql="select * from dept";//创建sql语句
  Query query = session.createSQLQuery(sql).addEntity(Dept.class);//addEntity是把sql变成hql,把表名变成类名
  System.out.println(query);
  int a=query.executeUpdate();
  System.out.println(a);
  
  
 }
}

 

4.对象查询

package com.model.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.comm.HibernateSessionFactory;
import com.model.pojo.Emp;

public class EmpDao {
 public static void main(String[] args) {
  EmpDao edao=new EmpDao();
  edao.selEmp();
  
 }
 //QBC查询,也叫对象查询
 public void selEmp(){
  Session session=HibernateSessionFactory.getSession();
  //第一个参数是个路径,第二个参数是别名(String associationPath, String alias)
  Criteria c = session.createCriteria(Emp.class, "e");//创建QBC查询语句,并给则个对象起个别名e
  //第一个参数是路径,第二个参数是连接类型(例如左外连接,内连接等)(String associationPath, int joinType)
  //连接类型中的1是Criteria接口的实现类CriteriaSpecification(查看源代码)中的一个常量的值,
  c.createCriteria("e.dept",1);//左连接
  c.add(Restrictions.eq("e.ename","喜洋洋"));
  List<Emp> elist = c.list();
  for(Emp e:elist){
   System.out.println(e.getEname());
   System.out.println(e.getDept().getDname());
  }
 }
 
 

}

 

 

分享到:
评论

相关推荐

    spring hibernate 事务管理学习笔记(二)

    NULL 博文链接:https://microjava.iteye.com/blog/525981

    hibernate学习笔记

    Hibernate 学习笔记 Hibernate 学习笔记 1 ...hibernate二级缓存 47 Hibernate Gossip: 二级快取(Second-level) 48 hibernate查询缓存 50 hibernate抓取策略 53 Hibernate最佳实践(Best Practices) 55

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的范例程序  22.6 小结  22.7 思考题 第23章 管理Session和实现对话  23.1 管理Session对象的生命周期  23.1.1 Session对象的生命周期与本地线程绑定  ...

    05.拓薪教育-hibernate4.3环境搭建上.part1

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    08.拓薪教育-hibernate4.3的hibernate.cfg.xml基本配置.part2

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的范例程序  22.6 小结  22.7 思考题 第23章 管理Session和实现对话  23.1 管理Session对象的生命周期  23.1.1 Session对象的生命周期与本地线程绑定  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的范例程序  22.6 小结  22.7 思考题 第23章 管理Session和实现对话  23.1 管理Session对象的生命周期  23.1.1 Session对象的生命周期与本地线程绑定  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的范例程序  22.6 小结  22.7 思考题 第23章 管理Session和实现对话  23.1 管理Session对象的生命周期  23.1.1 Session对象的生命周期与本地线程绑定  ...

    08.拓薪教育-hibernate4.3的hibernate.cfg.xml基本配置.part1

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    05.拓薪教育-hibernate4.3环境搭建上.part2

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    Hibernate教程

    4.4.4. 二级缓存与查询缓存 4.4.5. 查询语言中的替换 4.4.6. Hibernate的统计(statistics)机制 4.5. 日志 4.6. 实现NamingStrategy 4.7. XML配置文件 4.8. J2EE应用程序服务器的集成 4.8.1. 事务策略配置 ...

    hibernate 体系结构与配置 参考文档(html)

    二级缓存与查询缓存 3.4.5. 查询语言中的替换 3.4.6. Hibernate的统计(statistics)机制 3.5. 日志 3.6. 实现NamingStrategy 3.7. XML配置文件 3.8. J2EE应用程序服务器的集成 3.8.1. 事务策略配置 3.8.2. ...

    03.拓薪教育-hibernate4.3架构详解

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    01.拓薪教育-hibernate4.3介绍-序

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    Hibernate 中文 html 帮助文档

    3.4.4. 二级缓存与查询缓存 3.4.5. 查询语言中的替换 3.4.6. Hibernate的统计(statistics)机制 3.5. 日志 3.6. 实现NamingStrategy 3.7. XML配置文件 3.8. J2EE应用程序服务器的集成 3.8.1. 事务策略配置 ...

    07.拓薪教育-hibernate4.3环境搭建下

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    04.拓薪教育-hibernate4.3官方核心包介绍.part1

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    02.拓薪教育-hibernate4.3-orm剖析.part2

    hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,Hibernate多表联合查询, Hibernate二级缓存技术,...

    Hibernate学习总结

    学习成长路,Hibernate总结: 1.Hibernate入门优缺点、 2.Hibernate的操作CRUD、 3.主键生成机制、 4.持久化对象的状态、 5.映射一对多关联关系、 ...9.二级缓存、 10.Hbernate的检索方式(HQL语句)

    hibernate基础 二 关联映射 级联操作

    hibernate 的基础 常用的主键生成策略 持久化对象的三种状态 一级缓存的常用操作(save/update/saveOrUpdate/delete)一对多关联映射 级联操作

Global site tag (gtag.js) - Google Analytics