Hibernate入门

Hibernate入门

基本概述

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSPWeb应用中使用,最具革命意义的是,Hibernate可以在应用EJBJ2EE架构中取代CMP,完成数据持久化的重任。

    hibernate是轻量级的ORM框架,ORM全称object/relation mapping [对象/关系映射]

PSJAR包及其文档可以在官网网站下载:http://www.hibernate.org

 

ORM基本概念

    对象关系映射(Object Relation Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

PS:通过ORM这种技术可以在JAVA程序以类和对象的形式去操控数据库的表和记录。

 

ORM框架

1Apache OJB

2Hibernate

3iBatis

4SMYLE

5TopLink

 

使用Hibernate的好处

1、引入hibernate可以使工作人员角色细化,让程序员更关心业务流程。让数据库人员关注数据库相关的各种操作。

2、分层更清晰,耦合性更小。

3、通用性强:可以更轻松的从一个数据库平台转移到别的平台。

4、对象化:把关系数据库变成了Java的对象,更加方便操作。

5、性能保证:hibernate可能按不同的数据库,处理不同的操作是用最优化的SQL语句。

6、增加了程序的鲁棒性。

 

基本原理图

PSHibernate的基本原理是通过反射机制,将DB中的表与Java类进行映射。

 

Hibernate框架与JDBC的区别

PS:使用JDBC的时候如果有结果需要处理还需要进行二次封装,而Hibernate这样的ORM框架已经在内部就已经封装好了,故其功能更强大,也更便捷。

 

MVC框架图(加上Hibernate框架)

PS:这可以和前段时间写的Struts入门Web MVC模式实现 这两篇博客里的MVC模式进行比较。

 

Hibernate开发的三种方式

1、由Domain对象->mapping->database(官方推荐)

2、由Database->Domain对象->mapping

3、由映射文件开始

PS:其实通过MyEclipse可以自动生成大部分代码,但是为了理解的更深刻,还是要学习手工开发。

 

Hibernate手工开发

    采用上述第二种方式,实现一个员工管理系统。

1Database设计(Oracle)

--创建employee表
create table employee
(
       id number primary key, --编号
       name varchar2(50) not null,  --姓名
       email varchar2(50) not null, --电子邮件
       hiredate date not null --入职时间
);

--创建employee自增序列
create sequence emp_seq
start with 1
increment by 1
minvalue 1
nomaxvalue
nocycle
nocache
;

2、引入hibernate

    这个可以到官方网站上下载,然后引入。

3、编写POJO(Employee)

package com.pc.domain;

import java.io.Serializable;
import java.util.Date;

/**
 * 
 * @author Switch
 * @function employee表的映射Domain对象
 * @description 可以视为Domain对象、Javabean、POJO,该POJO按照规范应当序列化,目的是唯一的标识该对象,同时可以在网络和文件传输
 *
 */
public class Employee implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
    private String name;
    private String email;
    private Date hiredate;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}   
}

4、编写对象映射文件(Employee.hbm.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!-- 映射文件需要DTD来指定格式 -->
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 该文件用于配置domain对象和表的映射关系 -->
<!-- package指定是哪个包下面的映射 -->
<hibernate-mapping package="com.pc.domain">
	<!-- name指domain对象的名字 -->
	<!-- table指表的名字 -->
	<class name="Employee" table="employee">
		<!-- ID元素用户指定主键属性 -->
		<!-- name指定domain对象中的主键属性 -->
		<!-- column指定表中的主键列 -->
		<!-- type指定属性类型 -->
		<id name="id" column="id" type="java.lang.Integer">
			<!-- 该元素用户指定主键值生成策略 -->
			<!-- class指生成策略类型 -->
			<!-- hilo native increment sequence uuid等 -->
			<generator class="sequence">
				<!-- name指定生成策略参数名 -->
				<!-- 其中的值表示对应的东西,这里是一个自增序列 -->
				<param name="sequence">emp_seq</param>
			</generator>
		</id>
		<!-- 对其它属性的配置 -->
		<!-- name表示属性名 -->
		<!-- type表示属性类型 -->
		<property name="name" type="java.lang.String">
			<!-- 配置对应列属性 -->
			<!-- name对应于表中相应列 -->
			<!-- not-null之类的属性可以表示该列的限制 -->
			<column name="name" not-null="false" />
		</property>
		<property name="email" type="java.lang.String">
			<column name="email" not-null="false" />
		</property>
		<property name="hiredate" type="java.util.Date">
			<column name="hiredate" not-null="false" />
		</property>
	</class>
</hibernate-mapping>

5、配置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>
	<!-- 配置oracle连接 -->
	<session-factory>
		<!-- 常用配置可以参考hibernate集合包主目录\project\etc、hibernate.properties文件 -->
		<!-- 配置driver -->
		<!-- name表示参数类型 -->
		<!-- 元素值表示参数内容 -->
		<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
		<!-- 配置url -->
		<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:SWITCH</property>
		<!-- 配置用户名 -->
		<property name="connection.username">scott</property>
		<!-- 配置密码 -->
		<property name="connection.password">123456</property>
		<!-- 配置显示hibernate生成的 sql ,特别说明,在开发阶段设为true利于调试,在使用项目则设为false-->
		<property name="show_sql">true</property>
		<!-- 配置dialect,明确的告知Hibernate连接的是哪种数据库 -->
		<property name="dialect">org.hibernate.dialect.OracleDialect</property>
		<!-- 指定管理的对象映射文件 -->
		<!-- resource指定单个domain对象的配置文件 -->
		<mapping resource="com/pc/domain/Employee.hbm.xml" />
	</session-factory>
</hibernate-configuration>

6、编写测试类测试

    为了简单这里不写EmployeeService类提供服务了,直接调用持久层。但是实际开发,必须要通过EmployeeService调用持久层提供服务。

package com.pc.view;

import java.util.Date;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

import com.pc.domain.Employee;
import com.pc.util.MySessionFactory;

public class TestMain {
	public static void main(String[] args) {
		// 使用hibernate完成crud操作(只见对象,不见表)
		// 不使用service,直接测试
		// 1.创建Configuration对象,该对象用于读取hibernate.cfg.xml,并完成初始化
		// configure默认载入hibernate.cfg.xml文件,可以指定需要载入的xml
		Configuration configuration = new Configuration().configure();
		// 2.创建SessionFactory对象(这是一个会话工厂,是一个重量级的对象)
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.创建Session(用于与数据库的对话,相当于JDBC中的Connection)
		Session session = sessionFactory.openSession();
		// 4.对Hibernate而言,要求程序员,在进行增加、删除、修改的时候使用事务提交,否则不生效
		Transaction transaction = session.beginTransaction();
		// 添加一个雇员
		Employee employee = new Employee();
		employee.setName("zs");
		employee.setEmail("123456@switch.com");
		employee.setHiredate(new Date());
		// 保存
		// --->insert into ...[被hibernate封装]
		session.save(employee);
		// 提交
		transaction.commit();
		session.close();
    }
}

补充内容

1Hibernate依赖的其它库

Jar

说明

Commons Collections

Commons的集合类库

antlr

Java开源的语法分析生成器

dom4j

进行XML解析的类库

javassist

开源的分析、编辑和创建Java字节码的类库

slf4j-api

Simple Logging Facade for Java,日志处理API

slf4j-simple

SLF4J API的实现,实现了简单日志处理

JTA

Java Transaction APIJava中的事务处理API

PSHibernate框架是由许多技术组成的,比如解析XMLdom4j等等。

2POJO(Plain Ordinary Java Objects简单的Java对象)

    在使用hibernate时,要求和数据库的某张表相互映射的那个java类,是一个POJO类,一般放在com.xxx.domain包下,POJO类翻译过来就是:简单的Java对象(Plain Ordinary Java Objects)实际就是普通JavaBeans,使用POJO名称是为了避免和EJB混淆起来。一个POJO类应当具有:

1有一个主键属性,用于唯一标识该对象。(这就是hibernate设计者建议要映射的表需要一个主键的原因)

2有其它的属性

3有对各个属性操作的get/set方法

4属性一般是private修饰.

5一定有一个无参的构造函数(用于hibernate框架反射用)

3、使用第一种方式实现Hibernate

    第一种方式是先写Domain对象,再由mapping生成数据库中数据。

1、重新配置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>
	<!-- 配置oracle连接 -->
	<session-factory>
		<!-- 常用配置可以参考hibernate集合包主目录\project\etc、hibernate.properties文件 -->
		<!-- 配置driver -->
		<!-- name表示参数类型 -->
		<!-- 元素值表示参数内容 -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- 配置url -->
		<property name="connection.url">jdbc:mysql://127.0.0.1:3306/mydb1</property>
		<!-- 配置用户名 -->
		<property name="connection.username">root</property>
		<!-- 配置密码 -->
		<property name="connection.password">123456</property>
		<!-- 配置显示hibernate生成的 sql ,特别说明,在开发阶段设为true利于调试,在使用项目则设为false-->
		<property name="show_sql">true</property>
		<!-- 配置dialect,明确的告知Hibernate连接的是哪种数据库 -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- 让hibernate自动创建表 -->
		<!-- create创建该表 ,如果有表,删除后再创建-->
		<!-- update如果没有表则创建新表,如果有表,表结构有没有变化,如果有变化,则创建新表 -->
		<property name="hbm2ddl.auto">update</property>
		<!-- 指定管理的对象映射文件 -->
		<!-- resource指定单个domain对象的配置文件 -->
		<mapping resource="com/pc/domain/Employee.hbm.xml" />
	</session-factory>
</hibernate-configuration>
2、对对象映射文件(Employee.hbm.xml),做相应的修改
<id name="id" column="id" type="java.lang.Integer">
	<!-- 该元素用户指定主键值生成策略 -->
	<!-- class指生成策略类型 -->
	<!-- hilo native increment sequence uuid等 -->
	<generator class="increment" />
</id>

PS:因为是从Oracle转到MySQL,所以Sequence不能使用了,这是就修改成increment


对员工系统的优化

1、将SessionFactory做成工具类

    因为SessionFactory是重量级类,故一个数据库最好只对应一个SessionFactory,这就要采用单例模式了。

package com.pc.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * 
 * @author Switch
 * @function 实现SessionFactory单例化
 * @description 在使用Hibernate开发项目的时候,保证一个数据库只对应一个SessionFactory
 *
 */
public class MySessionFactory {
	private static SessionFactory sessionFactory = null;
	// 单例
	private MySessionFactory() {
		
	}
	static {
		sessionFactory = new Configuration().configure().buildSessionFactory();
	}
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}

2、将CRUD操作抽出成相应方法

    原理上应该讲业务逻辑放在EmployeeService类中,但是这里为了方便就放在测试类中。

package com.pc.view;

import java.util.Date;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

import com.pc.domain.Employee;
import com.pc.util.MySessionFactory;

public class TestMain {
	public static void main(String[] args) {
		// 使用hibernate完成crud操作(只见对象,不见表)
		// 不使用service,直接测试
		addEmployee();
		// updateEmployee();
		// deleteEmployee();
	}

	// 删除员工信息
	public static void deleteEmployee() {
		// 获取一个会话
		Session session = MySessionFactory.getSessionFactory().openSession();

		// 创建一个事务
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			// 1.获取该雇员
			Employee employee = (Employee) session.load(Employee.class, 3);
			// 2.删除该雇员
			session.delete(employee);
			// 提交
			transaction.commit();
		} catch (Exception e) {
			// TODO: handle exception
			if (transaction != null) {
				transaction.rollback();
			}
			throw new RuntimeException(e.getMessage());
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
	}

	// 修改员工信息
	public static void updateEmployee() {
		// 获取一个会话
		Session session = MySessionFactory.getSessionFactory().openSession();

		// 创建事务对象
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			// 1.获取要修改的雇员
			// load是通过主键属性,获取该对象实例(表的记录)
			Employee employee = (Employee) session.load(Employee.class, 2);
			// 2.修改该雇员
			employee.setName("ls");
			// 提交
			transaction.commit();
		} catch (Exception e) {
			// TODO: handle exception
			if (transaction != null) {
				transaction.rollback();
			}
			throw new RuntimeException(e.getMessage());
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
	}

	// 添加员工
	public static void addEmployee() {
		// 1.创建Configuration对象,该对象用于读取hibernate.cfg.xml,并完成初始化
		// configure默认载入hibernate.cfg.xml文件,可以指定需要载入的xml
		Configuration configuration = new Configuration().configure();
		// 2.创建SessionFactory对象(这是一个会话工厂,是一个重量级的对象)
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.创建Session(用于与数据库的对话,相当于JDBC中的Connection)
		Session session = sessionFactory.openSession();
		// 4.对Hibernate而言,要求程序员,在进行增加、删除、修改的时候使用事务提交,否则不生效
		Transaction transaction = session.beginTransaction();
		// 添加一个雇员
		Employee employee = new Employee();
		employee.setName("zs");
		employee.setEmail("123456@switch.com");
		employee.setHiredate(new Date());
		// 保存
		// --->insert into ...[被hibernate封装]
		session.save(employee);
		// 提交
		transaction.commit();
		session.close();
	}
}




----------参考《韩顺平.hibernate从入门到精通》


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值