一、Hibernate的第一个程序
1、导入jar包
2.domain,以及映射文件User.hbm.xml
User.hbm.xml的语法格式:
<-- package类的权限定名 -->
3.核心配置文件hibernate.cfg.xml,放到resource中
数据库连接配置和引入映射文件
org.hibernate.dialect.MySQL5Dialect com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/hibernatedemo root admin thread true true update
Configuration cfg = new Configuration().configure(); SessionFactory factory = cfg.buildSessionFactory(); Session session= factory.openSession(); // 5.打开事务 session.getTransaction().begin(); // 6.DML操作: session.save(u);// 保存操作 session.delete(u); session.update(u); User user = session.get(User.class, id); //清空一级缓存所有对象 //session.clear(); //删除一级缓存指定对象 //session.evict(user); Listlist = session.createQuery("select u from User u ").list(); // 7.提交/回滚事务 session.getTransaction().commit(); // 8.关闭Session session.close();
二、SessionFactory
SessionFactory对象: 1.负责创建Session对象 2.数据库的连接信息是配置SessionFactory; 3.SessionFactory是线程安全的,SessionFactory的创建需要很大的系统开销,实际上,在创建sessionFactory的时候才会去连接数据库,一般的,针对一个应用,一个数据库服务器,只需要一个SessionFactory实例就够了. 4.SessionFactory的重要方法:使用银行转账案例,说明openSession和getCurrentSession 1).openSession:这个方法代表,开启一个全新的Session(测试环境) 1.全新的连接 2.全新的事务 3.全新的一级缓存 2).getCurrentSession:得到当前上下文中的session,绑定到当前线程.(开发环境) 1.如果当前上下文中存在session,则使用该session; 2.如果当前上下文中不存在session,则使用opensession创建一个新的session; 3.要使用getCurrentSessoin,必须在hibernate.cfg.xml中配置thread 4.getCurrentSession得到的session是和事务绑定的(Spring集成Hibernate的方式); 1,无论是DML还是DQL ,都必须开启事务 2,当事务提交的时候,session就跟着关闭了.-->此时不需要人为的调用:session.close()
三、OID(就是对象在数据库中对应的主键的属性)
四、session常用方法(一级缓存 类型+OID)
session.flush();把一级缓存的脏数据同步到数据库中
session.load(对象,OID);查询数据库中对象(延迟加载,发送sql语句只有真正使用这个对象才会发送,就是使用非主键属性时)
load实现原理?使用动态代理,为load的domain动态创建了一个子类,在这个子类中,复写所有非主键调用方法,在这些方法中,去发送.
load原理:
1).Hibernate框架的中的javassist组件创建了代理类以及对象.
2).该对象提供了非主键属性的getter方法和toString方法.
3):该对象存在是否加载完毕的状态,访问属性是先判断对象是否加载完毕,如是直接返回该属性之,否则发送SQL查询该对象.
get方法返回的总是持久化状态的对象;get方法立刻发送一条SELECT语句,结果可以用if - null来判断
load方法并不会立刻发送一条SELECT语句去查询对象,而要到真正在使用(使用一个非主键属性)这个对象的时候,才会去发送SELECT语句,我们把这种方式叫做延迟加载(lazy-load)/懒加载
五、持久化对象的状态
临时状态(没有OID,不在session(即一级缓存)中)
持久化状态(有OID,在session中)
游离状态(有OID,不在session中)
删除状态(就是持久化状态即将从session删掉的状态)
session负责改变状态,事务负责同步数据
在save操作的时候,需要拿到OID(有些主键生成策略是通过发送sql语句拿到OID,有些不用发送SQL语句就可以拿到OID)
脏的持久化对象同步到数据库.(session快照)
1: save方法只需要把对象从临时变成持久化状态,只需要找到OID即可.不同的ID生成策略,
有的必须发生INSERT才能得到ID,有的不需要发生INSERT就可以得到ID,所以此时,不需要发送INSERT语句.
2: 因为delete方法仅仅只是把游离对象或持久化对象变成删除状态,并不负责发生SQL.
3: 持久化对象的属性真正发生改变时,才会发生UPDAE语句.
六、集合映射
1.映射文件配置
2.对象之间的关系(进行关联的时候get方法都是使用延迟加载,所以不会发送sql查找关联的对象,只有使用该对象才会发送sql语句)(先保存没有关联的数据,在保存有外键关联的数据,就不会有脏数据)(维护外键和放弃外键的维护)(单向多对一用的最多)
1)单向多对一(这个外键关联对象)
2)单向一对多
3)双向一对多,多对一
inverse:放弃外键维护
cascade:级联操作
4)双向的多对多
七、hibernate常用的两种查询方式
session.createNativeQuery(sql,返回的对象类型的字节码,如果是数组不用写);
session.createQuery(hql,返回的对象类型的字节码,如果是数组不用写);
八、分页查询
setFirstResult/setMaxResult
九、位置占位符和命名占位符
就是hql中? 变为:变量名(随意起)
十、投影查询
查询持久化类的一个或多个属性
List
十一、封装查询结果
HQ封装:
new list
new map
new EmployeeVO(值对象)
List> list=session.createQuery(hql).list();
List
List
十二、hql中的集合操作(对集合的操作(size属性或size函数获取集合元素数量 ) is empty)
select p from Project p where p.employees.size>0
十三、连接查询
select e.name,d.name from Employee e inner/left join e.dept d;
十四、聚焦函数和子查询
AVG()
MAX()
COUNT()
十五、事务并发访问问题和事务隔离级别
1.事务并发5大问题
第一类丢失更新(一个提交,另一个回滚,提交的也回滚)
脏读(读到未提交的另一个事务的数据)
虚读(读取到已经提交的数据)
不可重复读(读到已经修改的数据)
第二类丢失更新(两个都提交,后一个覆盖前一个)
2.4个隔离级别(3个不能处理第一类丢失更新和第二类丢失更新,通过hibernate的锁机制来处理)
十六、悲观锁、乐观锁
悲观所就是给数据上锁
乐观锁不会上锁,但是在更新的时候会判断
十七、JPA(使用注解或者xml配置文件进行描述对象-关系表的映射关系 加载方式 抓取策略)
1.注解 @Entity
@Table
@id
@GeneratedValue
@Column
@Temporal
@Transients
2.配置文件persistence.xml放在classpath/mata-inf
配置文件中的persistence-unit持久化单元相当于session-factory,name必须要写,用来创建持久化管理对象工厂用
持久化对象管理工厂EntityManagerFactory相当于SessionFactory
持久化管理的对象EntityManager相当于Session
EntityManger方法
1,persist;把对象从临时对象转成持久化对象——save;
2,find;直接查询一个持久化对象——get;
3,merge:把游离对象变成持久化对象——update;
4,getReference;相当于load,延迟加载;加载一个持久化对象——load;
5,createQuery;创建查询对象;
6,createNativeQuery;创建SQL查询对象;
7,remove;把持久化对象/游离对象转化为临时对象——delete;
8,detach;把持久化对象转化成游离对象——evict;
9,close:关闭EntityManager;
3. 放弃维护外键
@ManyToMany(mappedBy="teachers") teachers自己在另一方集合属性名称
4.自定义第三方表
@joinTable(name="",
joinColumns=@joinColumn(name="" ,referencedColumnName=""),
inverseJoinColuns=@joinColumn(name="" ,referemcedColumnName="")
)