首页 > Web开发 > 详细

Hibernate框架详解

时间:2019-07-21 20:09:11      阅读:102      评论:0      收藏:0      [点我收藏+]

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ 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);

 

 

 

   

       

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

 

     

 

执行过程;

查找;

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

 

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

 

    

找到;

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

Hibernate框架详解

原文:https://www.cnblogs.com/-levi/p/11222339.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!