■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ 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 是简化在需要创建的类路径,
那么在写的时候则不需要写类的全路径了
-->
<hibernate-mapping
auto-import="false" package="包路径">
1.<class>是定义对应的javaBean类和数据库表的映射
name 是javaBean映射类的类路径
table 是对应的数据库表名
-->
2.<id>是定义这个javaBean类的属性对应的数据表主键字段
column 是定义这个数据库表主键字段名
◆◆◆ 如果主键字段名和javaBean映射类的,
对应属性名同名,则column属性可以不写。
-->
3.<generator>是定义这个主键的值策略
class 是定义策略
1.开发人员
assignd 是开发人员自己添加
◆◆◆注意;如果开发人员忘记给了,
则赋值是0,并且只会赋值一次
2.底层数据库维护
identiry 针对MySQL数据的
squence oracle数据库,因为oracle是序列化的
native 自适应数据库赋值
3.hibernate框架维护
increment 算法是最大值+1
uuid 使用Java_API的UUID类赋值,
而使用这个UUID必须要是String类型
-->
4.<property>是设置其他的表字段和javaBean映射类属性的映射
name 是设置javaBean映射类的属性
column 是设置表的映射字段
type 是设置这个javaBean映射类的属性和这个表的字段映射类型
↓↓↓↓◆↓↓↓↓↓ 具体的类型看↓↓↓↓◆↓↓↓↓↓
↓↓↓↓↓
↓↓↓
↓
length 是设置这个映射属性的值的大小
-->
◆◆◆映射文件小结;
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,文件名
"-//Hibernate/Hibernate ConfigurationDTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
b) 根据dtd配置约束文件编写相应的代码
<!-- 1.定义连接数据库的基本参数-->
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
<!-- 5.设置映射文件位于的类路径-->
◆◆◆◆◆注;一般是要设置某一个文件的路径,那么则是使用( / )
如果是设置某一个类的路径则是( . )
◆◆ 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_ 编写对应的类的映射文件
▲ 编写对应的集合成员变量的表映射
说明;
<set> 是用于配置对应javaBean映射类的Set集合成员变量
name 是这个成员变量位于这个javaBean的成员变量名
<key> 是设置这个副表和主表之间的外键
column 是这个副表的外键字段名,会自动使用主键的
<element> 是设置这个副表存放数据的字段,
因为在集合中是存放数据的,
而集合中的数据中就是存放到数据库的。
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> 是定义这个映射类中的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 = 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> 是定义这个映射类中的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 = 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> orders =
new HashSet(); ---> 为了简化操作时的代码
get()......
set()......
c_ 编写javaBean类映射文件
在orders映射文件中,按照正常映射书写
▲ 在Customers映射文件中,加上
说明;
<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则按照正常规则编写,在编写一个映射
column="c_id"
class="com.xx.Customers"
cascade="all">
说明;
<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
Setorders 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>是设置javaBean类的这个集合数据和副表的映射
name 是这个Set集合成员变量名
cascade 是设置关联表之间的级联
save-update ---> 保存/修改级联
delete ---> 删除级联
all ---> 包含所有
inverse 是设置这个外键的维护权, ---> 默认是false
因为如果是一对多双向的情况下,
建议;最好把外键给副表维护。
因为主表的对应类添加数据的时候,
Hibernate发送第一条的sql语句是,
没有加上外键值的之后会在使用,
update进行修改的,这样降低了效率.
也避免出现不可预知性的错误
<key> 是定义这个Cutomers(主表)位于Orders(副表)的外键
column 是这个外键字段名
<one-to-many> 是设置这个映射的类型,
这个Orders(副表)对应的类路径。
▲ 编写Orders映射类的文件,
其余属性正常规则编写。
column="c_id"
class="com.xx.Customers"
cascade="all">
说明;
<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 = 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> teacher = new HashSet();
---> 节省操作代码
▲ 在Teacher映射类中创建对应的集合成员变量,类型为关联类的类型
Set<Student> student = new HashSet();
---> 节省操作代码
c_ 编写映射类的映射文件
▲ 编写Student映射类的映射文件, ---> Student让出外键维护权
其余的属性按照正常规则编写。
说明;
<set> 是配置中间表(关联表)的数据
name 是这个javaBean映射类对应的表的关联表对应的javaBean类
table 是中间表名,因为多对多映射是使用一个中间表进行关联的
cascade 是设置两个实体表,之间的级联
save-update ---> 保存/修改级联
delete ---> 删除
all ---> 所有
inverse 是设置这个外键维护权的权利,默认是一方维护, ---> false默认
但是在多对多中的类都是多方,那么则必须要设置维护权。
<key> 这个key是当前这个映射类位于中间表
的主外键值
column 当前这个类的主外键的字段名
<many-to-many> 是设置这个当前映射类的关联类(表)
class 是这个关联类的类路径
column 是这个关联类(表)位于中间表的主外键字段
▲ 编写Teacher映射类的映射文件,
其余的属性按照正常规则配置。
说明;
<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映射类的映射文件,
其余属性都是按照正常规则编写。
class="com.xx.IdCard"
cascade="all">
说明;
<one-to-one> 是设置这个类(表)对应的关联类(表)
name 是这个关联类位于当前类的成员变量
class 是这个关联类的类路径
cascade 设置当前类(表)和关联类(表)的级联
save-update ---> 保存/修改级联
delete ---> 删除级联
all ---> 包括所有级联
▲ 编写IdCard映射类的映射文件,
其余属性按照正常规则编写。
方式一;外键 - 特殊的多对一
column="p_id"
class="com.xx.Person"
cascade="all"
unique=true>
说明;
<many-to-one>在一对一中这是一个特殊的多对一配置从而配置为一对一的映射
name 是这个关联类位于当前类的成员变量名
column 是这个关联类位于当前类(表)的外键字段名
class 是这个关联类的类路径
cascade 当前这个映射类(表)与关联类的级联
save-update ---> 保存/修改级联
delete ---> 删除级联
all ---> 是所有
unique 是设置当前这个关联类的外键字段的值是唯一的
方式二;主键
class="com.xx.Person"
cascade="all"
constrained="true">
说明;
<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 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表中是在<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.编写配置文件;
其余的正常编写。
加入;
<!-- 开启二级缓存,因为默认是关闭的-->
true
<!-- 配置第三方的二级缓存类-->
org.hibernate.cache.ehcache.EhCacheRegionFactory
建议;在一个配置映射文件标签<mapping>之后,
配置这个二级缓存的有效类.
-->
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);
————————————————————————————————————————— 一级缓存和二级缓存的执行过程——————————————————————————————————————————————————————————
执行过程;
查找;
用户---> 一级缓存 ---> 二级缓存---> 数据库
找不到;则会抛出一个异常,并且不会在缓存中有这个对象的数据。
找到;
数据库---> 二级缓存 ---> 一级缓存---> 用户