Hibernate框架详解

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ Hibernate框架 ↓↓↓↓↓↓↓↓↓↓↓■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


Hibernate框架;
     为什么要有?
      框架是为了简化开发人员的代码,
      和提高开发人员的开发效率,
      而在现时的项目中都是基于MVC三层架构的,
      可是在dao层中的代码出现大量的冗余,
     
      因为这些冗余代码基本只是对数据操作方式的不同,从而只有小部分代码不同而已。
     
     
     
     是什么?
    是一个应用于MVC三层开发架构中的dao层的框架,是由一群Java爱好者开发的。
     
           
     作用;
        可以简化MVC三层开发架构的dao层开发的代码,以及提高开发效率
        
        
     特点;
        1.基于ORM思想的一个框架
        2.对dao层的代码封装的很深,从而使得效率有点低下。
  3.对数据库是强事务的操作
◆ 4.底层对JDBC的代码封装
◆ 5.在一定的程度上是一个强主键的dao层框架,
  因为Hibernate框架对数据操作都是按照id进行操作的。
  ◆◆◆建议;创建表的时候,必须要有id
 
  6.是使用代理类对需要进行操作的数据类进代理模式的操作
  7.是实现了JPA接口(标准)【JPA是SUN公司定义用于ORM思想框架对Java的实现标准】


◆◆◆注;Hibernate只有对单表进行操作的时候是一个轻量级的框架。




----------------------------↓↓↓↓↓↓↓↓↓ Hibernate框架 —— ORM思想 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------




ORM思想;
是什么?
Object Relation Mappping 对象关系映射,是一个dao层框架的设计思想。


使用效果;
Java开发人员只是需要管理对象,间接的管理与数据之间的关系 


好处;
    1) 面向对象
    2) 可以不写sql语句
    3) 查询更加方便,因为直接返回对象


弊端;
    1) 如果封装的越复杂,对ORM思想的封装越彻底则越慢
    

基于ORM思想框架;
DBUtils ---> 是一个简单的ORM思想的框架不纯粹。
Hibernate ---> 是一个相对复杂的ORM思想的框架,相对的纯粹。
MyBatis ---> 是一个一般的ORM思想的框架
TopLink ---> 是IBM的框架的
。。。。。。

速度(快)的比较;
      DBUtils ---> MyBatis ---> Hibernate      
         







----------------------------↓↓↓↓↓↓↓↓↓ Hibernate框架基本开发步骤 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------




Hibernate开发步骤;
 1.导包
  必须要导入\lib\required文件夹中的所有jar包,
  因为这个包的所有jar包都是Hibernate框架的必须包。
 
 2.编写Hibernate启动配置文件 ---> 看 00_框架.txt ---> 现用框架设计的基本设计
 
   必配;
  A_ 配置连接数据库基本参数

B_ 配置数据库的运行环境

C_ 建数据库表

D_ 建立javaBean,和数据库的表映射的JavaBean

E_ 创建表-对象映射文件
i) 配置ORM映射 ---> Object Relation Mapping 对象关系映射

 3. 编写对数据库进行操作的代码
 
i) 编写读取src下的hibernate.cfg.xml文件的对象

ii) 创建服务注册器对象

iii) 使用读取sec下的hibernate.cfg.xml文件类的,
方法创建会话工厂对象维护所有的映射文件

iiii) 使用会话工厂对象创建具体的会话对象

iiiii) 使用具体的会话对象对数据库的数据进行操作

◆◆◆◆◆◆记得开启事务,关闭事务,关闭连接









----------------------------↓↓↓↓↓↓↓↓↓ Hibernate框架基本开发实现 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------



基本开发实现;
    1.导包
  antlr-2.7.7.jar    〓 ---> Hierbante辅助包
  dom4j-1.6.1.jar    〓 ---> dom4J技术对xml文件解析包
  hibernate-commons-annotations-4.0.5.Final.jar 〓 ---> Hibernate注解核心包 
  hibernate-core-4.3.8.Final.jar           〓 ---> Hibernate框架核心包
  hibernate-jpa-2.1-api-1.0.0.Final.jar 〓 ---> JPA框架支持包,融合了JPA框架
  jandex-1.1.0.Final.jar 〓 ---> Hibernate辅助包
  javassist-3.18.1-GA.jar       〓 ---> 字节码辅助包
  jboss-logging-3.1.3.GA.jar      〓 ---> 日志包
  jboss-logging-annotations-1.2.0.Beta1.jar   〓 ---> 注解日志包
  jboss-transaction-api_1.2_spec-1.0.0.Final.jar  〓 ---> 事务支持包




    2.编写Hibernate框架启动配置文件
  
  ◆建议;先确定表,确定对象在编写配置文件    

A_ 建立数据库表

B_ 创建对应的映射javaBean类

   ◆◆ C_ 编写类和数据库表的映射文件

  a)引入Hibernate框架核心包下的映射dtd约束文件,位于Hibernate核心jar包下的org.hibernate
<!DOCTYPE hibernate-mapping PUBLIC 
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

  b) 根据dtd映射约束文件编写相应的代码
<!-- 
auto-import 默认是true,
如果在项目中出现同名的类,
那么则需要设置为false。
     
     ◆那么则在代码中使用这个映射类的时候,
      需要使用类的全路径。

package 是简化在需要创建的类路径,
那么在写的时候则不需要写类的全路径了

-->
<hibernate-mapping auto-import="false" package="包路径">


<!--
   1.<class>是定义对应的javaBean类和数据库表的映射  

name 是javaBean映射类的类路径
table 是对应的数据库表名
-->
<class name="com.xx.Abc" table="xx">


<!-- 
   2.<id> 是定义这个javaBean类的属性对应的数据表主键字段
   column 是定义这个数据库表主键字段名
   
    ◆◆◆ 如果主键字段名和javaBean映射类的,
      对应属性名同名,则column属性可以不写。
   
-->
<id name="id" column="id">
<!--
   3.<generator>是定义这个主键的值策略
   
    class 是定义策略
   
    1.开发人员
    assignd 是开发人员自己添加
   
    ◆◆◆注意;如果开发人员忘记给了,
    则赋值是0,并且只会赋值一次
   
    2.底层数据库维护
    identiry 针对MySQL数据的
    squence oracle数据库,因为oracle是序列化的
    native 自适应数据库赋值
   
    3.hibernate框架维护
   
    increment 算法是最大值 + 1
    uuid 使用Java_API的UUID类赋值,
    而使用这个UUID必须要是String类型
-->
<generator class="assignd"></generator>
</id>

<!--
   4.<property> 是设置其他的表字段和javaBean映射类属性的映射
   
    name 是设置javaBean映射类的属性
    column 是设置表的映射字段
    type 是设置这个javaBean映射类的属性和这个表的字段映射类型
    ↓↓↓↓◆↓↓↓↓↓ 具体的类型看 ↓↓↓↓◆↓↓↓↓↓
    ↓↓↓↓↓
    ↓↓↓
     ↓
     
    length 是设置这个映射属性的值的大小
   
-->
<property name="name" type="java.util.String" length="2000"></property>
<property name="age" column="age" type="string" length="200"></property>

</class>
</hibernate-mapping>



  ◆◆◆映射文件小结;
    1.如果name的值和column的值相同则column可以省略不写

    2.在使用<generator>组件策略的时候是使用数据库或Hibernate框架维护,
        那么则开发人员赋值可能无效,只会使用底层自动生成的值

◆◆ 3.映射的文件名建议是;javaBean映射类 + .hbm.xml命名,
◆◆◆ 并且一个javaBean映射类对应一个*.hbm.xml文件
 
 ◆ 4.在使用··维护主键策略的时候,
  之前设置的主键的值必须要是符合这个底层维护的
    
    5.在使用type属性的时候最好使用数据库的类型,
    因为避免类型的变化和预想的类型不一样,如类型的大小等......
    
    6.建议;javaBean映射类的属性和数据库的表的字段名相同,便于后期的维护。
    
    7.建议;在当前javaBean映射类的包下创建映射文件
 
 ◆ 8.属性技巧;
         name 是类属性或类
         column 是表或字段
         key 是表
◆◆◆重◆◆◆注;因为Hibernate框架的对数据库的数据进行操作基本都是通过表的主键,
◆◆◆所以在建立表的时候必须要赋予一个主键。


   
   ◆◆ D_编写Hibernate配置文件;

 a) 引入Hierbante框架核心包下的dtd约束文件,位于Hibernate核心jar包下的org.hibernate
---> ▲▲▲注意;映射文件的dtd,文件名

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

 b) 根据dtd配置约束文件编写相应的代码
 
  <hibernate-configuration>
 
  <!-- 1.定义连接数据库的基本参数 -->
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8</property>
  <proerpty name="hibernate.connection.usename">xxx</property>
  <property name="hibernate.connection.password">xxx</property>
 
  <!-- 
  2.设置要连接的数据库方言
  这个方言类位于在Hibernate核心jar包下的org.hibernate包下,
  因为Hibernate是一个强事务的框架所以必须要找支持事务的对应数据库类。
 
     方言;是因为不同数据库对数据库的操作语句不同等等......  
  -->
  <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</proerpty>
 
  <!--
     3.hibernate.show_sql 是在使用hibernate框架是,
      对数据库的数据进行操作的时候,
        显示对应的操作sql语句。
     
  -->
  <property name="hibernate.show_sql"></proerpty>
 
  <!-- 
     4.hibernate.format_sql 
     
      是因为显示的sql语句太多了,太乱,不容易查看,
      所以将hibernate对数据库的数据进行操作的时候,
      显示的sql语句全部都是格式化的。
     
  -->
  <property name="hiberante.format_sql"></property>
 
  <!-- 
     5.hibernate.hbm2ddl.auto 
     
      是设置使用hibernate框架对数据库的数据进行操作的时候,
      如果没有表则自动创建标签。
      update  ---> 是设置如果没有表则创建,
      并且只会创建一次,如果有了表则直接对这个表进行维护
 
  create ---> 是使用每一次对数据库的数据进行操作的时候,
  旧表都会删除,重新创建一张新的表。
  -->
  <property name="hibernate.hbm2ddl.auto">update</property>
 
  <!-- 5.设置映射文件位于的类路径 -->
  <mapping resource="com/bb/aa.xml"></mapping>
 
  </hibernate-configuration>

◆◆◆◆◆注;一般是要设置某一个文件的路径,那么则是使用 ( / ) 
如果是设置某一个类的路径则是 ( . )




   ◆◆ E.编写对应的类连接数据库,并且对数据库的数据进行操作
   
    //1.调用Configuration的方法读取src下的hibernate.cfg.xml文件
   
    Configuration config = new Configuration().configure();
   
    //另;在3.0之前是直接使用Configuration的方法创建SessionFacotry对象
       // SessionFactory before = config.buildSessionFactory();
   
    //2.创建服务注册器对象,这个是在3.0之后推出的 ---> 速度可能快一点
   
    ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
   
    //3.使用Configuration的方法创建SessionFactory对象传入一个服务注册器对象
    //作用;SessionFactory类是使用加载所有的javaBean映射类的映射文件的

SessionFactory factory = registry.buildSessionFactory(registry);

//4.使用SessionFactory类的方法获取到具体的Session对象

Session session = factory.openSession();

//5.因为Hibernate框架是一个强事务的框架,所以必须要开启事物

session.beginTransaction();

//6.使用Session类的方法对数据库的数据进行操作

Student stu = new Student("小明",16);
session.save(stu);

//7.提交事务

session.getTransaction().commit();

//8.关闭连接

session.close;
factory.close();

◆◆◆◆◆注意;必须要开启事务和提交事务,
否则如果对数据库的数据进行操作的话则会无效



映射文件的type属性;
  type 是设置这个映射类属性对应的数据库类型
  而这个设置的类型的值有三种,hibernate、数据库、Java_API

+------>  对象的常用类型值;  
|   Java_API hibernate MySql
|     ↓↓↓   ↓↓↓ ↓↓↓
|   文件;    
| java.util.String string/text       varchar/text/longtext
| Java.util.Byte[]【数组[]】  binary       blob/mediumblob/longblob
|   
|   整数;
| java.lang.Integer integer       int
| java.lang.Short short       short
|   
|   小数;
| java.lang.Double double       double
| java.lang.Float float               float
|   
|   日期;
| java.lang.Date date       date/datetime/timpstamp
|
|
|
|
|
|
|  
|  
|  
|
|
|
|
|
|
————====|========———————=======〓〓〓 Hibernate框架对数据基本操作 〓〓〓======——————————=============———————————————————————————————————
|
|
| Hibernate对数据基本操作;
| 为什么要有?
| 因为Hibernate框架是一个在MVC+三层开发模式的开发中是位于dao层的,
| 而dao层是对数据库的数据进行操作的。
|
| 所以Hibernate框架必须要可以对数据库的数据进行操作。
|
| 特点;
|     1.都是使用Session类的方法对数据库的数据进行操作
|     2.必须要开启事务,因为hibernate是强事务的
|     
|     
|     
|     
|     
--------|------------------------------↓↓↓↓↓↓↓↓↓ 对数据进行添加操作 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------
|
|     
| 对数据添加操作;
| 1.创建表   ---> test
| 2.创建对应的javaBean映射类   ---> Student
| 3.编写类映射文件   ---> student.hbm.xml
| 4.编写hibernate配置文件 ---> hibernate.cfg.xml
|
| 5.编写对数据库数据操作的代码
|
| //1.使用Configuration的方法读取src下的hibernate.cfg.xml文件,并且获取到Configuration对象     
|     Configuration config = new Configuration().configure();
|     
| //2.创建一个服务注册器对象
| //传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
|     ServiceRegistry registry = new StandardServiceResgitryBuild().applySettings(config.getProperties()).build();
|     
| //3.使用Configuration的方法传入一个ServiceRegistry对象创建SessionFactory对象,维护所有的映射文件
|     SessionFactory factory = config.buildSessionFactory(resgitry);
|
| //4.使用SessionFactory的方法获取到具体的Session对象
|     Session session = factory.openSession();
|
| //5.因为hibenrate是一个强事务的框架,所以必须要开启事务
|     session.beginTransaction();
|
| //6.使用Session类的方法对数据库的数据进行···保存···操作
|     
|     a_ 方式一;使用save()方法进行保存数据,如果主键是手动的,那么则相同的主键则报错
|     Student s = new Student();
|     s.setName("小宝");
|     s.setAge(18);
|     
|     session.save(s)
|
|     b_ 方式二;使用saveOrUpdate()方法保存数据,如果主键相同则不会报错会进行一个更改操作
| session.saveOrUpdate();
|
| //提交事务
|     session.getTransaction().commit();
|
| //关闭连接
|     session.close();
|     session.close();
|     
|
|
|  
|  
--------|------------------------------↓↓↓↓↓↓↓↓↓ 对数据进行查找操作 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------
|
|
| 对数据查找操作;
| 1.创建表   ---> test
| 2.创建javaBean映射类   ---> Student
| 3.编写类映射文件   ---> student.hbm.xml
| 4.编写配置文件   ---> hibernate.cfg.xml
|
| 5. 编写对数据库数据进行操作代码
|
| //1.使用Configuration的方法读取src下的hibernate.cfg.xml文件
| Configuration config = new Configuration().configure();
|
| //2.创建服务注册器对象
| //传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
| ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
|
| //3.使用Configuration的方法传入一个服务注册器对象创建SessionFactory对象,用于维护所有的映射文件
| SessionFactory factory = config.buildSessionFactory(registry);
|
| //4.使用SessionFactory方法,创建一个具体的Session对象
| Session session = factory.openSession();
|
| //5.Hibernate是一个强事务的dao层框架所以要开启事物
| session.beginTransaction();
|
| //6.使用Session类的方法对数据库的数据进行···查找···操作
|
| a_ 方式一;用get()方法,传入一个对应的javaBean映射类的类对象,
| 并且通过传入一个数据库的主键的值,因为主键是唯一。
| ---> 获取某一个具体数据
| Student stu = (Student)session.get(Student.class,1);
|
| b_ 方式二;用load()方法,传入对应javaBean映射类的类对象,
| 并且通过传入一个数据库的主键的值,因为主键是唯一。
| load()和get()有区别↓↓↓立即加载vs延迟加载
|
| Student stu = (Student)session.load(Student.class,1);
|
| c_ 方式三;使用hibernate定义的对数据库操作的语句 ---> 获取所有的数据
|
| Query query = session.createQuery("select s from Student s");
| List<Student> list = query.list();
|
| for(Student s : list){
| sysout(s);
| }
|
|
| c_ 方式四;使用hibernate定义HQL语句的对数据库操作的语句,定义的是预定义的语句
|
| Query query = session.createQuery("select s from Student s where id=?");
|
| ◆◆◆ //对于预定义语句的值,必须是从0开始的
| query.setParameter(0,1);
|
| Student s = (Student)query.uniqueResult();
|
| d_ 方式五;使用hibernate定义的QBC语句的对数据查找的语句,也是有预定义的值的
|
| Criteria criteria = session.createCriteria("select s from Student s where id=2");
| //使用Restrictions的对应数据库的语句,存入对应的属性字段名,并且设置值
| crriteria.add(Restrictions.eq("salary",6000));
| List<Student> stu = critera.list();
| for(Student s : list){
| sysout(s);
| }
|
| //7.提交事务
| session.getTransaction().commit();
|
| //8.关闭连接
| sesion.close();
| factory.close();
|
|
| ◆◆◆具体查找语句看↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓Hibernate框架查询数据
|
| ◆◆◆注;查找数据,并没有对数据起到了操作的作用,
| 所有也可以不开启事务,但是开启事务符合标准规范。     
|     
| ◆◆◆注;在使用Hibernate定义的对数据库的数据进行查找的语句,
| 如果返回的是多个对象,则是使用list()方法,
| 如果是单个则使用uqueResult()方法。
|     
|     
--------|------------------------------↓↓↓↓↓↓↓↓↓ 对数据进行更新操作 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------
|
|
| 对数据更新操作;
| 1.创建表   ---> test
| 2.创建对应的javaBean映射类对象   ---> Student
| 3.编写类映射文件   ---> student.hbm.xml
| 4.编写配置文件   ---> hibernate.cfg.xml
|
| 5.编写对数据库操作的代码
|
| //1.使用Configuration的方法读取src文件下的hibernate.cfg.xml文件
| Configuration config = new Configuration().configure();
|
| //2.创建服务注册器对象,注册服务器连接
| //传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
| ServiceRegistry registry = new StandardServiceRegisryBuilder().applySettings(config.getProperties()).build();
|
| //3.使用Configuration的方法传入一个服务注册器对象创建SessionFactory对象,用于维护所有的映射文件
| SessionFactory factory = config.build(registry);
|
| //4.创建具体的Session对象
| Session session = factory.openSession();
|
| //5.因为Hibernate是一个强事务的框架,所以要开启事务
| session.getTransaction();
|
| //6.使用Session的方法对数据库的数据进行···更改···的操作
|
| a_ 方式一;定义一个需要更改的对应的javaBean映射类,使用Session的方法进行操作
| Student s = new Student();
| s.setId(2);
| s.setName("小明");
| s.setAge(20);
|
| session.update(s);
|
| c_ 方法二;使用saveOrUpdate()方法,没有数据则保存,有数据则进行更改
| session.saveOrUpdate(s);
|
| b_ 方式二;使用查找出来的对象,对这个对象的数据进行更改并且提交
| Student s = (Student) session.get(Student.class,2);
| s.setName("小黑");
| s.setAge(18);
|
|
|
| //7.提交事务
| session.getTransaction().commit();
|
| //8.关闭连接
| session.close();
| session.close();
|
| ◆◆◆建议;使用先查找后修改的方式
|
|
|
|     
|     
|     
--------|------------------------------↓↓↓↓↓↓↓↓↓ 对数据进行删除操作 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------
|
|
| 对数据删除操作;
| 1.创建表 ---> test
| 2.创建对象的javaBean映射类 ---> Student
| 3.配置对象的类的映射文件 --->  student.hbm.xml
| 4.编写hibernate框架的配置文件 ---> hibernate.cfg.xml
|
| 5.编写对数据库数据进行操作的代码
|
| //1.使用Configuration的方法读取src下的hibernate.cfg.xml文件
| Configuration config = new Configuration().configure();
|
| //2.创建服务注册器对象
| //传入config.getProperties()方法的数据,
| //使用hibernate.cfg.xml文件配置的连接数据库的参数
| ServiceRegistry registry = new StandardServiceRehgistryBuilder().applySettings(config.getProperty).build();
|
| //3.使用Configuration类的方法传入一个ServiceRegistry对象创建SessionFactory对象用于维护所有的的映射文件
| SessionFactory factory = config.buildSessionFactory(registry);
|
| //4.使用SessionFactory的方法创建具体的Session对象
| Session session = config.openSession();
|
| //5.因为Hibernate框架是一个强事务的dao层的框架,所以要开启事物
| session.beginTransaction();
|
| //6.使用Session的方法对数据库的数据进行···删除···操作
|
| ◆建议;先查找在删除,可以避免各种问题......
|
| a_ 使用查找到的对象进行删除,因为查找到的对象包括了主键
| Student s = session.get(Student.class,1);
| session.delete(s);
|
| b_ 自定义一个对象,因为Hibernate是根据主键进行删除的, ---> 不建议
| 所以只需要设置这个对象的主键的值就可以了。
| Student s = new Student();
| s.setId(5);
| session.delete(s);
|
| //提交事务
| session.commit();
|
| //关闭连接
| session.close();
| factory.close();
|
|
|
|
|
————————|—————————————————————————————————— Hibernate框架 —— 存储文件 —————————————————————————————————————————————————————————————————————
|
|
| 存储文件;
| 为什么要存储文件?
| 虽然数据库资源很宝贵,所以不建议存储数据,
| 但是有一些机密的数据需要存储到数据库中。
|  
| 特点;必须要使用对应的类型进行操作
|
| 文件类型;
+---------------------->  二进制类型;↑↑↑↑↑↑↑↑↑↑↑↑看上类型↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ---> byte[] 
+---------------------->  文本类型;↑↑↑↑↑↑↑↑↑↑↑↑↑看上类型↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ---> String









-------------------------↓↓↓↓↓↓↓↓↓ Hibernate框架 —— 存储文件实现代码 ↓↓↓↓↓↓↓↓↓↓↓-------------------------------------------
 
  
文件实现代码;
    1.创建表 ---> test === 要有对应的文件类型的字段                    <--|
    2.创建javaBean映射类 ---> Student === 必须要有对应的文件类型的属性 <--|
    3.编写类映射文件 ---> studen.cfg.xml
    4.编写hibernate配置文件 ---> hibernate.cfg.xml
    
    5.操作文件数据实现代码
    //1.创建Configuration对象,使用这个类的方法读取src下的hibernate.cfg.xml文件
    Configuration config = new Configuration().configure();
   
    //2.创建ServiceRegistry对象
    //传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
    ServiceRegistry registry = new StandardServiceResgiryBuilder().applySeyttings(config.getProperties()).build();
   
    //3.使用Configuration的方法传入一个注册服务的对象用于创建SessionFactory对象,用于维护所有的映射文件
    SessionFactory factory = config.buildSessionFactory(registry);
   
    //4.使用会话工厂对象的方法创建具体的Session对象
    Session session = factory.openSession();
   
    //5.因为Hibernate是一个强事务的dao层框架,所以要开启事物
    session.beginTransaction();
   
    //6.使用session的方法对数据进行保存 


———————=============———————=======〓〓〓 Hibernate框架数据映射 〓〓〓======——————————=============———————————————————————————————————


数据映射;
为什么要有?
在各种项目的数据存放到数据库中,
一个项目基本都会有几个表等,
但是这些表之间可能有关联,
那么在使用Hibernate对数据库的数据进行查找的时候,
怎么查找出关联的数据?


是什么?
是Hibernate定义的一个重要的功能。


作用;
     用于查询数据库的表数据的时候,也查询到这个表的关联表的数据。
 
 
特点;
     1.都是有关联关系的。
     2.数据库最少有两张表
       



----------------------------------------- Hibernate框架数据映射分类 -----------------------------------------


数据映射分类;
    类型分类;
         基本属性映射;
       Set集合
       List集合
       Map集合
       
    ◆注;普通的属性映射,使用集合的时候,
    是按照使用的这个集合的特性进行使用的。
    如;Set是无序的,那么存放则是无序的
   
            
         对象映射;
一对多 ---> 单向
    多对一 ---> 单向
   
    一对多(多对一) ---> 单向
               
                多对多 ---> 双向
一对一 ---> 双向/单向


——————————————————————————————————— Hibernate框架基本类型映射实现代码 ———————————————————————————————————————————————————————

------------------------------------------------ Set集合映射 -------------------------------------------------------


Set集合
   特点;无序,在一次使用(存储到集合)的时候不可重复,
    如果这个对象在集合中销毁了才可以重复
   
a_ 创建表 ---> student
b_ 创建对应的表的javaBean类 ---> Student

▲ 在编写这个类的时候需要指定集合成员变量,并且提供对应的get()和set()方法
Set<String> address;

◆◆◆ 建议;加上泛型,可以控制数据的完整性和安全性

c_ 编写hibernate.cfg.xml文件
d_ 编写对应的类的映射文件

▲ 编写对应的集合成员变量的表映射

<set name="address">
    <key column="a_id"></key>
    <element type="string" column="s_address"></element>
</set>

说明;
    <set> 是用于配置对应javaBean映射类的Set集合成员变量
    name 是这个成员变量位于这个javaBean的成员变量名
   
    <key> 是设置这个副表和主表之间的外键
    column 是这个副表的外键字段名,会自动使用主键的

<element> 是设置这个副表存放数据的字段,
因为在集合中是存放数据的,
而集合中的数据中就是存放到数据库的。

type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,
映射文件的type属性。
column 是可以设置这个集合的数据存放的字段

◆◆◆注;这些属性是必须要配置的,缺一不可。  



e_ 在操作类中编写代码

//1.创建Configuration类对象,并且使用这个类的方法读取src下的hibernate配置文件
Configuration config = new Configuration().config();

//2.创建注册服务器对象
//传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
ServiceRegistry registry = new StandardServiceRegistry().applySettings(config.getProperties()).build();

//3.通过Configutaion的方法创建SessionFactory对象,
// 用于维护所有的映射文件以及二级缓存,并且传入一个ServiceRegistry的对象
SessionFactory factory = config,buildSessionFactory(registry);

//4.使用会话工厂的方法创建一个具体的Session对象
Session session = factory.openSession();

//5.因为Hibernate框架是一个强事务的框架,所以必须要开启事务
session.beginTransaction();

//6.设置数据
Set set = new Set();
set.add("广州中山大道西");

Student stu = new Student();
stu.setAddress(set);

//7.提交事务
session.getTransaction().commit();

//8.关闭连接
session.close();
factory.close();





---------------------------------------------- List集合映射 -------------------------------------------------------


List集合;
     特点;有序,存储到集合的数据是可以重复的。
     
a_ 创建表 ---> student
b_ 创建对应的javaBean映射类对象 ---> Student

▲ 在Student映射类中需要创建这个List集合类型的成员变量,
并且必须要提供get()和set()方法。
List<String> address;

◆◆◆ 建议;加上泛型,可以控制数据的完整性和安全性

c_ 编写对应的javaBean类的映射文件

▲ 编写javaBean类的List集合成员变量的映射

<list name="address">
<key column="a_id"></key>
<list-index column="l_id"></list-index>
<element type="string" name="l_address"></element>
</list>

说明;
    <list> 是定义这个映射类中的List集合的属性的数据映射
    name 是这个List集合在映射类中的成员变量名
   
<key> 是设置当前这个类位于这个集合对应的数据库表(副表)的外键
column 是这个外键的字段名

<list-index> 因为List集合是一个有序的,
而如果是使用主键(id)可能出现不符合有序(小到大)特点

如;删除了id=2的数据,那么则可能出现一个空行

column 是这个序号的值字段名

<element> 是这个集合数据的存储的字段

type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,
映射文件的type属性。
column 是指定这个字段的值
d_ 编写hibernate配置文件

e_ 编写操作数据的代码

//1.创建Configuration对象读取src下的hibernate.cfg.xml
Configuration config = new Configuration().configure();

//2.创建注册服务器对象,
//传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
ServiceRegistry registry = new StandardServiceRegistry().applySettings(config.getProperties()).build();

//3.通过Configuration的方法传入服务注册的对象创建会话工厂对象,用于维护所有的映射文件和二级缓存。
SessionFactory factory = config.buildSessionFactory();

//4.通过会话工厂对象创建具体的会话
Session session = factory.buildSession();

//5.因为Hibernate框架是一个强事务的框架,所以要开启事物
session.beginTransaction();

//6.操作数据

List<String> list = new List();
list.add("上海体育路");

Student student = new Student();
student.setList(list);

session.save(student);

//7.提交事务
session.getTransaction().commit();

//关闭连接
session.close();
factory.close();





------------------------------------------------ Map集合映射 -------------------------------------------------------


Map集合;
特点;保存在Map集合的数据,key是不可重复的,并且Map是无序的,但在映射中...... --->+
         |
 +<----------------------------------------------------------------------------------------+
 |
 |  a_ 创建表 ---> student
 |  b_ 创建表对应的javaBean映射类 ---> Student
 |  
 |   ▲ 在这个映射类中要创建一个Map集合类型的成员变量,并且提供get()和set()方法
 |
 | Map<String,String> cargo;
 |
 |  c_ 编写javaBean类的映射文件
 |  
 |   ▲ 编写javaBean映射类的Map成员变量的映射
 |  
 |   <map name="cargo"> 
 |        <key column="c_id"></key>
 |        <map-key type="string" column="number"></map-key>
 |        <element type="string" column="c_name"></map_key>
 |   </map>
 |  
 |   说明;
 |       <map> 是定义这个映射类中的Map类型的成员变量的
 |       name 是这个成员变量位于这个映射类中的成员变量名
 |      
 |       <key> 是当前这个映射类位于这个Map副表的外键,自动使用主表的主键值
 |       column 是这个外键的字段名
 |      
 |       <map-key> 因为map的key的是用于唯一标识当前这个类的Map属性的key
 +---------------------------------------->   如果在存储的时候,Map集合的数据出现key重复则使用后定义的。
      type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,
映射文件的type属性。
      column 是指定这个字段的名字
     
      <element> 是这个Map集合的value对应的字段
     
      type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,
映射文件的type属性。
      column 是指定这个字段的名字

 d_ 编写hibernate配置文件
 e_ 编写操作数据代码
  //1.创建Configuration对象读取src下的hibernate.cfg.xml
Configuration config = new Configuration().configure();

//2.创建注册服务器对象,
//传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
ServiceRegistry registry = new StandardServiceRegistry().applySettings(config.getProperties()).build();

//3.通过Configuration的方法传入服务注册的对象创建会话工厂对象,用于维护所有的映射文件和二级缓存。
SessionFactory factory = config.buildSessionFactory();

//4.通过会话工厂对象创建具体的会话
Session session = factory.buildSession();

//5.因为Hibernate框架是一个强事务的框架,所以要开启事物
session.beginTransaction();

//6.操作数据

Map<String,String> map = new HashMap();
map.add("上海体育路");

Student student = new Student();
student.setList(map);

session.save(student);

//7.提交事务
session.getTransaction().commit();

//关闭连接
session.close();
factory.close();
 
 


———————————————————————————————————————————————— 自定义工具类 ——————————————————————————————————————————————————————————  


自定义工具类;
    因为Hibernate框架定义的对数据进行操作的代码太多是冗余了,所以可以考虑抽象为一个工具类
   
    class HibernateUtils{
    private static SessionFafactory factory = null;
   
    //获取具体的会话对象
    public static Session getSession(){
    //1.创建Configuration对象读取src下的hibernate.cfg.xml
Configuration config = new Configuration().configure();

//2.创建注册服务器对象,
//传入config.getProperties()方法的数据,
//使用hibernate.cfg.xml文件配置的连接数据库的参数
ServiceRegistry registry = new StandardServiceRegistry().applySettings(config.getProperties()).build();

//3.通过Configuration的方法传入服务注册的对象创建会话工厂对象,用于维护所有的映射文件和二级缓存。
SessionFactory factory = config.buildSessionFactory();

//4.通过会话工厂对象创建具体的会话
Session session = factory.buildSession();
   
    //5.返回具体的会话对象
    return session;
    }
   
   
    //关闭连接
    public static void closeConnect(Session session){
    if(session != null){
    session.close();
    }
    if(factory != null){
    factory.close();
    }
    }
    }
   





———————————————————————————————————— Hibernate框架对象映射实现代码 ———————————————————————————————————————————————————————


     ◆◆◆◆◆◆技巧;1.在做对象映射的时候必须要先确定关系,那个是一方,那个是多方,
因为一方是用集合作为多方的成员变量,多方直接用一方的对象作为成员变量。
2.确定外键是在哪一方(表/类)
3.确定主表和副表
 

------------------------------------------------- 一对多映射 单向 -------------------------------------------------------


一对多映射;客人=订单
  1.确定关系;
       Customers 是一方   ---> 主表
       Orders 是多方      ---> 副表
  2.外键位于Orders
  
  
  a_ 创建表 ---> customers(客户)、orders(订单)
  b_ 创建对应的javaBean对象 ---> Customers、Orders
 
  Customers Orders
     id  id
     name  number
     Set<Orders>
 
  ▲ 在Customers类中先定义一个集合,
  类型为Orders的成员变量,
  提供get()和set()方法。
 
  private Set<Orders> orders = new HashSet();  ---> 为了简化操作时的代码
  get()......
  set()......
 
  c_ 编写javaBean类映射文件
 
  在orders映射文件中,按照正常映射书写
 
  ▲ 在Customers映射文件中,加上
 
  <set name="orders" cascade="all" inverse="true">
      <key column="c_id">
      <many-to-one class="com.xx.orders"></many-to-one>
  </set>
 
  说明;
      <set> 是设置成员变量中的Set集合的数据
      name 是这个set集合位于Customers(一方)类中的成员变量名
      cascade 是设置这两个关联的表的级联
      save-update ---> 添加和修改的级联
      delete ---> 删除级联
      all ---> 包含上面所有
     
      +<----- inverse 是设置这个外键的维护权反转给别的表
      |   false ---> 默认
      |   true ---> 交给别的类维护外键值
      |  
      | 这个是为了提高效率的。
      |
      |--------> 如;在做添加的时候,
      hibernate的insert into .....语句中的外键是没有值,
      而后面在使用update语句给这个外键赋值的。
     
      ◆◆◆◆◆注;默认的维护权在一方
       
     
      <key> 是设置当前这个Customers类位于的Orders(多方表)的外键字段
      column 是外键字段名
     
      <many-to-one> 是指定这个外键位于的表对应的javaBean映射类的类路径
      class 是指定这个映射类的类路径
     
 
  d_ 编写hibernate映射文件
  e_ 编写操作数据代码
 
  //1.使用 ↑↑↑ HiberteneUtils类的方法获取具体的会话对象
Session session = HibernateUtils.getSession();

//2.因为Hibernate是强事务的,所以要开启事务
session.beginTransaction();

//3.操作数据

Orders order = new Orders();
order.setNumber("a201611");

Customers customer = new Customers();
customer.setName("小明");
customer.getOrders().add(order);

//4.提交事务
session.getTransaction().commit();

//5.使用 ↑↑↑ HiberteneUtils类的方法关闭连接
HibernateUtils.closeConnet(session);





------------------------------------------------- 多对一映射 单向 -------------------------------------------------------


多对一映射;客人=订单
  1.确定关系;
       1.Customers ---> 一方
       2.Orders ---> 多方
  2.外键位于Orders     
  3.确定主副表;
  1.Customers ---> 主表
  2.Orders ---> 副表
 
  a_ 创建表 ---> customers(主表)、orders(副表)
  b_ 创建对应的javaBean映射类  
   
    Customers Orders
      id  id
     name number
      Customers customer 
   
  ▲ 在Orders类中创建Customers类类型的成员变量
  private Customers customer;
 
  c_ 编写映射文件
  
  ▲ Customers则按照正常的规则进行编写
 
  ▲ Orders则按照正常规则编写,在编写一个映射
 
  <many-to-one name="customer" 
  column="c_id"
    class="com.xx.Customers" 
       cascade="all"></many-to-many>
 
  说明;
      <many-to-one>是设置这个副表和主键直接的关系
      name 是Customers(主表)这个类位于Orders类的成员变量名
      column 是设置这个Customers映射类的表,
      位于Orders映射类的表的外键字段名。
      class 是这个外键的级联的类的类路径
      cascade 是设置这两个表之间的级联范围
      save-update 保存/修改级联
      delete 删除级联
      all 所有
     
      ◆◆◆注;因为在多对一中是由副表(外键表)来进行操作的

  d_ 编写hibernate.cfg.xml配置文件
  e_ 编写操作代码
 
  //1.使用 ↑↑↑ HiberteneUtils类的方法获取具体的会话对象      
  Session session = HibernateUtils.getSession();
 
//2.因为Hibernate是一个强事务的框架,所以要开启事务
    session.beginTransaction();

//3.操作代码
Customers customer = new Costomers();
customer.setName("夏洛莱");

Orders order = new Orders();
order.setNumber("201611");
order.setCustomers(customer);

//4.提交事务
session.getTransaction().commit();

//5.使用 ↑↑↑ HiberteneUtils类的方法关闭连接
HibernateUtils.closeConnect(session);





--------------------------------------------- 一对多(多对一)映射 双向 -------------------------------------------------------


一对多(多对一)映射;客人=订单 --->   就是一对多和多对一单向合并就是双向了,但是要注意外键维护权。
   1.确定关系;
    Customers ---> 一方
    Orders ---> 多方
   2.外键位于Orders
   3.确定主表和副表;
        1.Customers ---> 主表
        2.Orders ---> 副表
   
   a_ 创建表 ---> customers(主表)、orders(副表)
   b_ 创建对应的javaBean映射类
   
    Customers Orders
     id    id
     name   number
     Set<Orders> orders Customers customer
     
     ▲ 在Costomer类中创建对应的Orders类类型的集合(Set)的成员变量,
      并且提供对应的get()和set()方法。
private Set<Orders> orders = new HashSet();  ---> 为了节约代码
get()......
set()......
 
 
 ▲ 在Orders类中创建对应的Customers类的成员变量,
  并且提供对应的get()和set()方法。
  private Customers customer;
 
 
   c_ 编写对应的javaBean映射类的映射文件

▲ 编写Customers映射类的映射文件,
其余的属性正常编写。
  <set name="orders" cascade="all" inverse="true">
      <key name="c_id"></key>
      <one-to-many class="com.xx.Orders"></one-to-many>
  </set>
 
  说明;
      <set>是设置javaBean类的这个集合数据和副表的映射
      name 是这个Set集合成员变量名
      cascade 是设置关联表之间的级联
      save-update ---> 保存/修改级联
      delete ---> 删除级联
      all ---> 包含所有
 
  inverse 是设置这个外键的维护权, ---> 默认是false
  因为如果是一对多双向的情况下,
  建议;最好把外键给副表维护。
 
  因为主表的对应类添加数据的时候,
  Hibernate发送第一条的sql语句是,
  没有加上外键值的之后会在使用,
  update进行修改的,这样降低了效率.
也避免出现不可预知性的错误

<key> 是定义这个Cutomers(主表)位于Orders(副表)的外键
column 是这个外键字段名

<one-to-many> 是设置这个映射的类型,
这个Orders(副表)对应的类路径。


▲ 编写Orders映射类的文件,
其余属性正常规则编写。

<many-to-one name="customer" 
column="c_id" 
  class="com.xx.Customers" 
     cascade="all">
</many-to-one>  

说明;
    <many-to-one>是设置映射类(表)和关联表的关联
    name 是这个关联表对应的映射类位于当前这个类的成员变量名
    column 是这个设置外键字段名
    class 是设置这个对应的关联类的类路径
    cascade 是设置与关联类直接的级联
    save-update ---> 保存/更改级联
    delete ---> 删除级联
    all ---> 包含所有
    
    
  ◆◆◆◆◆注;双方的外键的字段名必须要是同一个。。。。。。

   d_ 编写hibernate.cfg.xml配置文件
   e_ 编写操作代码
   
    //1.使用 ↑↑↑ HiberteneUtils类的方法获取具体的会话对象
    Session sesion = HibernateUtils.getSession();
   
    //2.因为Hibernate是强事务的,所以要开启事务
    session.beginTransaction();
   
    //3.操作数据
    Orders orderT = new Orders();
    order.setNumber("201611");
   
    Customers customer = new Customers();
    customer.setName("西华海");
    cutomer.getOrders().add(customer);
   
    Orders order = new Orders();
    order.setNumber("201612");
    order.getorders().add(customer);
   
    session.save(order);
   
   
    //4.提交事务
    session.getTransaction().commit();
   
    //5.使用 ↑↑↑ HiberteneUtils类的方法关闭连接
    HibernateUtils.closeConnet(session);





---------------------------------------------- 多对多映射 双向 -------------------------------------------------------


多对多映射;老师 = 学生
  1.确定位置;
       Student 多方
       Teacher 多方
       
  2.使用一个中间表的字段作为外键,
  但是外键不可以重复所以这个2个外键都设置为主键,
  因为在多对多映射中都是多方,并且都是主表。
  
  3.确定主副表;
  Student 主表
  Teacher 主表
       
       
  a_ 创建表 ---> student、teacher
  b_ 创建对应的javaBean类
 
  Student Teacher
   id  id
   name  name
   Set<Teacher> teacher  Set<Student> student

▲ 在Student映射类中创建对应的集合成员变量,类型为关联类的类型
Set<Teacher> teacher = new HashSet(); ---> 节省操作代码

▲ 在Teacher映射类中创建对应的集合成员变量,类型为关联类的类型  
Set<Student> student = new HashSet(); ---> 节省操作代码
 
          c_ 编写映射类的映射文件

▲ 编写Student映射类的映射文件,  ---> Student让出外键维护权
其余的属性按照正常规则编写。

<set name="teacher" table="stu_tea" cascade="all" inverse="true">
     <key column="s_id"></key>
     <many-to-many class="com.xx.Teacher" column="t_id"></many-to-many>
</set> 

说明;
    <set> 是配置中间表(关联表)的数据
    name 是这个javaBean映射类对应的表的关联表对应的javaBean类

table 是中间表名,因为多对多映射是使用一个中间表进行关联的

cascade 是设置两个实体表,之间的级联
save-update ---> 保存/修改级联
delete ---> 删除
all ---> 所有

inverse 是设置这个外键维护权的权利,默认是一方维护, ---> false默认
但是在多对多中的类都是多方,那么则必须要设置维护权。

<key> 这个key是当前这个映射类位于中间表 的主外键值
column 当前这个类的主外键的字段名

<many-to-many> 是设置这个当前映射类的关联类(表)
class 是这个关联类的类路径
column 是这个关联类(表)位于中间表的主外键字段


▲ 编写Teacher映射类的映射文件,
其余的属性按照正常规则配置。

<set name="sutndet" table="stu_tea" cascade="all">
    <key column="stu_tea"></key>
    <many-to-many class="com.xx.Student" column="s_id"></many-to-many>
</set>

说明;
    <set> 是设置这个类(表)的关联映射类(表)
   
    name 是这个关联类位于当前类的成员变量的变量名
   
    table 这个中间表的表名,因为多对多映射是依靠中间表进行管理
   
    cascade 是当前这个映射类对应的表和关联表的级联
    save-update ---> 保存/修改级联
    delete ---> 删除级联
    all ---> 包括所有
   
    ◆◆注;因为Student映射类以及反转出主外键的控制权了
   
    <key> 是当前这个映射类位于中间表的主外键字段名
    column 是当前的映射类主外键字段名
   
    <many-to-many> 是设置这个关联类的映射
    class 是这个关联类的路径
    column 是这个关联类位于中间表的主外键字段名


◆◆◆◆◆注;hibernate框架会自动将其设置为主外键

◆◆◆◆◆注;因为多对多中的类都是多方,并且双方都是主表,
所以必须要有一方让出外键(主键)维护权。

这个外键必须要设置成为一个主键,或者是唯一的,
否则数据结构会遭到破坏,使得业务需要被破坏。


  d_ 编写hibernate.cfg.xml配置文件
  e_ 数据操作的代码
 
  //1.使用 ↑↑↑ HiberteneUtils类的方法获取具体的会话对象
  Session session = HibernateUtils.getSession();
 
  //2.因为Hibernate框架是一个强事务的框架,所以必须要开启事务
  session.beginTreansaction();
 
  //3.数据操作
 
  Student stu1 = new Student();
  stu.setName("小白");
 
  Teacher tea1 = new Teacher();
  tea1.setName("郑老师");
  tea1.getStudent().add(stu1);
 
  Student stu2 = new Student();
  stu2.setName("黄老师");
  stu2.getTeacher().add(tea1);
 
  session.save(stu2);
 
  //4.提交事务
  session.getTransaction().commit();
 
  //5.使用 ↑↑↑ HiberteneUtils类的方法关闭连接
  HibernateUtils.closeConnect(session);
 
 



---------------------------------------------- 一对一映射 双向 -------------------------------------------------------

  
一对一映射; --- 外键字段必须是唯一的
  1.确定关系;
       Person ---> 一方
       IdCard ---> 一方
  
  2.外键位于idcard
  3.确定主副表;
  person ---> 主表
  idcard ---> 副表
  
  a_ 创建表 person、idcard
  b_ 创建对应的映射类
  Person IdCard
   id  id
   name  number
   IdCard idCard  Person person
 
  ▲ 编写Person映射类的映射文件,
  其余属性都是按照正常规则编写。
 
  <one-to-ont name="idCard" 
  class="com.xx.IdCard"
    cascade="all"></one-to-one>
 
  说明;
      <one-to-one> 是设置这个类(表)对应的关联类(表)
      name 是这个关联类位于当前类的成员变量
     
      class 是这个关联类的类路径
     
      cascade 设置当前类(表)和关联类(表)的级联
      save-update ---> 保存/修改级联
      delete ---> 删除级联
      all ---> 包括所有级联
 
 
  ▲ 编写IdCard映射类的映射文件,
  其余属性按照正常规则编写。
 
  方式一;外键 - 特殊的多对一    
     <many-to-one name="person" 
        column="p_id"
            class="com.xx.Person"
               cascade="all"
                unique=true></many-to-one>   

   说明;
    <many-to-one>在一对一中这是一个特殊的多对一配置从而配置为一对一的映射
    name 是这个关联类位于当前类的成员变量名
    column 是这个关联类位于当前类(表)的外键字段名
    class 是这个关联类的类路径
    cascade 当前这个映射类(表)与关联类的级联
    save-update ---> 保存/修改级联
    delete ---> 删除级联
    all ---> 是所有
   
    unique 是设置当前这个关联类的外键字段的值是唯一的
   
   
方式二;主键 
   <one-to-one name="person"
    class="com.xx.Person"
      cascade="all"
         constrained="true"></one-to-one>

   说明;
        <one-to-one> 是设置当前这个映射类和关联类直接的关系
        name 是设置这个关联类位于当前类的成员变量名
        cascade 是当前类(表)和关联类(表)之间的级联
        save-update ---> 保存/修改级联
        delete ---> 删除级联
        all ---> 所有级联
        class 是这个关联类的类路径
        constrained 是设置主键字段也做为外键,默认是false
       





———————=============———————=======〓〓〓 Hibernate框架查询数据 〓〓〓======——————————=============———————————————————————————————————


Hibernate查询数据;
 为什么要有?
  因为Hibernate框架是用于MVC三层开发模式的dao层,
  而在实际的项目中基本都是对数据进行查找的为多,
  所以Hibernate也为了适应不同的人群提供了···数种···查找方式。
 
 
 是什么?
       是Hibernate框架定义的查找数据库的功能。
       
       
 作用;
      用于查找数据库的数据。
 
 
 特点;
      1.hibernate都提供了对象封装的方法或内部封装
      2.多个数据都是用list()方法
      3.单个数据查找都是用uniqueResult()方法
      4.都是可以使用预定义语句
 
 
 

------------------------------------ Hibernate框架对象查找方式分类 ------------------------------------------------------
 
 
Hibernate查找数据方式分类;
  1.HQL ---> Hiberante Query Langurage 
  是Hibernate框架定义的查找数据库数据的语句,
  是一个不纯粹的面向对象查找。
  会将查找到的数据封装为对应的类的对象。
 
  2.QBC ---> Query By Criteria 标准的查找
  是Hibernate框架定义的查找数据库的语句,
  是一个存储的面向对象查找。
  
  3.原生SQL 
  是使用sql语言对数据库的数据进行查找
 

           区别;
                 
 SQL     HQL           QBC
   
 问题  兼容性     问题不大           使用不直观,较为复杂  --->+
 速度     快                   一般               慢      |
 封装    没有封装 封装为对应映射类   封装复杂      |
 使用    追求处理效率 对速率没要求       不推荐使用,不便于排错 <--+
  类      SQLQuery              Query               Criteria、Restrictions
 
 
◆◆◆◆◆◆注;建议如果是不确定数据库会查出几条数据,
那么则建议尽量list()方法查询。  
 
 
 
 
 
——————————————————————————————————————— Hibernate框架查询Utils —————————————————————————————————————————————  
 

查询Uitls;
 class QueryUtils{
 
  //单个List遍历
  public staitc void ergodicList(List<T> list){
  for(T t : list){
     sysout(t);
  }
  }
 
  //数组List遍历
  public static void ergodicArr(List<Object[]> list){
  for(Obejct[] object :list){
  for(Object o : object){
  sysout(o);
  }
  }
  }
 }



 
 
——————————————————————————————————————— Hibernate框架 —— HQL —————————————————————————————————————————————  
 
 
HQL查询;◆◆◆如果是查询全表的数据则可以省略【select 对象(e)】
单表查询;
全表查询;
 //1.定义查找语句,方式一
  //  A_ Query query = session.createQuery("select e from Employee e");
 
 //方式二
  B_ Query query = session.createQuery("from Employee e");



 //2.使用list()方法获取到所有查询到的数据
  List<Employee> list = query.list();
 
 //3.使用 ↑↑↑ QueryUtils的单个List遍历方法进行遍历
  QueryUtils.ergodicList(list);


 
部分字段;
 //1.定义查找语句;方式一
  Query query = session.createQuery("select e.name,e.salary from Employee e");
 
   
 //2.使用list()方法获取到所有查询到的数据,多个数据不同字段则返回的一个集合数组
  List<Object[]> list = query.list();
 
 //3.使用 ↑↑↑ QueryUtils的数组List方法进行遍历
  QueryUtils.ergodicArr(list);

 //方式二;必须要提供一个查找的属性个数对应的构造器
  Query query = session.createQuery("new Employee(e.name,e.salary) from Employee e");
 
 //使用list()方法获取到所有查询到的数据,多个数据返回一个集合
  List<Employee> list = query.list();
 
 //使用 ↑↑↑ QueryUtils的ergodicList方法进行遍历
  QueryUtils.ergodicList(list);
 
   
   
条件查询;> < <= >= <> = between-and and or like_%  is-not-null is-null

一、查询某一个员工 

 //1.定义查询预定义语句
  Query query = session.createQuery("from Employee where id=?");
 
 //2.给预定义的位赋值
  query.setParameter("2");
 
 //3.因为是确定查询一个数据,因为主键是唯一的,
 // 所以可以使用uniqueResult()方法获取到这个数据
  Employee emp = (Employee)query.uniqueResult();
 
  sysout(emp);


二、查询所有性别为null或为''空字符串的  
 
 //1.定义查询语句
Query query = session.createQuery("select e from Employee e where e.gender<>'' or e.gender is null ");  
 
 //2.因为不确定是会查出几个数据,所以使用list()方法
  List<Employee> list = query.list();
 
 //3.使用↑↑↑ QueryUtils的ergodicList方法进行遍历
  HibernateUtils.ergodicList(list);


三、查询工资在6000 - 8000和名字的包含第二个字包含天的,名字只有三个字

 //1.定义查询语句
  Query query = session.crateQuery("select e from Employee e where e.salary between 6000 and 8000 and e.name like %天_");

 //2.因为不确定查询出几个数据,所以使用list()方法
  List<Employee> list = query.list();
 
 //3.使用↑↑↑ QueryUtils的ergodicList方法进行遍历
  HibernateUtils.ergodicList(list);
 
 
聚合查询;min max count sum 

一、查询所有普通员工的工资总和
 
 //1.定义查询语句
  Query query = session.createQuery("select sum(e.salary) from Employee e");
 
 //2.因为返回的是一个值,所以使用uniqueResult()获取方便,而sum对应的是long类型
  Long salary = (Long)query.uniqueResult();
 
  sysout(salary);


二、查询有多少个普通员工

 //1.定义查询语句
Query query = session.createQuery("select count(e.id) from Employee e");
 
//2.因为返回的是一个值,所以使用uniqueResult()获取方便,而count对应的是int
Integer emp = query.uniqueResult();

sysout(emp);
   
     
分页查询;limit,但是Hql语句封装为对象了,所以使用特定的方法
 
 //1.定义查询语句
 Query query = session.createQuery("select e from Employee e");
 
 //2.使用方法定义分页的值
  query.setFirstResult(0); // 起始行
  query.setMaxResult(5); //查询的行数
 
 //3.使用list()方法获取到查询到的所有数据
  List<Employee> list = query.list()
 
 //4.使用↑↑↑ QueryUtils的ergodicList方法进行遍历
  QueryUtils.ergodicList(list);
 
 
分组查询;group by
 
 //1.定义查询语句
  Query query = session.createQuery("select e.gender,count(e.gender) from Emoloyee e where e.gender<>'' or e.gender is not null group by count(e.gender)");
 
 //2.因为查询的是2个字段,而这个2个字段在对象的类中是没有2个都有的对应的成员变量
  List<Obejct[]> list = query.list();
 
 //3.使用↑↑↑ QueryUtils的ergodicList方法进行遍历使用
  QueryUtils.ergodicList(list);
 
◆◆◆注;查找语句都是使用对象进行查找的,所以要注意大小写。
 
 
 
 
 
多表查询;  
条件;
    1.最少要有两个表的对应的映射类
    2.数据库最少要有两个和映射类对应的表
 ◆ 3.多个表之间必须要有关联关系
   一对多(多对一)
   多对多
   。。。。。。
    ■ 模拟数据,员工和部门
    
内连接查询;查询所有员工对应的部门
   //1.定义查询语句
    Query query = session.createQuery("select e.name,e.depart.departName from Employee e inner join e.depart");
   
   //2.获取到查询的数据
    List<Object[]> list = query.list();
   
   //3.使用↑↑↑ QueryUtils的ergodicArr方法进行遍历集合数组数据
    QueryUtils.ergodicArr(list);
   
   
   
右外连接查询;查询所有部门对应的员工信息
     //1.定义查询语句
      Query query = session.createQuery("select d from Department d right outer join Employee");
     
     //2.获取到查询的数据
      List<Object[]> list = query.list(); 
     
     //3.遍历这个集合数组集合
      for(Object [] object: list){
           for(Object o : object){
            if(o.getClass().getName().equalsIgonoreCase("list")){
            for(object li : o){
            sysout(li);
            }
            }else{
            sysout(o);
            }
           }
      }
     
     
     
左外连接查询;查询所有员工对应的上司
//1.定义查询语句
 Query query = session.createQuery("select e.name,e.depart.princinal from Employee left outer join e.depart");
 
//2.使用list()方法获取所有的查询到的数据
 List<Object[]> list = query.list();

//3.使用↑↑↑ QueryUtils的ergodicList方法进行遍历集合数组数据
 QueryUtils.ergodicList(list);


 
可能出现的错;
     1.注意两个类之间的toString方法,
      不要互相调用,因为可能会出现死循环。
     
     2.注意如果是只是获取一个表的数据,
      那么在获取数据的时候不要toString,
      对应的关联类的数据。


     3.如果出现了Proxy代理类异常,
      那么则重新导入所有的jar包,
      以及删除MyEclipse自带的jar包
     




 
 
————————————————————————————————————— Hibernate框架 —— QBC —————————————————————————————————————————————  
 
 
QBC查询;是纯面向对象的查询语句

单表查询;
单条件查询;
 //1.定义查询语句
  Criteria criteria = session.createCriteria(Employee.class);  
   
   //2.使用Restrictions的抽象方法进行查找,
   // 而这个类的对应方法内部已经是定义了查找语句,
   // 在使用Criteria的add()方法将这个定义好的Restrictions类的方法添加进去
    criteria.add(Restrictions.eq("salary",6000));
   
   //3.根据查询到的数据个数使用对应的方法获取 ---> list()
    List<Employee> list = criteria.list();
   
   //4.使用↑↑↑ QueryUtils的ergodicList方法进行遍历集合数组数据
    QueryUtils.ergodicList(list);



多条件查询;  
   //1.定义查询语句
    Criteria criteria = session.createCriteria(Employee.class);  
     
     //2.使用Restrictions的抽象方法进行查找,
     // 因为是多条件查询并且是and所以使用对应的静态方法
     // 而在这个静态方法内部在添加对应的Restrictions的值
     // 在使用Criteria的add()方法将这个定义好的Restrictions的静态方法添加进去
      criteria.add(Restrictions.and(Restrictions.eq("salary",6000),Restrictions.eq("salary",8000)));
           
     //3.根据查询到的数据使用对应的方法获取 ---> list()
      List<Employee> list = criteria.list();
     
     //4.使用↑↑↑ QueryUtils的ergodicList方法进行遍历集合数组数据
    QueryUtils.ergodicList(list);

 
 
常用的Restrictions的方法;
eq() ---> 等于
gt() ---> 大于
lt() ---> 小于
and() ---> 并且,多条件查询
between() ---> 并且...包括
allEq() ---> 所有相等
isNotNull() ---> 不为空
。。。。。。
 
     



 
 
————————————————————————————————————— Hibernate框架 —— SQL —————————————————————————————————————————————  
 
 
SQL查询;

单表查询;
全表查询;
 //1.定义所有查询的语句
  SQLQuery sql = session.createQuery("select * from employee");  
   
   //2.添加需要进行封装的对象
    sql.addEntity(Employee.class);
   
   //3.使用对应的方法获取到对应的数据
    List<Employee> list = sql.list();
   
   //4.使用↑↑↑ QueryUtils的ergodicList方法进行遍历集合数组数据
    QueryUtils.ergodicList(list);
 
◆◆◆注;其余都是一样的。。。。。。
 




———————=============————————=======〓〓〓 Hibernate框架优化 〓〓〓======——————————=============———————————————————————————————————
 
 
Hibernate优化;
     为什么要有?
      Hibernate是一个纯粹的ORM(对象关系映射)思想的框架,
      而这个框架对代码的封装太复杂了,使得效率的降低,
      于是Hibernate框架使用了很多的方式去优化这个框架。
     
     
     是什么?
         是Hibernate框架自带,或者是第三方提供的插件优化(二级缓存)。
     
         
     作用;
        提高Hibernate的执行效率。
        
     特点;  
  1.都是为了提高Hibernate的执行效率
◆ 2.都是通过减少数据库的访问次数
  
  
  
  
-------------------------------------------- 常用的Hibernate优化功能 ---------------------------------------------------  
 
 
常用的优化功能;
一级缓存
对象状态定义 ---> 类似辅助一级缓存和二级缓存
立即加载VS延迟加载(懒加载) 
二级缓存  
  
  
  
  
  
-------------------------------------------- 一级缓存和二级缓存的区别 ---------------------------------------------------  
 
 
一级和二级区别;
一级缓存;
Hibernate框架的一级缓存也称为Session缓存,
因为数据是存放到Session对象中的。
 
而Session对象一旦销毁,
那么存放到这个对象里的数据也会销毁。
 
所以数据是不可以跨Session的。



二级缓存;
Hibernate框架的二级缓存称为SessionFactory级别的缓存,
因为数据是存储到SessionFactory对象。

而只有SessionFactory销毁,
那么存放在这个对象里的数据才会销毁。  
     
    因为Session是从SessionFactory中获取的,
    所以SessionFactory的数据是可以跨Session的。
     

 
 区别;      
一级缓存 二级缓存
     +---------------+---------------------+---------------------------+
     | 默认      | 开启    |  关闭   |
     | 可关      | 不可以关    | 可以关闭和开启 |
     | 会话      | 不可跨Session    | 可跨Session   |
     | 内部数据      | 可操作 ---> 方法    | 不可操作 ---> 方法   |
     | 查找顺序      |  先    |   后   |
     +---------------+-------------------------------------------------+

 
 
 
————————————————————————————————————— Hibernate框架 —— 一级缓存 ——————————————————————————————————————————————————————————  
 
 
-------------------------------------------- 一级缓存的现象 ------------------------------------------------------
 
 
一级缓存现象;
    class Test(){
    main(){
    //1.通过自定义的HierbanteUilts获取到Session对象
    Session session = HibernateUtils.getSession();
   
    //2.因为Hibernate是一个强事务的框架,所以必须要开启事务
    session.beginTransaction();
   
    //3.操作数据
   
    a_ 获取id为2的员工数据
    Employee emp1 = (Employee) session.get(Employee.calss,2);
   
    b_ 获取到相同id为2的员工数据
    Employee emp2 = (Employee) session.get(Employee.class,2)
       
+----------------> ■■■■■■ 现象;
|         Hibernate框架只是会发送一条SQL语句到数据库,
|         而不会发送两条sql语句到数据库。
|
|
|         c_ 使用Session的方法对存储在Session对象中的缓存数据进行操作 
|        
|         session.flush(); ---> 与数据库的数据进行同步,
|         而这个方法在执行commit()方法的时候就会自动执行
|
| session.evict(); ---> 删除某一个位于缓存的类对象,
|
| session.clear(); ---> 清空所有缓存的数据
|        
|
|    
|     //4.提交事务
|     session.getTransaction.commit();
|    
|     //5.使用自定义的HibernatUtils关闭连接
|     HibernateUtils.closeConnect(session);
|    
|     }
|     
|     }
|  
|
+<-------- ■■■■■■ 解释;因为在每次在操作和数据库相关的数据的时候,
 都会先到Hibernate一级缓存查找 ---->+  
       |
+<--------------------------------------------------------------------+
|  
+-----------> 有;则直接在缓存中返回,则不会和数据库进行任何的交互
|
+-----------> 没;则会先到数据库查找,到了对应的数据则先保存到缓存中(Session),再返回给用户
 
 
操作缓存数据方法用途;
session.flush(); ---> 在rollback后使用

■■ 个人建议;不要在每一次操作数据库数据的时候都使用,
 因为在提交时候的时候就已经执行了flush()方法,  
           并且是在提交事务之前执行这个方法的。

那么再次使用则降低了效率,虽然数据库及时的更新了。  
 
 
  假如;开发人员执行了flush()方法后,
  而在commit()的时候不会在执行flush(),
  也是不建议使用,因为将数据更新到了数据库,
  如果在flush()出现异常那么则会导致数据的破坏,丢失......。
 
 
 
  ◆◆ 建议;在出现异常的时以及rollback后,
  在进行flush(),避免有人恶意的利用漏洞恶意操作。
 
 
  session.evict(); ---> 在出现两个不同的数据方向传入Session缓存中主键一样
 
  例如;在查找数据库数据做判断后,
  再次添加这个相同id的数据。
 
  session.clear(); ---> 确定是一次性使用的Session或者,
  是确定在很长的一段时间中不会再次使用。
 
  例如;登录,用户登录后退出了一段时间,
      后再执行clear()方法,
  是为了避免用户在短时间再次登录,
    从而造成更大的资源开销。
 
 
 
 
 
 
————————————————————————————————————— Hibernate框架 —— 对象状态 ——————————————————————————————————————————————————————————  
 
 
对象状态;
为什么要有?
因为Hibernate框架封装的过于复杂,
那么Hibernate开发者则设计出各种用于提升Hibernate执行效率的办法。

而这些办法的根本就是减少和数据库的交互

而↑↑↑↑↑↑已经有几种减少和数据库的交互的办法,

◆◆◆ 但是怎么标识什么时候应该和数据库不进行交互?


是什么?
是Hibernate框架用于提高执行效率的一个功能(辅助功能)。


作用;
     因为Hiberante是基于ORM思想(对象关系映射),
      所以是面向对象的,而对象状态概念是用于定义需要查找的数据的类对象,
      ◆◆◆◆◆◆位于Hibernate框架中的状态。
 
特点;
     1.都是用于提高Hibernate执行效率
     2.都是在Session开启事务才会符合Hibernate框架定义的状态
     
     
     
------------------------------------- Hibernate框架 —— 对象状态分类 --------------------------------------------------------------      
     
     
对象状态分类;
    临时状态;
         就是在使用Session对象开启事务之后,new 出来的对象都是一个临时状态的。
         
          特点;
              a_ 在数据库中没有对应的记录 ---> 没有使用这个对象和数据库进行过交互
              
              b_ 没有OID ---> 因为Hibernate框架是根据主键进行查找的
              
              c_ 在一级缓存中没有这个对象对应的数据      
    
    
    持久状态;
         就是在使用Session对象开启事务之后,
          使用new 出来的对象对数据库的数据进行操作,
          而操作的时候也是有这个对象对应的数据。
     
     
      特点;
          a_ 在数据库有对应的记录 ---> 因为和数据库进行过交互,
          而交互的时候也有这个数据。
         
          b_ 有OID ---> 因为Hibernate框架是根据主键进行查找的,
          而因为在数据库中有这个数据那么对象才有对应的id。
          
          c_ 在一级缓存中有这个对象对应的数据,看 ↑↑↑↑↑↑ 一级缓存的现象
          
          d_ 操作的对象和数据库的数据是有对应的数据的
          
     
     
      如何进入持久状态;
       load()、get()、upload()、createQuery()。。。。。。
     
     
      ◆◆◆ 只要是和数据库的数据进行交互,
          并且交互之后数据库的数据的主键是没有发生改变的。  
    
    
    游离状态;
         就是在使用Session开启事务之后,
          将这个数据从缓存从删除。
         
          特点;
              a_ 在数据库有对应的记录 ---> 和数据库进行过对应的数据交互,
              并且这个交互是在数据库中有数据库的。
                 
             
              b_ 有OID ---> 因为和数据库进行过数据交互,并且有对应的记录。
             
          
          c_ 在一级缓存中是没有对应的数据 ---> 因为已经从缓存中删除了。
       
       如何进入游离状态;
          evict()、clear()......
       
        ◆注;使用update()、save()......方法可以从游离状态到持久状态
     
     
       
    删除状态; 
             就是在使用Session开启事务之后,
              将这个数据从数据库中删除。
             
              特点;
                  a_ 在数据库中没有对应的记录 ---> 因为和数据库进行过对应的数据交互,
                   但是这个交互是在数据库中删除这个对应的数据。
                 
                  b_ 有OID ---> 因为和数据库进行过交互,并且有对应的记录
                  
                  c_ 在一级缓存中没有对应的记录 ---> 因为在从数据库删除的时候commit()方法,
             就已经进行了同步了(flush)数据库的数据了。
       
 
 
 
 
 
———————————————————————————————————— Hibernate框架 —— 立即加载VS延迟加载 ——————————————————————————————————————————————————————————  


立即VS延迟加载;
为什么要有?
因为可能在获取到了数据库的对应的对象的数据的时候,
可能就不需要立即使用(获取之后下一句代码出现异常)。


是什么?
是Hibernate框架定义的一个用于提高效率的功能。


作用;
    是用于减少与数据库的交互次数的。
    
    
特点;
    1.都是对数据库的数据进行操作
    2.延迟加载默认是在映射文件开启的  

     
     
     
--------------------------------------- 立即加载VS延迟加载 —— 代码实现 --------------------------------------------------------------      
     
     
代码实现;
class Test{
main(){
   //1.使用自定义的HibernateUtils类获取到Session对象
    Session session = HibernateUtils.getSession();
   
   //2.因为Hibernate框架是强事务的框架
    session.beginTransaction();
   
   //3.操作数据 -- 模拟
   
+-----立即加载------->    a_ 立即加载
|     Student stu = (Student)session.get(Student.class,2); ———> 立即加载
|    
+-----延迟加载------->    b_ 延迟加载
|     Student stu = (Student)session.load(Student.class,3); ———> 延迟加载
+------getId()------->     sysout(stu.getId());
+------getName()----->     sysout(stu.getName());
|    
|    
|    //4.提交事务
|     session.getTransaction().commit();
|    
|    //5.使用自定义HibernateUtils类关闭连接
|     HibernateUtils.close(session);
|
| }
| }      
|      
|
|
+--------------->   A_ 立即加载; --->get()
1.会立即执行sql语句,  
查询数据库的数据。  
2.取id执行查询数据库。  
3.数据库找不到返回null。
    4.无法转换成为延迟加载      
     
      B_ 延迟加载; ---> load()
         1.不会立即执行sql语句
         2.取id也不会查询数据库
         3.只有在获取这个对应的对象的其他的成员变量的值,
          的时候才会查询数据库。
          所以如果只用id值对数据进行查找操作建议用load()
         
         4.找不到则返回代理类对象,包含 $$
         5.可以转换为立即加载
         
         
         ◆◆◆注;如果把映射文件的对应的标签的lazy属性设置为false,
          那么延迟加载则会变成立即加载。      
     
   
   
   
     
------------------------------------------- 延迟加载 —— 映射文件 --------------------------------------------------------------      

     
配置文件;
在配置文件中的lazy属性是默认true,
-◆- 而这个lazy表中是在<class>表和配置映射的标签中的lazy也是默认为true。
 
所以在使用对应的表的映射类的时候,
在查找关联表的时候是延迟查找的。
 
因为lazy默认是true



   
       
————————————————————————————————————— Hibernate框架 —— 二级缓存 ——————————————————————————————————————————————————————————  
     
     
二级缓存;
为什么要有?
因为一级缓存无法跨Session,
而且Session那么在对一个数据库的数据进行操作完了之后关闭了这个Session,

那么在后续的相同对这个对象操作的都会重新加载缓存等。。。。。。


是什么?
是Hibernate框架提供的一个接口,用于提高执行的效率.


作用;
     解决Session一级缓存的弊端,
      提高执行的效率。
     
     
特点;
     1.占用内存大 ---> 牺牲效率,提高性能
     2.默认是开启的
     3.需要引用第三方的插件,因为Hibernate框架只是提供了一个接口

◆◆◆注;只要Hibernate官网支持的第三方插件都可以。 
 
 
 
   
   
     
------------------------------------------- 二级缓存 —— 实现代码 --------------------------------------------------------------      
 
 
实现代码;
1.导入第三方插件包 ---> + hibernate-release-4.3.8.Final\lib\required  
 |---> 这个是Hibernate框架的jar包自带的。。。。。。
 
 
2.编写配置文件;
其余的正常编写。

加入;
    <!-- 开启二级缓存,因为默认是关闭的 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    
    <!-- 配置第三方的二级缓存类 --> 
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    
    
    <!-- 
    建议;在一个配置映射文件标签<mapping>之后,
    配置这个二级缓存的有效类.
     -->
     <class-cache usage="read-only" class="com.xx.Student"></class-cache>
 
 
3.模拟二级缓存;
//1.使用自定义HibernateUtils工具类的方法获取到Session对象
Session session = HibernateUtils.getSession();

//2.因为Hibernate框架是一个强事务的框架,所以要开启事务
session.beginTransaction();

//3.模拟数据

Student stu = (Studnet)session.get(Student.class,1);

//清空一级缓存
session.clear();

//再次查找相同的映射类的数据。
// 〓 观察是否有发送查询语句到数据库,
// 如果有发那么则二级缓存没有生效,没有发则二级缓存生效了。

Student stu = (Student)session.get(Student.class,1);      

//4.提交事务
session.getTransaction().commit();

//5.使用自定义的HibernateUtils工具类的方法关闭连接
HibernateUtils.close(session);



   
       
————————————————————————————————————————— 一级缓存和二级缓存的执行过程 ——————————————————————————————————————————————————————————  
     

执行过程;
查找;
    用户 ---> 一级缓存 ---> 二级缓存 ---> 数据库

找不到;则会抛出一个异常,并且不会在缓存中有这个对象的数据。

    
找到;
    数据库 ---> 二级缓存 ---> 一级缓存 ---> 用户


猜你喜欢

转载自blog.csdn.net/su_levi_wei/article/details/78192644
今日推荐