浅析Hibernate

简介

    由于底层封装了jdbc和很多的东西,是基于关系型数据库的orm(对象关系映射)和持久性的框架,特点是全自动,mybatis是半自动。

实现步骤

    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():取得持久化的对象(

         区别:

                1、get()不经过懒加载,load()是通过懒加载的,相当于产生了一个代理行为,假如没有使用,就不会真的执行

                2、get查询内部缓存(一级缓存),没有结果就直接调用sql去访问数据库会跳过二级缓存(1.3版本之前),load不会跳过二级缓存

                3、load可以返回实体的代理类实例,get直接返回实体类

                4、当查询不到符合条件的数据时,get返回null,load会报异常。

        )。

    save(),update,saveorupdate,delete是持久化对象的保存,更新,删除。

    beginTransaction():开启事务

    clear():可清除session缓存。

    evict(Object c):是清除指定缓存。

    flush():刷新数据库的数据。

缓存
    一级缓存:是hibernate自带的,是基于session的事务及缓存,同一个session缓存共用,不同的session缓存不共用,在同一个session缓存中,只能由一个did,不能重复,一级缓存是属于线程动作。如果查询时一级缓存没有符合的数据就去数据库查并把结果保存在一级缓存中。

    二级缓存

特点
	基于sessionFactory,贯穿整个服务,属于进程的范围
内置缓存
	预定义sql,是二级缓存自带的
外置缓存
	要配置插件
应用场景
	适合
		很少被修改
		不是很重要的数据
		允许出现偶尔的并发问题
	不适合
		经常被修改
		财务数据
		不允许出现并发问题
		与其他应用数据共享的数据
打开二级缓存:
首先配置第3 放插件,我们用的是EHCache,在hibernate.cfg.xml 文件中加入<propertyname="hibernate.cache.user_second_level_cache">true</property>
在映射中也要显示的调用,<cacheusage="read-only"/>二级缓存之查询缓存:对普通属性进行缓存。如果关联的表发生了修改,那么查询缓存的生命周期也结束了。在程序中必须手动启用查询缓存:query.setCacheable(true);

    三级缓存(查询缓存)

特点
	针对数据很少被改动的情况,因为如果查询缓存的对象映射的表被改动,查询缓存就会失效
说明
	要基于二级缓存使用才有意义,因为查询缓存缓存的是所有的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>
优缺点:

    优点是封装了JDBC简化了很多重复性代码;简化了dao层编码的工作,使开发更对象化了;移植性好,如果换一个数据库只要改配置文件就可以了;支持透明持久化,因为hibernate操作的是纯粹的java实体类,并且没有实现任何接口,没有侵入性,所以是一个轻量级的框架。

    缺点是因为是基于对象操作,所以sql不灵活,难优化。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值