Hibernate是一个基于jdbc的开源的持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作。Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
在分层结构中处于持久化层,封装对数据库的访问细节,使业务逻辑层更专注于实现业务逻辑。
Hibernate的优点
1)Hibernate功能强大,是java应用与关系数据库之间的桥梁,较之JDBC方式操作数据库,代码量大大减少,提高了持久化代码的开发速度,降低了维护成本。
2)Hibernate支持许多面向对象的特性,如组合、继承、多态等,使得开发人员不必在面向业务领域的对象模型和面型数据库的关系数据模型之间来回切换,方便开发人员进行领域驱动的面向对象的设计和开发。
3)可移植性好。系统不会绑定在某个特定的关系型数据库上,对于系统更换数据库,通常只需要修改Hibernate配置文件即可正常运行。
4)Hibernate框架开源免费,可以在需要时研究源代码,改写源代码,进行功能的定制,具有可扩展性。
Hibernate的缺点
Hibernate体系架构
Hibernate的环境搭建
创建配置文件hibernat.cfg.xml
此文件主要用于配置数据库连接和Hibernate运行时所需要的各种特性。
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- mysql连接数据库 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/news<![CDATA[?useUnicode=true&characterEncoding=utf8]]></property>
<!-- <property name="connection.url">jdbc:mysql://localhost:3306/news?useUnicode=true&characterEncoding=utf8</property> -->
<property name="connection.username">root</property>
<property name="connection.password">11</property>
<!-- JDBC connection pool (use the built-in) -->
<!-- <property name="connection.pool_size">1</property> -->
<!-- SQL dialect每个数据库都有其对应的方言以匹配其平台特性 -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 指定当前session范围和上下文 -->
<!-- <property name="current_session_context_class">thread</property> -->
<!-- Disable the second-level cache -->
<!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> -->
<!-- 是否将运行期生成的SQL输出到日志以供调试 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property> <!-- 是否格式化SQL-->
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">update</property> -->
<mapping resource="cn/happy/entity/NewsDetail.hbm.xml" />
</session-factory>
</hibernate-configuration>
Oracle连接数据的代码
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="connection.username">happy</property>
<property name="connection.password">happy</property>
<property name="dialect">org.hibernate.dialect.Oracle8iDialect</property>
持久化类:Student
public class Student{ private Integer sid; private String sname; private String pwd;省略get和set..}
映射文件:student.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.hibernate01.entity">
<class name="Student" table="student">
<id name="sid" type="int" column="sid">
<generator class="native"/>
</id>
<property name="sname" type="string" column="sname"/>
<property name="pwd" type="string" column="pwd"/>
</class>
</hibernate-mapping>
通过Hibernate API编写访问数据库的代码
编程步骤:
- 获取Configuration对象
- 获取SessionFactory对象
- 获取Session,打开事务
- 用面向对象的方式操作数据库
- 关闭事务,关闭Session
由于是Hibernate入门,所以我不会搞得很复杂,就只是简单的向数据库中的student表中插入一条记录,然后再取出来而已。
这里我用的是orcal数据库!!!所以主键自动生成用的是序列(sequence), 如果是mysql就用identity
测试类:保存数据
@Test
public void test01() {
Student student=new Student();
student.setSname("xxx22");
student.setPwd("123");
Configuration conf=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sf=conf.buildSessionFactory();
Session session = sf.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(student);
tx.commit();
}
结果显示:
查询数据
@Test
public void test03() {
Configuration conf=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sf=conf.buildSessionFactory();
Session session = sf.getCurrentSession();
session.beginTransaction();
Student student = session.get(Student.class, 1);
System.out.println(student.getSname());
}
结果显示:
Configuration: 加载配置文件 property 、加载hbm映射配置
SessionFactory:线程安全,保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。在SessionFactory中内置了连接池。其有两个常用方法:
openSession() --从连接池中随机获取一个连接
getCurrentSession() --将Session和ThreadLocal绑定,确保在一次请求中,
只有一个Session对象。
getCurrentSession()与openSession()的区别?
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()创建的session必须手动关闭
使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>