一、Hibernate初识
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲地使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
hiberbate优点:使用面相对象的方式操纵数据库
1.切换数据库对它没有影响
2.实现功能的sql语句方式统一
3.程序移植扩展不依赖sql,维护方便
Tips:Intellij IDEA自动集成了hibernate和junit的jar包
二、创建第一个Hibernate例子
1. 创建工程,导入jar包
2. 创建Hibernate配置文件
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernate?useUnicode=true</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name=“format_sql">true</property>
<property name="hbm2ddl.auto">create</property> <! -- 会重新创建一张表 -- >
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="com/imooc/student/Student.hbm.xml"/>
Tips:配置文件每个字母都要正确,错一个后果严重;文件名为hibernate.cfg.xml
其中url中的hibernate为数据库名称,dialect指定为MySQL5Dialect
3.创建持久化类
遵守javabeans的设计原则:1.公有的类;2.提供公有的不带参数的构造方法;3.属性私有;4.属性setter/getter封装
e.g.创建一个Student持久化类
4. 创建对象—关系映射文件
作用:将持久层的类及其属性与数据库表名和字段进行映射,文件名为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>
<class name="com.imooc.student.Student" table="students">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="name" />
</property>
<property name="age" type="int">
<column name="age" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" />
</property>
<property name="address" type="java.lang.String">
<column name="address" />
</property>
</class>
</hibernate-mapping>
创建完对象关系映射文件后,需要在cfg.xml中配置文件声明:如<mapping resource="Student.hbm.xml" ></mapping> 或者<mapping class=“com.imooc.Student” />
5. 使用Junit进行测试
使用到的标签:
@Test:要测试的方法。
@Before:初始化方法(表示在测试前会先执行before方法进行初始化)。
@After:释放资源。
e.g.新建一个test源文件目录,新建StudentTest.java类,包括标签为@Before的init()方法,标签为@Test的testSaveStudent()方法,标签为@After的destroy()方法
@Before
public void init() {
Configuration config = new Configuration().configure(); // 创建配置对象
config.addClass(Student.class);// 创建服务注册对象
ServiceRegistry serviceRegistery = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
// 创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistery);// 创建会话对象
session = sessionFactory.openSession();// 开启事务
transaction = session.beginTransaction();
}
@After
public void destory() {
// 提交事务
transaction.commit();
// 关闭会话
session.close();
// 关闭会话工厂
sessionFactory.close();
}
6. 通过Hibernate API编写访问数据库的代码
StudentTest.java中定义三个私有属性:sessionFactory、session、transaction
二、Hibernate进阶
1. hibernate.cfg.xml配置
2. session简介
- Configuration对象:配置文件对象,读取hibernate配置文件xxx.cfg.xml
- SessionFactory对象:读取对象/关系映射文件 xxx.hbm.xml
- session对象:数据库链接对象,获得之后可以操作数据库。可以理解为操作数据库的对象
- Transaction:使用session操作数据库需要开启的事务
关于session的说明:
- 不建议直接使用jdbc的connection操作数据库,而是通过使用session操作数据库;
- session可以理解为操作数据库的对象;
- session与connection,是多对一的关系,每个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用;
- 把对象保存到关系型数据库中需要调用session的各种方法,如:save(),update(),delete(),createQuery()等。
3. transaction简介
- hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。
- 如果想让hibernate想jdbc那样自动提交事务,必须调用session对象的doWork()方法,获得jdbc的connection后,设置其为自动提交事务模式。(注意:通常并不推荐这样做)
//不开启事务(transaction.commit()//提交事务)的方式
@Test
public void testSaveStudents(){
Stusdents s= new Students(1,"ZSF",new Date(),"wudang");
session.doWork(new Work(){
@Override
public void execute(Connection connection) throws SQLException{
connection.setAutoCommit(true);
}
})
session.save(s);//保存对象进入数据库
session.flush();//强制发出SQL语句(通过SQL写入SQL)
}
- 不开启事务就不能将对象保存到数据库中!!!
4. session详解
- 如何获取session对象?
(1)openSessionion
(2)getCurrentSession
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置:
如果是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
如果是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
openSession与getCurrentSession的区别?
- openSession:每次创建新的session对象;每次使用需要手动关闭session,不会自动关闭。cfg.xml文件无需其他配置
- getCurrentSession:使用现有的session对象;每次使用不需要手动关闭session,会自动关闭。cfg.xml文件需其他配置
- 可以通过打印session里的connection的hashcode来验证,如果没有设置数据库连接池,那么初始连接池的大小是20,最小是1,也就是说当启动hibernate的时候,hibernate就初始化了一个connection对象放在数据库连接池里面了。如果第一次调用openSession的时候,hibernate直接就把连接池里面的connection对象给你了,但是如果你没有关闭session,那么这个connection对象就没有被释放,所以当你再次调用openSession的时候,hibernate就会创建一个新的connection对象,如果一直这样,连接池就溢出了
5. hbm配置文档
<hibernate-mapping>
schema="schemaName" //模式的名字
catalog="catalogName" //目录的名称
default-cascade="cassade_style" //级联风格
default-access="field/property/CalssName" //访问策略
default-lazy="true/false" //加载策略
package="packagename" //默认包名
/>
<class>
name="ClassName" //对应映射的类
table="tableName" //对应映射数据库的表
batch-size="N" //抓取策略,一次抓取多少记录
where="condition" //条件 eg:抓取条件
entity-name="EntiyName" //如果需要映射多张表
/>
//表的主键
<id
name="propertyName" //对应的属性
type="typeName" //对应类型
column="column_nam" //映射数据库中表当中字段名的名称
length="length" //指定长度
<generator class="generatorClass"/>//主键生成策略
</id>
主键生成策略:
由于使用MYSQL,着重讲解一下两个
native:由底层数据库自动生成标识符
assigned:手工赋值
三、Hibernate单表操作
1. 单一主键
单一主键:指表中由某一列来充当主键
<id name="id"type="int">
<columnname="id"/>
<generatorclass="assigned"/>
</id>
assigned 由java应用程序负责生成(手工赋值)
native 由底层数据库自动生成提示符,如果是MySQL就是increment,如果是Oracle就是sequence,等等。另外,即使手动赋值主键,也不会起作用。
2. 基本类型
对象/映射关系配置文件中属性的类型type可以用hibernate的也可以用java的
3. 对象类型
CLOB类型:大文本类型
BLOB:大的二进制文件类型(如音频、视频、图片等)
MySQL不支持变准SQL的CLOB类型,在MySQL智能光,用TEXT,MEDIUMTEXT以及LONGTEXT类型表示长度唱过255字节的长文本数据。
4. 组件属性
组件属性:某个类对象的成员属性是一个自定义类型对象。
存储在数据库中的效果和单一字段一样
hbm文件中的配置:
<component name="address"class="com.imooc.hibernate.Address">
<propertyname="postcode"column="POSTCODE"/>
<propertyname="phone"column="PHONE"/>
<propertyname="address"column="ADDRESS"/>
</component>
5. 单表CRUD操作实例
- 保存对象,save
- 修改对象,update
- 删除对象,delete
- 查询单个记录,get/load
- get与load的区别
- 在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象。
- load方法会在调用后返回一个代理对象,该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。
- 查询数据库中不存在的数据时,get方法返回null,load方法抛出异常org.hibernate.ObjectNotFoundException
四、总结
1.什么是ORM?为什么使用Hibernate?
对象关系映射;为了少写和底层数据库相关的sql语句,方便程序的维护、修改,提高跨平台性和可扩展性。Hibernate是Java领域内的一款技术成熟稳定的ORM框架
2.Hibernate开发的基本步骤?
(1)编写配置文档hibernate.cfg.xml
(2)编写实体类。注意:每一个实体类都要与数据库中的一张表一一对应,实体类的编写要遵循JavaBean的要求。
(3)生成对应实体类的映射文件并添加到配置文档中
(4)调用Hibernate API进行测试
3.什么是session?
类似于JDBC里面的connection对象。调用session操作数据库,实际上就是调用connection的各种API函数来实现的。
4.openSession与getCurrentSession的区别?
openSension每次都是创建新的session对象,而getCurrentSenssion使用单例模式,每次创建都是相同的对象。openSession在使用完毕后需要显式地关闭,而getCurrentSession在事务提交之后会自动关闭。
5.单表操作有哪些常用的方法?
增删改查对应使用session当中的save、delete、update、get/load方法
6.单表操作,查询一条记录时,get和load的区别?
get在使用的时候立即发送sql语句,并且获得的是实体类的对象类型,而load只有在使用具体对象的非主键属性的时候才会发送sql语句,而且返回的是一个代理对象