Hibernate概括小结
1.主配置文件Xxxx.cfg.xml
2.映射文件:Xxx.hbm.xml
3.映射源文件(持久类):
Xxx.java (一般一个数据库表对应一个源文件类)
需遵循四原则:1.为属性设置getter,setter方法,
2.实现一个默认的无参构造方法,以便Constructor.newInstance()实例化;
3.提供一个属性标识,该属性映射数据库和表的主键字段(id),
4.使用非final的类
4.编写辅助类session
5.封装获取session方法,hibernate进行增删改查
6.7种主键生成策略
主键类型
1.自然主键
有业务逻辑的字段,必有唯一不重复的字段
2.代理主键(常用)
不具备业务逻辑的字段,但是必须要有而且唯一不重复的字段
7种策略:
1.identity
自增的类型的主键,数据库本身提供的生成标识
2.increment
自增的类型的主键,执行过程:先查询出最大主键值,然后加1,作为主键值
3.sequence
自增的类型的主键,(oracle序列,用于支持序列的数据库)
4.hilo
自增的类型的主键,通过高低位的算法实现
5.native(最常用)
自增的类型的主键,hilo+identity+sequence 的结合,优点,跨平台性,根据数据库选择主键策略
6.uuid
String 类型 32位的16进制字符串
7.assigned
开发人员自己来维护主键
7.对象状态:
1.瞬时状态:
手动new出来的对象,没有id,没有保存到session中;
*
2.持久状态:
有id,有保存到session中,没有保存到数据库中
3.托管(游离)状态 session.close();
将session中的对象保存到数据库中
有id,没有保存到session中
8.缓存和快照:
-
一级缓存
Hibernate提供了两级缓存,第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
-
二级缓存
第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。
- 快照
当程序调用get()方法时,Session会先在缓存区找有没有存在对应的对象,如果是第一次调用,这时缓存区是空的,自然就找不到,那么Session就会发送select语句向数据库查找,数据库找到后将结果返回给Session,这时Session会对 数据进行组装成实体对象,并且一式两份,即一份在缓存中,一份是快照,然后Session会将缓存中的那一份返回给程序; 如果这时进行更新操作,那么在Session中会进行对比缓存中的对象与快照中的对象,如果对象的属性发生了变化,那么就 会发送update语句对数据库进行更新,如果对象的属性没有变化,则不发送update语句。
总结,快照是数据库的数据在Session中的代表,也就是说,数据库中的数据一旦发生变化,快照就会随之改变。个人觉得这样设计能减少对数据库的访问,提高数据库的效率。
9.crud操作:增删改查
hibernate对sql语句进行了封装,大大简化了程序员编写sql语句的时间,同样,失去了灵活性,对一些复杂sql语句的执行不太友好。
10.事务:
事务:
-
对jdbc的轻量级封装,多条语句执行时,一起成功一起失败;
-
特性:
- 原子性:
- 一致性:两条SQL语句同时执行,结果需要一致
- 隔离性:事务的操作执行的时候,每个事务之间不能互相干扰;(百度一下)
- 持久性:数据库中的改变都是永久状态
事务并发:
- 1.脏读:
- 一个事务读取到另外一个事务未提交的数据
- 2.不可重复:
- 一个事务读到另外一个事务提交的数据(update),导致同一个事务中多次查询的结 果不一致
- 3.幻读:
- 一个事务读到另外一个事务已经提交的数据(insert),导致在同一个事务中查询的结 果不一致
事务隔离级别:
- 1.读未提交(.脏读,不可重复,幻读)
- 2.读已提交的(不可重复,幻读)
- 3.读可重复读(幻读)
- 4.串行化
11.hibernate查询
1.Hql查询:
特点:
* hibernate独家所有
* 面向对象的查询(HQL语句查询不能出现数据库表中的字段)
* 一般用于不复杂的多表查询使用
2.基本查询
//1.编写Hql语句
//如果直接写实体类的名称,那么这实体类必须在这个web工程中是唯一的,不可重复
String hql="from User";
String hql2="from User where id=1l";
//如果其他包中有User类,则必须用如下方式
//String sql="from com.lilinyang.pojo.User";
Query query=session.createQuery(hql);
Query query2=session.createQuery(hql2);
//获取集合的结果集
List<User> list=query.list();
//获取单个的结果集
User u=(User) query2.uniqueResult();
3.条件查询
//查询语句
String hql3="from User where id=?";
占位符可用 ?
session.createQuery.setLong(0, 1l);// 等同于createQuery.setParameter(0, 1l);,不用去找 传的参数类型
也可用别名 :别名
//条件赋值
createQuery.setParameter("别名", 1l);
4.分页查询
//设置查询开始的位置及显示条数
createQuery3.setFirstResult(0);
createQuery3.setMaxResults(2);
5.criteria查询
特点:
无语句的面向对象查询,不需要SQL hql语句,调用方法查询
/*
- 查询所有
*/
Criteria createCriteria = session.createCriteria(User.class);
List<User> list=createCriteria.list();
/*
- 条件查询
- > ---gt
>
> - > =------ge
>
> - < ---lt
>
> - <= ---le
>
> - == --eq
>
> - != ---ne
>
> - in ---in
>
> - between and ---between
- like -----like
- is not null isNotNull
- is null --isNull
- or or
- and and
*/
Criteria createCriteria2 = session.createCriteria(User.class);
//设置条件
createCriteria2.add(Restrictions.eq("id","1l"));
/*
- 分页查询
*/
Criteria createCriteria3 = session.createCriteria(User.class);
//设置每页条数
createCriteria3.setFirstResult(0);
createCriteria3.setMaxResults(2);
/*
- 获取查询到的条数
*/
Criteria createCriteria4 = session.createCriteria(User.class);
//获取查询到的结果条数
createCriteria4.setProjection(Projections.rowCount());
long uniqueResult = (long) createCriteria4.uniqueResult();
6.原生sql查询:用在比较复杂的业务
12.hibernate 对象关系映射
(参考了Hibernate的七种映射关系之七种关联映射(一)
-
一对一:
通常使用多对一的方式进行配置,因为一对一的扩展性不够好,
多对一关联映射是在多的一端来维护关联字段,实体类中要有相应的one端的属性引用
<many-to-one name="one端的引用" column="groupid" cascade="save-update" unique="true"/>
unique=“true”:限制many端的唯一性,实现one to one。
-
一对多:
一对多关联映射通常在多的一端维护关系,让一的一端失效,用到inverse=“true”,
例如:教室对学生,在教师端创建学生类集合students
教室.hbm.xml:
<set name="students" inverse="true"> <key column="classesid"></key> <one-to-many class="学生类.java"/> </set>
inverse=“true”:将维护权交给学生类(多的一方),指明many的一方。
-
多对多:
单向多对多:
学生对课程,学生类中有课程这一属性
<set name="课程" table="课程在数据库中表名"> <key column="学生主键"/> <many-to-many class="课程类" column="课程主键"/> </key> </set>
双向多对多:在单向的基础上,在课程类中添加学生这一属性,并修改 课程.hbm,xml。