简介
由于底层封装了jdbc和很多的东西,所以相对spring等轻量级的框架来说,hibernate是一个重量级的框架,是基于关系型数据库的orm(对象关系映射)和持久性的框架。
实现步骤
1、导包(注意不要忘记mysql的包!)
2、写一个hibernate.cfg.xml核心配置类(包括数据源,额外的配置,关联映射文件)
3、写bean类和映射文件
4、运行前要初始化configuration配置,然后建立与数据库的连接,创建一个session会话。
原理
1、通过configuration接口初始化配置(Configuration cfg=new Configuration().configure()),解析xml。
2、通过拿着初始化配置的对象来创建与数据库的连接(接口是sessionFactory).
方法一:SessionFactory afctory=cfg.buildSessionFactory(); 方法二:ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); SessionFactory factory = cfg.buildSessionFactory(sr);是线程安全并且是重量级的 介绍 重量级的,做的事情多,占内存(会缓存sql语句获取开启服务的快速),sessionFactory实例对应一个数据存储源,如果只访问一个数据库,只需要建立一个sessionFactory对象
3、session(操作sql的)
方法一:Session session = factory.openSession(); 方法二:Session session = factory.getCurrentSession()且要在hibernate.cfg.xml中添加配置 <property name="hibernate.current_session_context_class">thread</property>);这种方式不用关闭,但要提交 特点 是一个持久化管理器;线程不安全(只是对数据的一次操作);轻量级的;一级缓存;及时关闭:通过SessionFactory打开,使用后需及时关闭。
4、开启事务(transaction)
5、query(用于接收从数据库查出来的数据)
example:Query q = (Query) session.createQuery(hql); List<Student> list = q.list();
对象的状态
瞬时状态:是创建了对象放到session作用域之前的过程。(无连接,无唯一标识)
持久状态:是一个过程,实例放到session里面就是被持久化了(有链接,有唯一标识)
游离状态:处于持久化到垃圾回收之间(有唯一标识,无连接)
删除状态
常用方法
contains:判断是否在session中
get()/load():取得持久化的对象(区别:get()不经过懒加载,load()是通过懒加载的,相当于产生了一个代理行为,假如没有使用,就不会真的执行)。
save(),update,saveorupdate,delete是持久化对象的保存,更新,删除。
beginTransaction():开启事务
clear():可清除session缓存。
evict(Object c):是清除指定缓存。
flush():刷新数据库的数据。
缓存
一级缓存:是hibernate自带的,是基于session的事务及缓存,同一个session缓存共用,不同的session缓存不共用,在同一个session缓存中,只能由一个did,不能重复,一级缓存是属于线程动作。
二级缓存
特点 基于sessionFactory,贯穿整个服务,属于进程的范围 内置缓存 预定义sql,是二级缓存自带的 外置缓存 要配置插件 应用场景 适合 很少被修改 不是很重要的数据 允许出现偶尔的并发问题 不适合 经常被修改 财务数据 不允许出现并发问题 与其他应用数据共享的数据
三级缓存(查询缓存)
特点 针对数据很少被改动的情况,因为如果查询缓存的对象映射的表被改动,查询缓存就会失效 说明 要基于二级缓存使用才有意义,因为查询缓存缓存的是所有的id,然后通过id去二级缓存查询数据,如果不开启二级缓存,会拿着id依次到数据库查询,十分消耗资源
映射关系
双向一对一
1、你中有我,我中有你 2、<!-- 主表映射配置 --> <one-to-one name="address" cascade="all" property-ref="stu"/> 3、<!-- 副表映射配置 --> <many-to-one name="stu" column="s_id" unique="true" />
单向一对一
1、<!-- 主表使用one-to-one来添加映射,会引用从表对应的属性名 --> <one-to-one name="address" cascade="all" class="Address" /> 2、<!-- 副表映射文件配置 --> <one-to-one name="student" class="Student" constrained="true" /> 3、<!-- 设置组件生产策略 --> <!-- 设置数据库主键的生成策略,native表示自动检查数据库,选择适当的生成策略 --> <generator class="foreign"> <param name="property">student</param> </generator>
一对多
一个班级对应多个学生 1、 //学生 private Clazz clazz; 2、 //班级private Set<Student> studentSet; 3、 //学生映射 <!-- 添加学生对班级的引用,多对一的关联映射 --> <many-to-one name="clazz" column="c_id" class="Clazz"/> 4、 //班级映射 <set name="studentSet" cascade="all" inverse="true"> <key column="c_id" /> <one-to-many class="Student" /> </set>
多对多
学生和课程 1、//学生 private Set<Course> courseSet 2、//课程 private Set<Student> studentSet; 3、学生映射 <many-to-many class="com.hsia.MOM.Course" column="course_Id" /> 4、课程映射 <many-to-many class="com.hsia.MOM.Student" column="stu_id" />
查询
HQL (仿sql,性能一般)
查的是实体类的属性或者字段,而非数据库;iterator 会执行(n+1)条sql语句,第一次获取所有的id,然后查看每个id,通过迭代的方式获取值,可用于方便判断,提高性能,这种迭代方式相当于生成了一个代理行为,假使不使用迭代出来的对象,查询的sql就不会执行 操作的是对象 仿sql
QBC (无sql,纯对象,性能低)
1、Criterion,可以在不使用sql情况下进行查询。 2、Criteria criteria = session.createCriteria(Dept.class); List<Dept> list = criteria.list(); 查询Dept所有的数据 3、Criteria criteria = session.createCriteria(Dept.class); criteria = criteria.add(Restrictions.eq("location", "西一区")); List<Dept> list = criteria.list();条件查询,前面是属性,后面的是值。 完全对象操控 可调控的SQL(纯sql,无对象,性能高)
原生sql查询,查的是数据库的数据 命名查询:<hibernate-mapping> <class name="cn.jbit.hibernatedemo.entity.Emp" table="emp"> ...... </class> <sql-query name="selectEmpByJob"> <return alias="e" class="cn.jbit.hibernatedemo.entity.Emp"/> select {e.*} from EMP e where e.job = :job </sql-query> </hibernate-mapping>