■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ 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. name 是javaBean映射类的类路径 table 是对应的数据库表名 --> 2. 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. name 是设置javaBean映射类的属性 column 是设置表的映射字段 type 是设置这个javaBean映射类的属性和这个表的字段映射类型 ↓↓↓↓◆↓↓↓↓↓ 具体的类型看↓↓↓↓◆↓↓↓↓↓ ↓↓↓↓↓ ↓↓↓ ↓ length 是设置这个映射属性的值的大小 --> ◆◆◆映射文件小结; 1.如果name的值和column的值相同则column可以省略不写 2.在使用 那么则开发人员赋值可能无效,只会使用底层自动生成的值 ◆◆ 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_ 编写对应的类的映射文件 ▲ 编写对应的集合成员变量的表映射 说明; 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集合成员变量的映射 说明; name 是这个List集合在映射类中的成员变量名 column 是这个外键的字段名 而如果是使用主键(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成员变量的映射 | | | | | | | | 说明; | | name 是这个成员变量位于这个映射类中的成员变量名 | | | column 是这个外键的字段名 | | +----------------------------------------> 如果在存储的时候,Map集合的数据出现key重复则使用后定义的。 type 可以查看↑↑↑↑↑↑↑↑Hibernate框架基本开发实现, 映射文件的type属性。 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.操作数据 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 new HashSet(); ---> 为了简化操作时的代码 get()...... set()...... c_ 编写javaBean类映射文件 在orders映射文件中,按照正常映射书写 ▲ 在Customers映射文件中,加上 说明; name 是这个set集合位于Customers(一方)类中的成员变量名 cascade 是设置这两个关联的表的级联 save-update ---> 添加和修改的级联 delete ---> 删除级联 all ---> 包含上面所有 +<----- inverse 是设置这个外键的维护权反转给别的表 | false ---> 默认 | true ---> 交给别的类维护外键值 | | 这个是为了提高效率的。 | |--------> 如;在做添加的时候, hibernate的insert into .....语句中的外键是没有值, 而后面在使用update语句给这个外键赋值的。 ◆◆◆◆◆注;默认的维护权在一方 column 是外键字段名 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 HashSet(); ---> 为了节约代码 get()...... set()...... ▲ 在Orders类中创建对应的Customers类的成员变量, 并且提供对应的get()和set()方法。 private Customers customer; c_ 编写对应的javaBean映射类的映射文件 ▲ 编写Customers映射类的映射文件, 其余的属性正常编写。 说明; name 是这个Set集合成员变量名 cascade 是设置关联表之间的级联 save-update ---> 保存/修改级联 delete ---> 删除级联 all ---> 包含所有 inverse 是设置这个外键的维护权, ---> 默认是false 因为如果是一对多双向的情况下, 建议;最好把外键给副表维护。 因为主表的对应类添加数据的时候, Hibernate发送第一条的sql语句是, 没有加上外键值的之后会在使用, update进行修改的,这样降低了效率. 也避免出现不可预知性的错误 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映射类中创建对应的集合成员变量,类型为关联类的类型 Set ---> 节省操作代码 c_ 编写映射类的映射文件 ▲ 编写Student映射类的映射文件, ---> Student让出外键维护权 其余的属性按照正常规则编写。 说明; name 是这个javaBean映射类对应的表的关联表对应的javaBean类 table 是中间表名,因为多对多映射是使用一个中间表进行关联的 cascade 是设置两个实体表,之间的级联 save-update ---> 保存/修改级联 delete ---> 删除 all ---> 所有 inverse 是设置这个外键维护权的权利,默认是一方维护, ---> false默认 但是在多对多中的类都是多方,那么则必须要设置维护权。 的主外键值 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 ————————————————————————————————————— 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); ————————————————————————————————————————— 一级缓存和二级缓存的执行过程—————————————————————————————————————————————————————————— 执行过程; 查找; 用户---> 一级缓存 ---> 二级缓存---> 数据库 找不到;则会抛出一个异常,并且不会在缓存中有这个对象的数据。 找到; 数据库---> 二级缓存 ---> 一级缓存---> 用户 是定义这个映射类中的List集合的属性的数据映射