这个假期准备把hibernate学会,学习这个hibernate的动机就是觉得自己在开发项目的时候,数据库操作方面的代码效率不高,只是使用了简单的JDBC操作数据库,没有数据库连接池或者缓存之类的机制,所以准备学习hibernate,填补这方面的缺陷。
写这篇博客的目的是总结学习hibernate的每个阶段,一方面可以加深对知识的理解,另一方面可以供自己以后查阅。
1. Hibernate是什么
- hibernate是一个框架(framework)
- hibernate是一个ORM(Object Relation Mapping,关系对象映射)框架
- hibernate处于项目的持久层位置
- hibernate实际上就是对JDBC进行了轻量级的封装
2. Hibernate的基础是java的反射机制
3. 需要重点学习的三个方面:
①hibernate api
②hibernate.cfg.xml hibernate核心配置文件
③对象关系映射文件
4. Hibernate可以应用在J2SE项目中,也可以用在J2EE项目中。Struts是web框架,所以只能用在web项目中。
5. 对象持久化:把对象保存在数据库中或者文件中。
6. 手动配置Hibernate,完成CRUD操作
①在MyEclipse中创建一个java项目
②画出一个简单项目框架示意图
③引入hibernate开发包
④开发hibernate项目有三种方式
a) 由Domain object -> mapping -> db (官方推荐)
b) 由db开始。用工具生成mapping和domain object (使用较多)
c) 由映射文件开始
7. 我们使用第二种开发方式
1) 创建employee表(oracle数据库)
create table employee(
id number primary key,
name varchar2(64) not null,
email varchar2(64) not null,
hiredate date not null
)
2) 开发domain对象和对象关系映射文件
关于POJO:实际上就是JavaBean,一个POJO类应当具有:
① 有一个主键属性,用于唯一标识该对象
② 有其他属性
③有对各个属性操作的get/set方法
④属性一般是private修饰
⑤一定有一个无参的构造函数(用于hibernate框架放射用)
⑥pojo对象需要序列化
POJO类一般放在com.xxx.domain包下
对象关系映射文件:作用是指定domain对象和表的映射关系,命名规则:domain对象.hbm.xml,一般放在和domain对象同一个文件夹(包)下。
3) 创建一个序列,用于主键生成策略
create sequence emp_seq
start with 1
increment by 1
minvalue 1
nomaxvalue
nocycle
nocache
4) 配置文件Employee.hbm.xml如下:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hh.domain">
<!-- class中,table代表数据库中的表,name表示所映射的java类的类名 -->
<class name="Employee" table="employee">
<!-- id元素用于指定主键属性.name=id表示Employee中表示的主键,column表示对一个的表中的主键 -->
<id name="id" column="id" type="java.lang.Integer">
<!-- generator用于指定主键值生成策略 -->
<generator class="sequence">
<param name="sequence">emp_seq</param>
</generator>
</id>
<!-- 对其它属性进行配置 -->
<property name="name" type="java.lang.String">
<!-- column中的name值对应的是数据表中的字段的名字,not-null=false表示不允许为空 -->
<column name="name" not-null="false"></column>
</property>
<property name="email" type="java.lang.String">
<column name="email" not-null="false"></column>
</property>
<property name="hiredate" type="java.util.Date">
<column name="hiredate" not-null="false"></column>
</property>
</class>
</hibernate-mapping>
5) 手动配置hibernate.cfg.xml文件,该文件用于配置连接的数据库类型、driver、用户名、密码、URL等等,同时管理对象关系映射文件。hibernate.cfg.xml这个文件的文件名一般不修改。
6) 在hibernate中,几个比较重要的类和接口
①Configuration
②SessionFactory
③Session
④Transaction
7) hibernate.cfg.xml配置文件如下:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 设计者给我们提供了一些常用的配置可在etc文件夹下找到 -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.username">csr</property>
<property name="connection.password">***</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
<!-- 配置dialect,明确告诉hibernate连接的是哪种数据库 -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- 显示出对应的SQL语句 -->
<property name="show_sql">true</property>
<!-- 指定对象关系映射文件 -->
<mapping resource="com/hh/domain/Employee.hbm.xml" />
</session-factory>
</hibernate-configuration>
8) 测试文件TestMain.java文件内容如下
package com.hh.view;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.hh.domain.Employee;
import com.hh.util.*;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
//删除用户
public static void deleteEmployee() {
//获取一个对话
Session session = MySessionFactory.getSessionFactory().openSession();
Transaction ts = session.beginTransaction();
//删除 1.先获取该雇员,然后删除
Employee employee = (Employee)session.load(Employee.class, 3);
session.delete(employee);
ts.commit();
session.close();
}
//修改用户
public static void updateEmployee() {
//获取一个会话
Session session = MySessionFactory.getSessionFactory().openSession();
Transaction ts = session.beginTransaction();
//修改用户1.获取要修改的用户。 2.修改
//loda方法是通过主键属性,获取该对象实例,该对象与表的记录对应
Employee employee = (Employee)session.load(Employee.class, 3);//这句话产生一个select语句
employee.setName("胡辉8");//update.这句话会导致一个update语句产生
employee.setEmail("abc@sohu.com");//修改两个地方,但是也只产生一个SQL语句
ts.commit();
session.close();
}
//增加用户
public static void addEmployee() {
// 我们使用hibernate完成crud操作【这里我们只见对象,不见表】
// 不使用Service,直接测试
// 1.创建Configuration,用于读取配置文件hibernate.cfg.xml,并完成初始化
Configuration configuration = new Configuration().configure();
// 2.创建SessionFactory,这是一个会话工厂,是一个重量级的对象
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.创建session,相当于JDBC中的Connection,用于和数据库的对话.这个会话不是jsp中的session
Session session = sessionFactory.openSession();
// 4.对Hibernate而言,要求程序员,在进行增加,删除,修改的时候使用事务提交,查询可以不用
Transaction transaction = session.beginTransaction();
// 添加一个雇员
Employee employee = new Employee();
employee.setName("huhui");
employee.setEmail("huhui@sina.com");
employee.setHiredate(new Date());
// 保存
session.save(employee);// 持久化该对象(保存到了数据库中)==>insert into.......
// 提交
transaction.commit();
// 关闭资源
session.close();
}
}
需要注意,在使用hibernate开发项目的时候,请一定保证只有一个SessionFactory。如果连接了多个数据库,可以有多个SessionFactory,即一个数据库分配一个SessionFactory。
于是,对上面的java代码进行优化,创建MySessionFactory.java,目的是将SessionFactory做成单态:
final public class MySessionFactory {
private static SessionFactory sessionFactory = null;
private MySessionFactory(){
}
static{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}