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

"-//Hibernate/HibernateMapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


  b) 根据dtd映射约束文件编写相应的代码


auto-import 默认是true,

如果在项目中出现同名的类,

那么则需要设置为false。

     ◆那么则在代码中使用这个映射类的时候,

      需要使用类的全路径。


package 是简化在需要创建的类路径,

那么在写的时候则不需要写类的全路径了


-->

auto-import="false" package="包路径">




   1.是定义对应的javaBean类和数据库表的映射


name 是javaBean映射类的类路径

table 是对应的数据库表名

-->




   2.是定义这个javaBean类的属性对应的数据表主键字段


   column 是定义这个数据库表主键字段名


    ◆◆◆ 如果主键字段名和javaBean映射类的,

      对应属性名同名,则column属性可以不写。

-->


   3.是定义这个主键的值策略


class 是定义策略


1.开发人员

assignd 是开发人员自己添加


◆◆◆注意;如果开发人员忘记给了,

则赋值是0,并且只会赋值一次


2.底层数据库维护

identiry 针对MySQL数据的

squence oracle数据库,因为oracle是序列化的

native 自适应数据库赋值


3.hibernate框架维护


increment 算法是最大值+1

uuid 使用Java_API的UUID类赋值,

而使用这个UUID必须要是String类型

-->



  4.是设置其他的表字段和javaBean映射类属性的映射

    name 是设置javaBean映射类的属性

    column 是设置表的映射字段

    type 是设置这个javaBean映射类的属性和这个表的字段映射类型

    ↓↓↓↓◆↓↓↓↓↓ 具体的类型看↓↓↓↓◆↓↓↓↓↓

↓↓↓↓↓

↓↓↓

    length 是设置这个映射属性的值的大小

-->






  ◆◆◆映射文件小结;

    1.如果name的值和column的值相同则column可以省略不写


    2.在使用组件策略的时候是使用数据库或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,文件名


"-//Hibernate/Hibernate ConfigurationDTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">


 b) 根据dtd配置约束文件编写相应的代码

 

com.mysql.jdbc.Driver

jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8

xxx

xxx


  2.设置要连接的数据库方言

  这个方言类位于在Hibernate核心jar包下的org.hibernate包下,

  因为Hibernate是一个强事务的框架所以必须要找支持事务的对应数据库类。

     方言;是因为不同数据库对数据库的操作语句不同等等......

-->

org.hibernate.dialect.MySQL5InnoDBDialect


     3.hibernate.show_sql 是在使用hibernate框架是,

对数据库的数据进行操作的时候,

  显示对应的操作sql语句。


-->


     4.hibernate.format_sql

是因为显示的sql语句太多了,太乱,不容易查看,

所以将hibernate对数据库的数据进行操作的时候,

显示的sql语句全部都是格式化的。


-->


     5.hibernate.hbm2ddl.auto


是设置使用hibernate框架对数据库的数据进行操作的时候,

如果没有表则自动创建标签。

update  ---> 是设置如果没有表则创建,

并且只会创建一次,如果有了表则直接对这个表进行维护

  create ---> 是使用每一次对数据库的数据进行操作的时候,

  旧表都会删除,重新创建一张新的表。

-->

update

 



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

如果是设置某一个类的路径则是( . )






   ◆◆ E.编写对应的类连接数据库,并且对数据库的数据进行操作

    //1.调用Configuration的方法读取src下的hibernate.cfg.xml文件

Configuration config = newConfiguration().configure();

    //另;在3.0之前是直接使用Configuration的方法创建SessionFacotry对象

//

SessionFactory before =config.buildSessionFactory();

    //2.创建服务注册器对象,这个是在3.0之后推出的 ---> 速度可能快一点

ServiceRegistry registry =newStandardServiceRegistryBuilder().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 =newStandardServiceResgitryBuild().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 = newConfiguration().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 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 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 = newConfiguration().configure();

|

| //2.创建服务注册器对象,注册服务器连接

| //传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

| ServiceRegistry registry = newStandardServiceRegisryBuilder().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 = newConfiguration().configure();

|

| //2.创建服务注册器对象

| //传入config.getProperties()方法的数据,

| //使用hibernate.cfg.xml文件配置的连接数据库的参数

| ServiceRegistry registry = newStandardServiceRehgistryBuilder().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 = newConfiguration().configure();

    //2.创建ServiceRegistry对象

    //传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

ServiceRegistry registry =newStandardServiceResgiryBuilder().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 address;


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


c_ 编写hibernate.cfg.xml文件

d_ 编写对应的类的映射文件


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




说明;

    是用于配置对应javaBean映射类的Set集合成员变量

    name 是这个成员变量位于这个javaBean的成员变量名

    是设置这个副表和主表之间的外键

    column 是这个副表的外键字段名,会自动使用主键的


是设置这个副表存放数据的字段,

因为在集合中是存放数据的,

而集合中的数据中就是存放到数据库的。


type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,

映射文件的type属性。

column 是可以设置这个集合的数据存放的字段


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




e_ 在操作类中编写代码 


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

Configuration config = newConfiguration().config();


//2.创建注册服务器对象

//传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

ServiceRegistry registry = newStandardServiceRegistry().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 address;


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


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


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




说明;

    是定义这个映射类中的List集合的属性的数据映射

    name 是这个List集合在映射类中的成员变量名

是设置当前这个类位于这个集合对应的数据库表(副表)的外键


column 是这个外键的字段名


因为List集合是一个有序的,

而如果是使用主键(id)可能出现不符合有序(小到大)特点


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


column 是这个序号的值字段名


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


type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,

映射文件的type属性。

column 是指定这个字段的值


d_ 编写hibernate配置文件


e_ 编写操作数据的代码


//1.创建Configuration对象读取src下的hibernate.cfg.xml

Configuration config = newConfiguration().configure();


//2.创建注册服务器对象,

//传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

ServiceRegistry registry = newStandardServiceRegistry().applySettings(config.getProperties()).build();


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

SessionFactory factory =config.buildSessionFactory();



//4.通过会话工厂对象创建具体的会话

Session session = factory.buildSession();


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

session.beginTransaction();


//6.操作数据


List 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 cargo;

|

 |  c_ 编写javaBean类的映射文件

|


|

▲ 编写javaBean映射类的Map成员变量的映射

|


|

|

|

|

|

|


|

说明;

|

    是定义这个映射类中的Map类型的成员变量的

|

    name 是这个成员变量位于这个映射类中的成员变量名

|

|

    是当前这个映射类位于这个Map副表的外键,自动使用主表的主键值

|

    column 是这个外键的字段名

|

|

    因为map的key的是用于唯一标识当前这个类的Map属性的key

+---------------------------------------->

  如果在存储的时候,Map集合的数据出现key重复则使用后定义的。

type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,

映射文件的type属性。

column 是指定这个字段的名字


是这个Map集合的value对应的字段


type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现,

映射文件的type属性。

column 是指定这个字段的名字


 d_ 编写hibernate配置文件


 e_ 编写操作数据代码

  //1.创建Configuration对象读取src下的hibernate.cfg.xml

Configuration config = newConfiguration().configure();


//2.创建注册服务器对象,

//传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

ServiceRegistry registry = newStandardServiceRegistry().applySettings(config.getProperties()).build();


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

SessionFactory factory =config.buildSessionFactory();



//4.通过会话工厂对象创建具体的会话

Session session = factory.buildSession();


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

session.beginTransaction();


//6.操作数据


Map map = newHashMap();

map.add("上海体育路");


Student student = new Student();

student.setList(map);


session.save(student);


//7.提交事务

session.getTransaction().commit();


//关闭连接

session.close();

factory.close();



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



自定义工具类;

    因为Hibernate框架定义的对数据进行操作的代码太多是冗余了,所以可以考虑抽象为一个工具类

class HibernateUtils{

private staticSessionFafactory factory = null;

    //获取具体的会话对象

public static SessiongetSession(){

    //1.创建Configuration对象读取src下的hibernate.cfg.xml

Configuration config = newConfiguration().configure();


//2.创建注册服务器对象,

//传入config.getProperties()方法的数据,

//使用hibernate.cfg.xml文件配置的连接数据库的参数

ServiceRegistry registry = newStandardServiceRegistry().applySettings(config.getProperties()).build();


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

SessionFactory factory =config.buildSessionFactory();



//4.通过会话工厂对象创建具体的会话

Session session = factory.buildSession();

    //5.返回具体的会话对象

return session;

}

    //关闭连接

public static voidcloseConnect(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

  ▲ 在Customers类中先定义一个集合,

  类型为Orders的成员变量,

  提供get()和set()方法。

  private Set orders =

new HashSet();  ---> 为了简化操作时的代码

get()......

set()......

  c_ 编写javaBean类映射文件

  在orders映射文件中,按照正常映射书写

  ▲ 在Customers映射文件中,加上

  说明;

      是设置成员变量中的Set集合的数据

name 是这个set集合位于Customers(一方)类中的成员变量名

cascade 是设置这两个关联的表的级联

save-update ---> 添加和修改的级联

delete ---> 删除级联

all ---> 包含上面所有


+<----- inverse 是设置这个外键的维护权反转给别的表

|   false ---> 默认

|   true ---> 交给别的类维护外键值

|

| 这个是为了提高效率的。

|

|--------> 如;在做添加的时候,

hibernate的insert

into .....语句中的外键是没有值,

而后面在使用update语句给这个外键赋值的。


◆◆◆◆◆注;默认的维护权在一方


是设置当前这个Customers类位于的Orders(多方表)的外键字段

column 是外键字段名


是指定这个外键位于的表对应的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则按照正常规则编写,在编写一个映射

column="c_id"

class="com.xx.Customers"

cascade="all">

  说明;

      是设置这个副表和主键直接的关系

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

Setorders Customers customer

     ▲ 在Costomer类中创建对应的Orders类类型的集合(Set)的成员变量,

并且提供对应的get()和set()方法。

private Set orders = new

HashSet();  ---> 为了节约代码

get()......

set()......

 ▲ 在Orders类中创建对应的Customers类的成员变量,

  并且提供对应的get()和set()方法。

private Customers customer;

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


▲ 编写Customers映射类的映射文件,

其余的属性正常编写。

  说明;

      是设置javaBean类的这个集合数据和副表的映射

name 是这个Set集合成员变量名

cascade 是设置关联表之间的级联

save-update ---> 保存/修改级联

delete ---> 删除级联

all ---> 包含所有

  inverse 是设置这个外键的维护权, ---> 默认是false

  因为如果是一对多双向的情况下,

  建议;最好把外键给副表维护。

  因为主表的对应类添加数据的时候,

  Hibernate发送第一条的sql语句是,

  没有加上外键值的之后会在使用,

  update进行修改的,这样降低了效率.


也避免出现不可预知性的错误


是定义这个Cutomers(主表)位于Orders(副表)的外键

column 是这个外键字段名


是设置这个映射的类型,

这个Orders(副表)对应的类路径。




▲ 编写Orders映射类的文件,

其余属性正常规则编写。


column="c_id"

class="com.xx.Customers"

cascade="all">


说明;

    是设置映射类(表)和关联表的关联

    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 = newCustomers();

    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

Set student


▲ 在Student映射类中创建对应的集合成员变量,类型为关联类的类型

Set teacher = new HashSet();

---> 节省操作代码


▲ 在Teacher映射类中创建对应的集合成员变量,类型为关联类的类型

Set student = new HashSet();

---> 节省操作代码

          c_ 编写映射类的映射文件



▲ 编写Student映射类的映射文件,  ---> Student让出外键维护权

其余的属性按照正常规则编写。



说明;

    是配置中间表(关联表)的数据

    name 是这个javaBean映射类对应的表的关联表对应的javaBean类


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


cascade 是设置两个实体表,之间的级联

save-update ---> 保存/修改级联

delete ---> 删除

all ---> 所有


inverse 是设置这个外键维护权的权利,默认是一方维护, ---> false默认

但是在多对多中的类都是多方,那么则必须要设置维护权。


这个key是当前这个映射类位于中间表

的主外键值

column 当前这个类的主外键的字段名


是设置这个当前映射类的关联类(表)

class 是这个关联类的类路径

column 是这个关联类(表)位于中间表的主外键字段



▲ 编写Teacher映射类的映射文件,

其余的属性按照正常规则配置。




说明;

    是设置这个类(表)的关联映射类(表)

    name 是这个关联类位于当前类的成员变量的变量名

    table 这个中间表的表名,因为多对多映射是依靠中间表进行管理

    cascade 是当前这个映射类对应的表和关联表的级联

    save-update ---> 保存/修改级联

    delete ---> 删除级联

    all ---> 包括所有

    ◆◆注;因为Student映射类以及反转出主外键的控制权了

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

    column 是当前的映射类主外键字段名

    是设置这个关联类的映射

    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映射类的映射文件,

  其余属性都是按照正常规则编写。

class="com.xx.IdCard"

cascade="all">

  说明;

      是设置这个类(表)对应的关联类(表)

name 是这个关联类位于当前类的成员变量


class 是这个关联类的类路径


cascade 设置当前类(表)和关联类(表)的级联

save-update ---> 保存/修改级联

delete ---> 删除级联

all ---> 包括所有级联

  ▲ 编写IdCard映射类的映射文件,

  其余属性按照正常规则编写。

  方式一;外键 - 特殊的多对一

column="p_id"

class="com.xx.Person"

cascade="all"

unique=true>


   说明;

    在一对一中这是一个特殊的多对一配置从而配置为一对一的映射

    name 是这个关联类位于当前类的成员变量名

    column 是这个关联类位于当前类(表)的外键字段名

    class 是这个关联类的类路径

    cascade 当前这个映射类(表)与关联类的级联

    save-update ---> 保存/修改级联

    delete ---> 删除级联

    all ---> 是所有

    unique 是设置当前这个关联类的外键字段的值是唯一的


方式二;主键

class="com.xx.Person"

cascade="all"

constrained="true">


   说明;


是设置当前这个映射类和关联类直接的关系

        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 QueryLangurage

  是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 voidergodicList(List list){

for(T t : list){

sysout(t);

}

}

  //数组List遍历

public static voidergodicArr(List 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("fromEmployee e");




 //2.使用list()方法获取到所有查询到的数据

List list = query.list();

 //3.使用 ↑↑↑

QueryUtils的单个List遍历方法进行遍历

QueryUtils.ergodicList(list);



部分字段;

 //1.定义查找语句;方式一

Query query = session.createQuery("selecte.name,e.salary from Employee e");

 //2.使用list()方法获取到所有查询到的数据,多个数据不同字段则返回的一个集合数组

List list = query.list();


 //3.使用 ↑↑↑

QueryUtils的数组List方法进行遍历

QueryUtils.ergodicArr(list);


 //方式二;必须要提供一个查找的属性个数对应的构造器

Query query = session.createQuery("newEmployee(e.name,e.salary) from Employee e");

 //使用list()方法获取到所有查询到的数据,多个数据返回一个集合

List 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("selecte from Employee e where e.gender<>'' or e.gender is null ");

 //2.因为不确定是会查出几个数据,所以使用list()方法

List 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 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 list = query.list()

 //4.使用↑↑↑

QueryUtils的ergodicList方法进行遍历

QueryUtils.ergodicList(list);

分组查询;group by

 //1.定义查询语句

Query query = session.createQuery("selecte.gender,count(e.gender) from Emoloyee e where e.gender<>'' or e.genderis not null group by count(e.gender)");

 //2.因为查询的是2个字段,而这个2个字段在对象的类中是没有2个都有的对应的成员变量

List 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 einner join e.depart");

   //2.获取到查询的数据

List list = query.list();

   //3.使用↑↑↑

QueryUtils的ergodicArr方法进行遍历集合数组数据

QueryUtils.ergodicArr(list);

右外连接查询;查询所有部门对应的员工信息

     //1.定义查询语句

Query query =session.createQuery("select d from Department d right outer joinEmployee");

     //2.获取到查询的数据

List 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 leftouter join e.depart");

//2.使用list()方法获取所有的查询到的数据

List 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 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 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 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表中是在表和配置映射的标签中的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.编写配置文件;

其余的正常编写。


加入;

   

true

   

org.hibernate.cache.ehcache.EhCacheRegionFactory


    建议;在一个配置映射文件标签之后,

    配置这个二级缓存的有效类.

-->

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框架详解)