1、hibernate的概述、orm思想、环境的搭建、实现添加操作、配置文件详解、核心API
Hibernate概述
Orm思想:
Session.save(user);
环境的搭建:
- 导入hibernate的jar包:
Hibernate/requied/*.jar;
Jpa/*.jar;
因为在使用hibernate的时候,会有很多日志信息的输出,hibernate本身没有支持日志的jar包,所以导入log4j,slfj,还有mysql的连接工具jar包。
- 创建实体类
- 创建数据库,不需要手动创建表,hibernate会帮助建表。
- 配置实体类和数据表的映射关系。
创建xml格式的配置文件,名称和位置没有要求,一般建议*.hbm.xml;
- 引入约束:dtd,
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> |
- 配置映射关系:
|
- hibernate的核心配置文件:名称和位置固定。Src/hibernate.cfg.xml
引入约束:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> |
Hibernate的操作过程中只会加载核心配置文件,不会加载其他文件。
一:配置数据库的信息
二:配置hibernate的信息
三:把映射文件放到里边
实现添加操作:
- 加载hibernate的核心配置文件
- 创建sessionFactory对象
- 使用sessionFactory创建session
- 开启事务【多个操作,有一个失败,那么都失败】
- 写逻辑curd操作
- 提交事务
- 关闭资源
效果:
- 是否生成表
- 看表是否有记录
配置文件详解:
核心API:
解决配置文件没有提示的问题:
- 能上网都能可以。
- 把文件引入到eclipse中。Window/preference/xml catalog/在配置文件中复制地址,URI
重启后生效。
hibernate的编写规则、主键生成策略、实体类的操作、一二级缓存、事务操作、绑定session单线程对象
实体类的编写规则
- 实体类的属性是私有的
- 实行对应的getset方法是public的
- 要求实体类有属性值作为唯一表示id值int类型
- 实体类的属性建议为基础类型的包装类;原因:我想要表示学生的分数,int类型,学生得了0分,如果说学生没有参加考试,不能写null,所以使用包装类。
Hibernate的主键生成策略
Int类型不能存uuid,自动获取,可以是字符串类型,让uid自动增长
Hibernate中要求实体类中有个属性作为唯一值,对应表的主键,主键可以不同生成策略。
Hibernate的主键生成策略可以有很多值:
<generator class=”native”/>:根据使用的数据库选择哪个值。
<generator class=”uuid”/>:自动生成UUID的字符串的值。
- web阶段手写代码生成uuid的值。
- 使用uuid,实体类的类型必须是String类型。
实体类的操作
Curd操作
添加操作:若果设置的id与数据库相同,由于id是自动增长的类型,所以数据的id自动增长,不产生冲突,与不设置id一样
根据id查询:session的get方法实现
public class TestDemo { @Test public void testGet() { SessionFactory sessionFactory = GetSessionFactory.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user = session.get(User.class, 1); System.out.println(user); tx.commit(); session.close(); sessionFactory.close(); } } |
修改操作:先查询后修改
public void testUpdate() { SessionFactory sessionFactory = GetSessionFactory.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user2 = session.get(User.class, 2); user2.setUsername("update");//saveorupdate() session.update(user2); System.out.println(user2); tx.commit(); session.close(); sessionFactory.close(); }
|
结果吧所有的值都给改了,因为只设置了username值,所以其他值为null |
删除操作:
public void testDelete() { SessionFactory sessionFactory = GetSessionFactory.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); //delete里边的参数是对象 //session.delete(session.get(User.class, 1));
User user = new User(); user.setUid(2); session.delete(user); tx.commit(); session.close(); sessionFactory.close(); } |
实体类对象状态
- 瞬时态:对象里边没有id值,对象与session没有关联
在调用sesison之前。
- 持久态:对象里边有id值,与session有关联
- 托管态:对象里边有id值,与sesssion没有关联。
Saveorupdate方法
既能实现添加又能实现修改:
实体类是瞬时态的时候,是做添加操作。 实体类是托管态的时候,是做修改操作。 实体类是持久态的时候,是做修改操作。 |
Hibernate的一级缓存
什么是缓存:
数据存放在数据库中,数据库本身是文件系统,使用流方式操作文件的效率并不是很高。
把数据存放到内存中,不用流的方式可以直接读取内存中的数据,提高了读取效率。
特点:
一级缓存:
- 默认就是打开的
- 有使用的范围:是session的范围。创建session到关闭
- 在Hibernate的一级缓存中,必须是持久态的数据。
验证一级缓存的存在:
- 首先根据uid=1进行查询,返回的是对象的方式;
- 再次进行,看是否查看数据库。
一级缓存的执行过程:
第二次查询根据第一次存入缓存的uid进行查询。
一级缓存的特性:持久态对象了,已经session了,不用session.saveorupdate()了,自动更新到数据库。
执行的过程:
二级缓存:
目前已经不使用了,使用了redis技术替代。
- 默认不是打开的,需要配置使用
- 二级缓存的使用范围是整个web,即sessionFactory范围。
Hibernate的事务操作
事务代码编写规则写法【回滚】
事务的相关概念:事务是操作中最基本的单元,要么全成功,要么全失败。‘
特性:
- 一致性
- 隔离性
- 持久性
- 原子性
不考虑隔离性产生的问题:
- 脏读
- 不可重复读
- 虚读
设置事务的隔离级别:mysql默认的隔离级别是repeatable read
代码结构
@Test public void testTransaction() { SessionFactory sessionFactory = null; Session session = null; Transaction tx = null; try { sessionFactory = GetSessionFactory.getSessionFactory(); session = sessionFactory.openSession(); //开启事务 tx = session.beginTransaction();
//添加: User user = new User(); user.setUsername("pshdhx"); user.setPassword("pshdhx"); user.setAddress("zb"); session.save(user); int i=10/0; tx.commit(); }catch(Exception e) { e.printStackTrace(); tx.rollback(); }finally { session.close(); sessionFactory.close(); } } |
Hibernate绑定session的单线程对象:
线程结束,session自动关闭 |
Hibernate的其他api:
Query对象:
- 使用query对象,不需要使用sql语句,使用hql语句,Hibernate+query+language
跟sql语句的区别:使用普通sql操作的是数据库的表和字段,hql操作的是实体类和属性。
查询所有的hql语句:
- from 实体类名称
query对象的使用:
- 创建query对象
- 调用query对象里边的方法得到结果
Criteria对象:
Criteria criteria = session. List<User> users = criteria.list(); for(User user:users) { System.out.println(user); } |
SQLQuery对象:
数组转为字符串输出 arrays.toString(); |
表的关系-一对多、多对多、级联保存修改和删除
- 列表功能实现
- 表与表之间关系回顾
一对多
- 分类和商品
- 客户-联系人
客户:与公司有业务往来的公司
联系人:在公司里边的员工
公司和员工的关系
一对多建表:通过外键建立表之间的关系
多对多
- 订单和商品
一对一
1、夫妻制
3、Hibernate一对多操作:
Set无序,且有重复元素。
引入核心配置文件
一对多级联操作:
一对多的级联保存
1、
2、
一对多的级联删除
过程:根据id查询客户,根据外键的id值查询联系人,把联系人的外键设为null,删除联系人,删除客户。
一对多修改操作:
持久态自动更新数据库。
为什么改了两次:外键?双向维护外键,可以让其中的一方不维护外键,让一的哪一方放弃外键。
性能更好
- Hibernate多对多操作:
hibernate的查询方式、对象导航查询、OID查询、HQL查询、QBC查询、多表查询、本地sql查询、hibernate的检索策略
Hibernate的查询方式
对象导航查询
遍历的话有两种,增强for和迭代器
OID查询
Hql查询
查询所有
条件查询
排序查询
分页查询
投影查询
聚集函数的使用
Qbc查询
查询所有
条件查询:
排序查询:
分页查询:
统计查询:
离线查询:
离线跟session没有关系
多表查询:
左边表中的所有数据,右边表中的关联数据。
内连接:
本地sql查询
Hibernate的检索策略:
值越大,执行的sql语句越少,性能越高。