简单的Hibernate搭建

Hibernate简介

什么是hibernate?
hibernate是免费开源的框架,是一个OR-Mapping映射工具, 将实体类和数据库表形成映射关系,是一个优秀的持久层解决方案,hibernate对jdbc进行了封装,我们不需要再关心底层实现,只需要关系具体的业务实现即可。
hibernate核心类和接口
Configuration类: 加载hibernate.cfg.xml配置文件
SessionFactory接口:会话工厂,可以得到会话
Session接口: 会话,操作CRUD增删改查
Transaction接口: 事务,开启事务,提交事务,关闭事务
为什么使用hibernate?
hibernate是一个优秀的持久层解决方案,提供了标准化模版,能够为开发人员提高开发效率。
Hibernate和MyBatis的区别?
1.Hibernate是全自动的ORM框架 而MyBatis是半自动的ORM框架
2.MyBatis 是一个基于DAO层处理的ORM框架 SQL语句和实体映射
Hibernate 是一个基于DAO层处理的ORM框架 表和实体的映射
3.Hibernate是一个重量级框架 适用于大中型项目
MyBatis是一个轻量级框架 适用于中小型项目 尤其是当下的互联网项目
4.Hibernate封装的比较好,而MyBatis比较灵活


提醒

引入dtd文件 提供配置文件自动提示功能
1.在hibernate3.jar解压 org.hibernate下面找dtd文件
2.在window-perferences-xml catalog下配置dtd指定key和dtd文件对应


搭建Hibernate

1.导入jar包

链接:http://pan.baidu.com/s/1eSmy40q 密码:q6za

2.编写Hibernate配置文件 hibernate.cfg.xml

<hibernate-configuration>
        <!-- 配置数据库连接信息 -->
        <session-factory>
        <!-- 配置数据库驱动 -->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <!-- 配置数据库连接URL -->
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <!-- 配置用户名 -->
        <property name="connection.username">system</property>
        <!-- 配置密码 -->
        <property name="connection.password">accp</property>
        <!-- 方言 -->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <!-- Session上下文 -->
        <property name="current_session_context_class">thread</property>
        <!-- 配置日志 输出sql语句 -->
        <property name="show_sql">true</property>
        <!-- 配置日志 对输出的sql语句进行格式化处理 -->
        <property name="format_sql">true</property>
        <mapping resource="com/kawa/pojo/user.hbm.xml"/>
        </session-factory>
        </hibernate-configuration>

3.编写user.hbm.xml映射文件

    <hibernate-mapping>
        <class name="com.kawa.pojo.User" table="users">
        <id column="id" name="id" type="java.lang.Integer"></id>
        <property column="name" name="name" type="java.lang.String"></property>
        <property column="pwd" name="pwd" type="java.lang.String"></property>
        </class>
        </hibernate-mapping>

4.编写测试类

    public void addUser(){

        //1.获取Session对象
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();

        //开启事务
        Transaction tran = session.beginTransaction();

        User user = new User();
        user.setId(3);
        user.setName("Marry");
        user.setPwd("123456");

        try {
        //2.通过Session对象执行操作
        session.save(user);
        tran.commit();
        System.out.println("数据插入成功!");
        } catch (HibernateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        tran.rollback();
        }
        //3.关闭Session对象
        session.close();
        }

注意
1.不要忘记在hibernate.cfg.xml中引入xxx.hbm.xml映射文件
2.在进行数据库增删改时不要忘记开启事务 成功提交事务,失败回滚事务
3.不要忘记导入slf4j.jar的log4j实现jar包 以及log4j.jar


主键生成策略

1.increment:对类型为long short 或 int的主键,以自动增长的方式生成主键的值。主键按数值顺序递增,增量为1.
2.identity:对如SQLServer、DB2、MySQL等支持标识列的数据库,课使用该主键生成策略生成自动增长主键,但要在数据库中将该主键设置为标识列。
3.sequence:对如Oracle、DB2等支持序列的数据库,可使用该主键生成策略生成自动增长主键,通过子元素param传入数据库中序列的名称。
4.native:由Hibernate根据底层数据库自行判断采用何种主键生成策略,即由使用的数据库生成主键的值。
5.assigned:主键由应用程序负责生成,无需Hibernate参与


Code Frist思想

代码第一,先有代码后有数据库 ,可以使用hibernate利用pojo和hbm.xml去生成数据库表
配置hibernate.cfg.xml

<property name="hibernate.hbm2ddl.auto">update</property>

主键查询

get查询和load查询的区别?
1.get查询不到数据会返回null 而load查询不到会抛出异常ObjectNotFoundException
2.hibernate默认使用懒加载,在缓存中不存在查询数据时,get会直接到数据库中查找,而load不会,
load只会产生一个代理对象,只有在其后进行除get之外的其他操作才会真正的查询数据库

    session.get(Users.class, new Short("4"));
    session.load(Users.class, new Short("4"));

Hibernate的三种状态

Hibernate框架通过Session来管理Java对象的状态
瞬时状态 new对象/delete
通过new创建对象后,没有存储到数据库,此时java对象的状态为瞬时状态。
持久状态 get、load/save/update
当对象与Session关联,被Session管理时,他就处于持久状态。
对象与Session关联:
1.通过Session查询接口,或者get()|load()
2.通过调用Session的save()|SaveOrUpdate()
游离状态 evict、clear、close
处于持久状态的对象,脱离与其关联的Session管理后,对象就处于游离状态。
Session提供两个方法(update() merge())将处于游离状态的对象与一个新的Session发生关联

三种状态之间的转换

1.瞬时状态转换为持久状态
使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态
使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态
2.持久状态转换为瞬时状态
执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联
3.持久状态转为游离状态
执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态
4.游离状态转为持久状态
重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象关联
5.游离状态转为瞬时状态
执行Session对象的delete()方法,对象由游离状态转为瞬时状态。
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机安装垃圾回收机制处理。


脏检查和刷新缓存

脏检查:session中的对象信息与数据库不一致
刷新缓存:解决session中的对象信息与数据库不一致的情况
实现:flush()、commit()
Session是Hibernate向应用程序提供的操纵数据库的主要接口,它提供了基本的保存、更新、删除和加载Java对象的方法。Session具有一个缓存,可以管理和跟踪所有持久化对象,对象和数据库中的相关记录对应。在某些时间点,Session会根据缓存中对象的变化来执行相关SQL语句,将对象包含的编号数据更新到数据库中,这一过程称为刷新缓存,换句话说就是将Session缓存同步刷新为与数据库一致。
脏检查
在Hibernate中,状态前后发生变化的对象,称为脏对象。
当事务提交时,Hibernate会对Session中持久状态的对象进行检测,判断对象的数据时候发生了改变,这种判断称为脏检查。
Hibernate为什么要进行脏检查呢?
因为如果对象发生了改变,就需要将改变更新到数据库中,以确保内存中的对象与数据库中的数据保持一致。
Session是如何进行脏检查的呢?
当一个Dept对象被加入到Session缓存中时,Session会为Dept对象的值类型的属性复制一份快照。当Session刷新缓存是,会先进行脏检查,即比较Dept对象的当前属性与它的快照,来判断Dept对象的属性是否发生了变化。如果发生了变化,Session会根据脏对象的最新属性值来执行相关的SQL语句,将变化更新到数据库中。
刷新缓存机制
当Session缓存中对象的属性每次发生变化时,Session并不会立即刷新缓存和执行相关的SQL语句,而是在特定的时间点才刷新缓存。这使得Session能够把几条相关的SQL语句合并为一条或者一批SQL语句,减少了访问数据库的次数,从而提高应用程序的数据访问性能。
Session在何时刷新缓存呢?
1.当应用程序调用Transcation的commit()方法时,commit()方法先调用Session的刷新缓存方法flush(),然后向数据库提交事务。Hibernate之所以把刷新缓存时间点安排在事务快结束时,一方面是因为可以减少访问数据库的频率,林一方面是因为可以尽可能缩短当前事务对数据库中相关资源的锁定时间。
2.当应用程序显示调用Session的flush()方法时,刷新缓存。
Session的flush()方法和Transaction的commit()方法的区别?
flush()方法进行刷新缓存的操作,执行一系列的SQL语句,但不会提交事务;commit()方法会先调用flush()方法,然后提交事务。提交事务意味着对数据库所做的更新被永久保存下来。


sava、update、savaOrUpdate、merge的区别?
save()方法用于将一个临时对象转变为持久化对象,也就是将一个新的业务实体保存到数据库中;
update()方法用于将一个游离对象重新转变为持久化对象,也就是更新一个已经存在的业务实体到数据库中;
saveOrUpdate()兼具了save()和update()方法的功能,该方法根据传入参数的状态执行不同的操作,当为临时状态时,调用save()方法;当为持久化状态时,则直接返回;当为游离状态时,调用update()方法。
merge()方法主要用于更新和保存实体,当实体不存在时,则执行保存操作,当实体已经存在时,执行更新操作,其实同saveOrUpdate()的功能是类似的。


update 和saveOrUpdate区别
这个是比较好理解的,顾名思义,saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段话来解释他们的使用场合和区别
通常下面的场景会使用update()或saveOrUpdate():
程序在第一个session中加载对象,接着把session关闭
该对象被传递到表现层
对象发生了一些改动
该对象被返回到业务逻辑层最终到持久层
程序创建第二session调用第二个session的update()方法持久这些改动
saveOrUpdate(po)做下面的事:
如果该po对象已经在本session中持久化了,在本session中执行saveOrUpdate不做任何事
如果savaOrUpdate(新po)与另一个与本session关联的po对象拥有相同的持久化标识(identifier),抛出一个异常
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]
saveOrUpdate如果对象没有持久化标识(identifier)属性,对其调用save() ,否则update() 这个对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值